Question
Im new to object design and Im trying to figure out which design is better. I have a Material entity which can have multiple versions. I have two designs, one is with nested classes, and the other is flat, more like a database table.
Nested example (pseudo code):
class Material
name
path = "some/path/" + name
List MaterialVersion
class MaterialVersion
versionNumber
path = "some/path/materialName/" + versionNumber
MaterialVersion is nested inside Material and this way its easier for me to display it in the UI. But I've tought of another design like this:
class Material
name
version
path = "some/path/" + name + version
class MaterialCollection
List Material
getUniqueMaterialsByName
getMaterialVersions
I have lost the MaterialVersion class but I need some methods that I can query all of the materials so I can display them in a tree like this
-- Material 1
---- V1
---- V2
-- Material 2
---- V1
I think the first one is better for my use but I would like to hear some opinions or even some other solution.
Solution
Preliminary remark: The terminology is ambiguous. In general, "nested classes" are classes defined within other classes. I'd rather use the term of "structured class" or "composite class", which means that the classes is composed of other classes.
Your design, your choice: There is no best design for this kind of problems. It's just a different vision of the same reality and slightly different ways to proceed. It's up to you to decide where you want to put the focus:
- In the first approach, you'd identify a version independent
Material
that has several versions. This is perfect if you design a CAD/CAM system, where you putMaterials
in a schema and then select/change the version number. It leaves you the flexibility to define each behavior at material or version level as best suits the needs. - In the second approach, you'd identify a versioned
Material
. This is perfect if you design a sales or a warehouse management system, where people care about the version for everything you do withMaterial
(e.g. if there are shelves and prices for iPhone X and different shelves and prices for iPhone XE).
It's really your choice: You could for example use version independent materials to implement the second example: just define prices and storage location at the level of the version, and make sure that everywhere you reference a material you also refer to a (valid) version. And you could use version dependent materials to implement the first example: it's just that switching between the versions would require you to find articles with the same name and a different version.
But make the choice for the right reason: failing a proper separation of concerns as recommended by popular architectures (e.g. MVC, MVVM, onion architecture, clean architecture, ...) might sooner or later backfire. So make design decisions:
- for domain classes based on domain reasons
- for UI classes based on UI reasons
Choosing the domain model because "it makes UI easy" might no be the most inspired choice (although it's not proven to be bad either). But if your Material
was in reality a MaterialUI
class, then follow your intuition.