How to design classes involving collections of other classes?
General Example:
A Workspace contains number of Projects .
A Project contains large number of Resources .
Each Resource may contain large number of Files.
So here the classes identified can be Workspace,Project,Resource and File.
Workspace will have list of Project.Project will have list of Resources and Resource will have list of Files. Of course each class has its related settings.
Now the basic questions are :
a) Who creates and adds a class to a particular collection? Another class or the class containing the collection?
b) Also how to keep track of a particular collection and how to store same?
c) Who audits changes to a particular collection?
d) What are the different design patterns that could be applied in such situations?
Basically I want to reduce the coupling between the different classes .
Thanks Everyone
There are many kinds of relationships – consider
If you look at UML modelling you’ll see concepts such as Cardinality and Direction and distictions between Aggegration and Composition and questions relating to the life-cycle of the related objects.
It’s then unsurprising that we need a range of techniques and patterns to deal with different kinds of relationships.
Concerning d). There’s one overriding principle Law of Demeter or principle of least knowledge.
One important technique is then, Encapsulation decrease coupling by hiding information. Automobiles probably have little interest in many details of people, so we might have a IDriver interface on our Person class, IDriver offers the particular methods that Automobile cares about. The general principle being to favour programming to interfaces.
Following that through, we can think about a). Creation. As we’re tending to use Interfaces, it often makes sense to use Factory patterns. That does leave the question of who calls the factory. Do we prefer:
or
Here I think it’s pretty clear that Automobiles don’t know much about people, and therefore the second is better division of responsibilities. However maybe Orders could reasonably create OrderLines, Classes create ClassInstances?
b). Keeping track? That’s why we have rich sets of Collection classes. Which ones to use depend upon the nature of the relationship (one-one, one-many; etc.) and how we use it. So we pick Arrays and HashMaps etc. according to need. For a Car/Wheel we might even use names attributes of the Car – after all a Car has exactly six wheels (frontLeft, frontRight, backLeft, backRight, spare and steering). If by “store” you mean persist, then we’re looking at techniques such foreign keys in a relational database. Mapping between RDBMS and in-memory objects is increasingly managed by nice persistence mechanisms such as JPA.
c). Audit? I’ve not seen auditing applied specifically at a relationship level. Clearly the automobile.addDriver() method may be arbitrarily complex. If there’s a business requirement to audit this action, then it’s pretty clear that this a decent place to do it. This is just a standard OO design question revolving around who owns the information. General principle: “Do Not Repeat Yourself” so pretty clearly we don’t want every object that calls addDriver() to need to remember to audit, hence it’s Auto’s job.