Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternatives to a deep inheritance hierarchy?

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:

  • MSI GTX690
  • Gigabyte GTX690
  • ASUS GTX690

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?

like image 474
Zac Blazic Avatar asked Oct 11 '12 19:10

Zac Blazic


People also ask

Which type of hierarchy allows inheritance?

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.

Which is better inheritance or composition?

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.

What potential problems can you encounter when you have a very deep class hierarchy 6 classes?

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.

Is hierarchy and inheritance same?

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.


1 Answers

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.

like image 116
eulerfx Avatar answered Sep 19 '22 12:09

eulerfx