I am attempting to model products with a set of comprehensive attributes. Usually an online store would use a text description to list the attributes of a specific product. However, this solution is not optimal.
For example, the following links show the inconsistencies of attributes within a text description for the same product, but with different manufacturers:
Thus, I have opted for an inheritance hierarchy as follows:
Product
> Component
> GraphicsCard
> NvidiaGraphicsCard
The reason for this is because I want fine-grained control over the attributes of each Product
. This allows me to include attributes specific to say a NvidiaGraphicsCard
that are not applicable to an ATiGraphicsCard
.
Note that, in addition to adding more fields to subclasses, the inheritance allows me make use of polymorphism in terms of having an OrderItem
hold a reference to a Product
. This is a reason why I ruled out composition.
Is there a problem to having such a deep inheritance hierarchy, and if so are there any solutions or perhaps patterns to handle this problem?
The Inheritance Hierarchy. OpenROAD system classes are organized into an inheritance hierarchy. In this hierarchy, a class that is a child of another class is considered its subclass and a class that is the parent of another class is considered its superclass.
One more benefit of composition over inheritance is testing scope. Unit testing is easy in composition because we know what all methods we are using from another class. We can mock it up for testing whereas in inheritance we depend heavily on superclass and don't know what all methods of superclass will be used.
The major issues here are mundane: Fragile base classes (changes to base are a nightmare for the derived) Increased coupling (with too many base classes comes tight coupling) Encapsulation weakens.
Hierarchical inheritance is a kind of inheritance where more than one class is inherited from a single parent or base class. Especially those features which are common in the parent class is also common with the base class.
Deep inheritance hierarchies are problematic in the context of DDD and ORMs for a few reasons. One problem arises when you try to define an entity's identity. A Product
must be comparable to other products based on identity, regardless which sub-class is being compared. This functionality can be provided in the Product
class, but care must be taken to ensure that sub-classes can also be compared and there are a few gotchas. For example, NHibernate will generate a proxy for classes, so that actual runtime type of the object will not be NvidiaGraphicsCard
but a proxy inheriting from it. While a transient instance of NvidiaGraphicsCard
will not be a proxy. This means that you can't compare them based on type.
Another difficulty is in configuring ORM mappings to support inheritance. While most ORMs allow for it, the resulting mapping and generated SQLs are often complex. Do you store all sub-classes in a single table? In multiple tables with foreign keys to a common product table? In the former you end up with a huge table. In the latter case your queries will suffer since all sub-class tables will need to be joined. There is just too much of an impedance mismatch between the relational model and the object model. Event if using a document database, it is best to favor composition over inheritance.
Instead, I would go for having a single Product
class, which can be composed of either product specific descriptors, or a dictionary of attributes. This would an OrderItem
to reference a Product
without knowing the specific product type - no need for polymorphism. This would also make it easier to allow for new types of products - no need to create a new sub-class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With