I am creating a class diagram for what I thought was a fairly simple problem. However, when I get to the bottom of the hierarchy, all of the classes only contain one field and it is the same one.
This to me looks very wrong, but this field does not belong in any of the parent classes. I was wondering if there are any suggested design patterns in a situation like this?
A simplified version of the class diagram can be found below.
Note, fields named differently cannot belong to any other class
+------------------+
| NoteMapping |
|------------------|
| String noteId |
| String content |
| |
+---------+--------+
|
+---------------+----------------+
| |
+--------|--------+ +--------|--------+
| UserNote | | AdminNote |
|-----------------| |-----------------|
| String userId | | String adminId |
| | | |
+--------+--------+ +--------+--------+
| |
| |
+--------|--------+ +--------|--------+
| UserBookNote | | AdminBookNote |
|-----------------| |-----------------|
| String bookId | | String bookId |
| | | |
+-----------------+ +-----------------+
ASCII tables drawn using http://www.asciiflow.com/
Edit
I have added some class and field names to the class diagram above.
The reason bookId
cannot exist in any of the parent classes is because it is used to create a OneToOne
relationship with another class – which is not something that we always want to do.
7
The scenario you described probably means that there is an element (the field you are worrying about) that actually cames from a different hierarchy. This seems to be the typical use-case for multiple inheritance, as jwernerny already said in a comment.
Think to this: all existing cars derive (inherit) from an abstract “car” of some type. You can draw a tree that links all of them (a family tree). In which point of the family tree would you put the GPS navigator that you can see inside every modern car?
Most likely, you would end with a field named “GPS navigator” in each bottom (most modern) class of your tree. This happens because the GPS navigator comes from a different world (electronics) and does not have anything to share with cars.
Is this your situation?
2
I’d just put String five in ObjectAA or ObjectAB or even ObjectA, then just accept that it will be blank or null most of the time. I might not do this if I suspected ObjectAAA and ObjectABA were going to get enhanced in the future, or if it really made the logic much easier to follow. I guess the bottom line is, which way is easiest to understand?
There are really three ways a class stands apart from others.
It may have different data stashed in it, which is pretty much what we are discussing here.
Or it’s methods might do different things–same name, but different code. If that applies here, then I wouldn’t worry about duplicate fields. You should use different classes if they do different things even though they contain no new fields.
Or it just might mean something different to the programmer. This is usually a function of fields, methods, and future intent. If it makes more sense, go with it. (But if two classes are identical in fields and methods–or even close–you might want to ask yourself if the two different concepts behind them are really one and the same.)
4
Sometimes code duplication is a good practical approach.
Did I really write that? Don’t shot me now, listen first.
As stated several times: without a concrete case it’s hard to tell, but sometimes it is easier to live with the consequences of a little duplication. When it comes to a special case, C++ developer shout: multiple inheritence, while Java enthusiasts hum Generics. I say KIS – keep it simple. Not too simple, i.e. not simpler as the problem itself, but neither more complex! IMO you gain more benefit of clear structures than of a generic system that may cover everything (at the costs of readability).