I was creating and discussing a class diagram with a partner of mine. To simplify things, I’ve modify the real domain we’re working on and made up the following diagram:
Basically, a company works on constructions that are quite different one from each other but are still constructions. Note I’ve added one field for each class but there should be many more.
Now, I thought this was the way to go but my partner told me that if in the future new construction classes appear we would have to modify the Company class, which is correct. So the new proposed class diagram would be this:
Now I’ve been wondering:
- Should the fact that in no place of the application will there be mixed lists of planes and bridges affect the design in any way?
- When we have to list only planes for a company, how are we supposed to distinguish them from the other elements in the list without checking for their class names?
- Related to the previous question, is it correct to assume that this type of diagram should be high-level and this is something it shouldn’t matter at this stage but rather be thought and decided at implementation time?
Any comment will be appreciated.
3
First and foremost, the models are highly dependent of the business domain so, since you have changed it, it might be that my answer fits the question but not your real domain.
-
Depends of what the relationship means. An “inventory of company” or “construction projects currently active” would be examples where the relationship with
AbstractProject
would be understandable. -
I would do, so. Of course, your language might make it difficult and you might find it easier to add a “type” attribute to
AbstractProject
. (Not good because it breaks the open/closed principle).As, outside 1 & 2, I think that
Plane
andBridge
have so few things it common that probably you should skip the abstract class altogether. Of course, that would complicate the model, since know you either have two relationships with company (bad for the open/closed principle, if you end producing alsoCar
), or you have to add another middle class (ConstructionProject
), which is what I would do. -
No, it is not high level, “free to change”. It is the data that you pass to the code-monkeys so they do their job, and the data that you pass to other teams that must develop SW to use your system, so you have to stick with it.
That does not forbid you from modifying it if you see that it does not really adapt to your needs, but those modifications “in the code” must be approved, reflected in the UML, and communicated. Depending of your project management phylosophy, they would be interpreted as “mistakes” or “refinements” of your original model.
2
If the Company
does not need to know the difference between a Bridge
and a Plane
, the second diagram is indeed better; it encodes the fact that the Company
is fundamentally ignorant of the difference.
On the other hand, if the Company
needs to intimately understand the difference between a Bridge
and a Plane
(and any other future subclasses of AbstractConstruction
) then the first diagram is the right one; it’s a better model of the nature of the domain. (It might be that this is an indication that the model is wrong in other ways, such as encoding information in the wrong class, but that’s out of the scope of this particular decision, and sometimes it is better to use a less perfect OO solution to get better buy-in from project partners.)
Which fits the real domain better? Well, I find it hard to think of any real company that just makes Bridge
s and Plane
s, so this is all a stand-in for something else (or a silly toy example) and it is by examining the details of that that you’ll understand more completely what you should choose. However, whatever you pick, it should be the thing that best models the real situation.
I’d also rename AbstractConstruction
to ConstructionProject
, but that’s just me. I hate putting meta-information into class names; a class is abstract if it’s metadata says it is, not if its got that label. And plain old Construction
is wrong too; it’s the project that you’re dealing with…
This is what I would do:
-
If you want to take into account that there is no mixed list, you can have a company having a Map of lists. (mapping type to list)
-
Having a map of lists as above, you also will be able to get the type without having to use the class name (still need some thing for identification of objects though). I am not saying doing this is better. I am only saying you will get what you stated above by doing this. In fact you can even rename the AbstractConstruction to ProjectInfo and use composition pattern to have it inside each Plane or Bridge object. Which design is good depends on the situation, and your situation is essentially what you would want in the application (so list more of what you want, or what you would anticipate that you want). I don’t see a lot of what you want to actually come up with a good design and defend that design based on what you want.
-
I personally use diagram to make sure that I think in paper before I code some thing reasonably complex. For design and implementation point, if you use it as an internal diagram (for yourself and team), then it doesn’t matter if you change it or not. But the moment you start handing out that diagram to other people and team, you should assume that they will make decisions based on the diagram when they work on their module. Any changes you make after that will have cascading effects.