What is the accepted terminology to use for referring to the items of a dependency?
I've been using parent and child, where parents depend on their children, but this caused some confusion when someone else thought that children depended on their parents. Arguably both are true in real life.
We found that dependent isn't clear enough- you have to think really hard about which end it is referring to.
Bonus points for links to documents using or better yet discussing such terminology.
I've only ever heard of a child being the dependent. That goes for real life too (excluding some scenarios involving sickness or old age). From modelling heirachies in a database to filling out my tax return at the end of the year to changing nappies(diapers), my experience has been that a child always is the dependent of a parent.
If you need to describe entity relationships more thoroughly then you can use ER modelling. Or on the attribute level functional dependencies.
"Parent" and "child" are fine.
At the level of physical FOREIGN KEYs, the terms "referencing" and "referenced" are sometime used.
When talking about X:Y relationships in the logical model, the cardinality is sometimes used. For example, a 1:N relationship might use the terms: "1 endpoint" and "N endpoint".
In the end we decided to use item and depends_on. It's easy to read and avoids any ambiguity.
You could use dependent and depends_on, but it doesn't read as well.
Someone suggested requires and enables - I really like this.
Related
From what I've read and what I've seen, I consider multiple inheritance as a bad practice, not by itself but because it leads beginner to use everywhere where more elegant design patterns might be useful and more meaningful.
Some languages have chosen not to implement multiple inheritance and then have chosen to implement traits (e.g. PHP). The only interesting and substantial difference I see between multiple inheritance and traits I see is a linguistic one: while "inheritance" indicates some kind of shared nature, "trait" stands more for features.
Is there any other important difference I'm missing that would explain why some consider that multiple inheritance was inappropriate and that, now, traits are appropriate?
You could use traits to fake multiple inheritance, but I believe the basic difference is a conceptual one. A parent-child relation is a "is-a" relation.
If you have a Furniture class, with a Table child and a PicknickTable child, you have Picknicktable is-a Table is-a Furniture (hmm, is furniture countable like that? nvrmnd).
With traits, you just say: I hate to keep on writing the code to put stuff on a surface, so I write the "putStuffOnThisThing" trait, and they have it. This is not inheritance! The basic fault behind such reasoning might be is that you want to look at traits as a different way to show hierarchies while you shouldn't. It is no substitution for an actual good design, it is a trick in the toolbox that you could misuse for multiple inheritance, but you might be better use as a way to avoid writing some lines several times.
So in defence of the comparison: traits have some of the same problems as multiple inheritance, like the problem you need to address with aliasing in case of multiple things with the same name. While this is not exactly the diamond problem, it comes awfully close.
This design problem is turning out to be a bit more "interesting" than I'd expected....
For context, I'll be implementing whatever solution I derive in Access 2007 (not much choice--customer requirement. I might be able to talk them into a different back end, but the front end has to be Access (and therefore VBA & Access SQL)). The two major activities that I anticipate around these tables are batch importing new structures from flat files and reporting on the structures (with full recursion of the entire structure). Virtually no deletes or updates (aside from entire trees getting marked as inactive when a new version is created).
I'm dealing with two main tables, and wondering if I really have a handle on how to relate them: Products and Parts (there are some others, but they're quite straightforward by comparison).
Products are made up of Parts. A Part can be used in more than one Product, and most Products employ more than one Part. I think that a normal many-to-many resolution table can satisfy this requirement (mostly--I'll revisit this in a minute). I'll call this Product-Part.
The "fun" part is that many Parts are also made up of Parts. Once again, a given Part may be used in more than one parent Part (even within a single Product). Not only that, I think that I have to treat the number of recursion levels as effectively arbitrary.
I can capture the relations with a m-to-m resolution from Parts back to Parts, relating each non-root Part to its immediate parent part, but I have the sneaking suspicion that I may be setting myself up for grief if I stop there. I'll call this Part-Part. Several questions occur to me:
Am I borrowing trouble by wondering about this? In other words, should I just implement the two resolution tables as outlined above, and stop worrying?
Should I also create Part-Part rows for all the ancestors of each non-root Part, with an extra column in the table to store the number of generations?
Should Product-Part contain rows for every Part in the Product, or just the root Parts? If it's all Parts, would a generation indicator be useful?
I have (just today, from the Related Questions), taken a look at the Nested Set design approach. It looks like it could simplify some of the requirements (particularly on the reporting side), but thinking about generating the tree during the import of hundreds (occasionally thousands) of Parts in a Product import is giving me nightmares before I even get to sleep. Am I better off biting that bullet and going forward this way?
In addition to the specific questions above, I'd appreciate any other comentary on the structural design, as well as hints on how to process this, either inbound or outbound (though I'm afraid I can't entertain suggestions of changing the language/DBMS environment).
Bills of materials and exploded parts lists are always so much fun. I would implement Parts as your main table, with a Boolean field to say a part is "sellable". This removes the first-level recursion difference and the redundancy of Parts that are themselves Products. Then, implement Products as a view of Parts that are sellable.
You're on the right track with the PartPart cross-ref table. Implement a constraint on that table that says the parent Part and the child Part cannot be the same Part ID, to save yourself some headaches with infinite recursion.
Generational differences between BOMs can be maintained by creating a new Part at the level of the actual change, and in any higher levels in which the change must be accomodated (if you want to say that this new Part, as part of its parent hierarchy, results in a new Product). Then update the reference tree of any Part levels that weren't revised in this generational change (to maintain Parts and Products that should not change generationally if a child does). To avoid orphans (unreferenced Parts records that are unreachable from the top level), Parts can reference their predecessor directly, creating a linked list of ancestors.
This is a very complex web, to be sure; persisting tree-like structures of similarly-represented objects usually are. But, if you're smart about implementing constraints to enforce referential integrity and avoid infinite recursion, I think it'll be manageable.
I would have one part table for atomic parts, then a superpart table with a superpartID and its related subparts. Then you can have a product/superpart table.
If a part is also a superpart, then you just have one row for the superpartID with the same partID.
Maybe 'component' is a better term than superpart. Components could be reused in larger components, for example.
You can find sample Bill of Materials database schemas at
http://www.databaseanswers.org/data_models/
The website offers Access applications for some of the models. Check with the author of the website.
I'm working on building a tree structure in MySQL and have been experimenting with different ways of representing the data. However, no matter how I slice it, there are shortcomings.
The nested sets model allows me to easily select entire branches of the tree - which I need to do. However it is not so easy to select immediate children of a node.
The adjacency list model is great for getting immediate children, but not so good for returning entire branches of the tree.
I'm wondering, is there anything particularly bad about building a tree structure like this:
TABLE: Tree
ID
name
lft
rgt
parentID
So what I have is the adjacency list model and the nested sets model all in the same table. That way I can use either / or, depending on the circumstances of what I am selecting for.
What are peoples' thoughts? Is this allowed? (Peanut butter and chocolate together at last?) Or is this considered bad design?
Thanks in advance,
I highly recommend it myself. This is the style which CakePHP uses for its tree structures, and as you pointed out, it gives you great flexibility. You just need to do a bit more work to ensure the integrity of your tree, but it's quite worth it.
No, its not bad design at all. At least in my opinion.
I would however only implement one. For example, I used Adjacency List Model as my prime method of adding new elements and retreiving.. (obviously retreiving since its so easy) however, I also added parentIds for Nested Set.
The benefit of this is that I can rebuild my ALM at any time and can easily move things quickly providing I keep the parentIds.
I would not use both in your code however, just have it there in the background...
Edited Comments
You mention that it is not so easy to select immediate children. I think you might be doing something wrong. It is extremely easy even in Adjacency List to select the immediate children.
If you create a new question I will answer how to do it in that.
I have a class A that has a collection of objects of Class B.
Class A can also 'inherit' (for lack of a better term) the collection of objects of Class B from other instances of Class A. To model this, instances of Class A point to other instances of Class A (I control for circular references).
A simplified concrete example might be that a person has biological children but also 'inherits' children from their spouse and ex-spouses.
I use instances of class A with and without the inherited objects in my application at run-time. That is, both 'projections' of instances of Class A are meaningful to me in the context of my application in difference scenarios.
My question is, is there a pattern for coding this sort of model or standard terminology? I don't think 'inherit' is the right word here. I have my own ways of handling it technically and my own cumbersome terminology but I'm imagining there is a standard pattern I can adhere to that I just can't seem to find.
An imperfect analogue would be inspecting the methods of .NET classes with and without their inherited methods or inspecting prototypes in Javascript, but here I'm 'inheriting' records/objects.
Looks like the composite pattern to me, with A objects being composites and B leafs. The one object A that points to other objects A is a root item. The difference seems that when getting leaf items you distinguish whether the root item includes leaf items from other composites it knows of or not.
No, I don't think (A) there are common OOP idioms for what you're doing, nor (B) any prominent patterns similar to yours. And (C), that is absolutely fine. Now maybe you should be doing it this way and maybe you shouldn't be. Whenever you're doing something that you have a hard time describing, you should certainly second-guess yourself and wonder if there's a simpler way of doing it. But, the lack of common terminology for describing your model, and it not fitting into a "pattern" you've heard of, does not in itself indicate a problem. Classes sometimes have to do wacky stuff under the hood. That's the point. If you're encapsulating a lot of complexity for the consumers of these classes, and it's intuitive and logical and discoverable for them, then great!
It is a mistake though to improperly use common terms to try to help someone understand. In fact, your use of the term inherit above really confused me, and I'm still not 100% sure I have it. Is it this?
An object of class ClassA maintains a collection of ClassB objects. In addition, some of a ClassA object's functionality has to act upon not only its own ClassB objects, but those maintained by other ClassA objects as well. A ClassA object maintains references to other ClassA objects for this purpose.
Assuming I have it correct of course, I think that's a good way to decribe it. And since there is precisely no inheritance here, it would confuse people if that term were used. Also, do not ever, ever, every be distressed if what you're doing does not match some pattern somewhere.
I think your model is at fault. If two or more instances of a class have a relation with an instance of another class, the correct model is not to make one of the instances contain the third - it is to make both of them refer to the third. In the case of human parents, each should refer to the same "offspring" (a list of human children) object. You then control the referred to class via mechanisms such as reference counting.
OOP defines two basic types of relationships:
A is a B
A has a B
Within the second category you have subcategories:
A contains B
B is a component of A
A is associated with (or references) B
The first two are similar, but your concrete example clearly refers to the 3rd. Parents do not contain children, they are related to their children, and when somebody marries into family, they have new relationships (associations) created with the existing family.
So I guess the answer is no, there is no "pattern." You are simply copying/transforming a set of relationships from one instance to another.
Something keeps showing up in my programming, and it is that two things are the same from some viewpoint, but different from another. Like, imagine you build a graph of rail stations, connected by trains, then the classes Vertex and RailStation are sometimes the same, other times not.
So, imagine I have a graph that very much represents rail stations and trains. Then I hand this graph to another object, which deletes some vertices, and then I want the corresponding rail stations to be gone.
I don't want to make rail stations "properties" of vertices, they're not. Also, the problem is symmetrical: If I erase a railstation, I want the corresponding vertex to be gone. What is the proper OO way to model or correspondences. I'm willing to go a few extra miles by writing some support methods or classes, if in the end the overall usage is simple and easy.
I'm currently using the Smalltalk programming language, but the question isn't really smalltalk-specific, I think. I just mention it because in Smalltalk, you can do cool tricks like examining the call stack, which might be helpful in this context.
Update:
Well, RailStations aren't Vertices! Are they?
Ok, let us consider real code, as demanded in the answers. Let me model a person with children. That's the easiest thing, right? Children should also know their parents, so we have like a doubly linked tree. To make disbanding parents from children easier, I model the link between parent and child as a Relationship, with properties parent and child.
So, I could implement parent>>removeChild: perhaps like this
removeChild: aChild
(parent relationshipWith: aChild) disband.
So, a parent has a collection of relationships, not of children. But each relationship corresponds to a child. Now I want to do things like this:
parent children removeAllSuchThat: [:e | e age < 12]
which should remove the relationship and the child.
Here, relationships and children correspond in some sense. So, what do I do now? Don't get me wrong, I'm fully aware that I could solve the problem without introducing Relationship classes. But indeed, parents and children actually do share a relationship, so why not model that and use it to help disbanding double links less imperatively?
In your problem domain, aren't stations a kind of vertex? In which case, why not derive Station from Vertex?
Notice the use of the phrase "in your problem domain". Your problem appears to be about the use as railway stations appearing in a graph. So yes, in that domain, stations are vertexes. If it was a different problem domain, say a database on railway station architecture, they may well not be. Most modern languages support some idea of namespaces to allow you to have different kinds of entity with the same names in different domains.
Regarding your parent/child problem, once again you are being too general. If I were modelling mathematical expressions and sub expressions, if I remove a parent I would want to remove and delete/free all subexpressions. OTOH, ff I were modelling legal responsibility relationships in the UK population, then when a responsibility isis dissolved (say because of a divorce), I only want to remove the relationship, and NOT delete/free the child, which has its own independent existence.
It seems like you just want RailStation to inherit from Vertex (is-a relationship). See this smalltalk tutorial on inheritance. That way, if you have a graph of RailStations, an object used to dealing (generically) with graphs of Vertexes would handle things right naturally.
If this approach won't work, be more specific (preferably with real code).
From your description of the problem, you have a one-to-one correspondence of stations to vertices and deleting a station should automatically delete the corresponding vertex (and vice-versa). You also mentioned building "a graph of rail stations, connected by trains", by which you apparently mean a graph in which stations are vertices and trains are edges.
So, in what way is a station not a vertex? If the station does not exist except as a vertex, and if a vertex does not exist except as a station, then what benefit do you see in maintaining them as two distinct-but-linked entities?
As I understand your situation, station-isa-vertex and inheritance is the way to model that.
Having a Relationship object is a good idea.
I think the appropriate question here is "which use should be made of it?".
Probably Parent and Child classes are extending the same Person superclass, so they'll have some attributes in common, age for example.
In my idea, I can see the following: Parent and Child objects have to know each other, so both classes have to keep a link to the same Relationship.
The Relationship object keeps a one-to-many relation between a single parent and a certain number of children, and it'll keep a reference to each Person object.
This way you can implement the whole disbanding logic within the Relationshp object, more or less sophisticated as you wish. You can query the Relationship object to know which members of the family match your requirements to do something. You can make the relationship to disband (and destroy) safely, as it will know all members and would ask them to break the reference and then it would be ready to destroy, or ask to some member to leave the family, keeping the Relationship object alive.
But that's not all. Relationship should be really a superclass, extended by HierarchicalRelationship and PeerRelationship (or FriendRelationship).
This specialization lets you have Parent(s) and Child(ren) to link between other hierarchies in a completely traversal way.
The true concept behind this is that your Relationship objects are the key to query and organize the whole bunch of Person objects (or Vertex objects) in a scalable and structured way, so the whole data domain you end up with is usable in any sense you like, whether you want to disband groups or walk a certain path (or railroad) between them.
Sorry for the huge amount of metaphores.
Take a look at Fame, see http://www.squeaksource.com/Fame.html
We use a specialized subclass of Collection that updates the opposite end when you add or remove elements. Also, you can annotate your classes with pragmas to annotate relations. These pragmas are used by the Fame framework to do all kind of nice stuff.