Inherit vs Delegate - how to know which one to use

Posted by Tim Kuehn on 07-May-2010 13:11

Classes allow for inheriting from super classes, overloading methods, etc. while one could also create delegate objects and then access their methods.

Outside of getting overloading and signature matching, are there any good rules for deciding when to use inheritance vs delegation?

All Replies

Posted by Thomas Mercer-Hursh on 07-May-2010 13:33

The underlying test here is the coherence of the resulting decomposition.  If you look at the problem space and it seems pretty clear that there is a set of things which all belong to one type, but there are subtypes within that type, then you have a classic setup for generalization, aka inheritance.  Whereas, if you have a complex set of behaviors in which there seems to be a subcategory of behavior and knowledge which can be treated as a cohesive unit separate from the rest of the behaviors and knowledge, then you have a good candidate for a delegate.  Thus, in simpler cases, the two don't really compete as much as they relate to different ways of breaking up the problem space.

The place where they become more closely related is in complex cases where one has what amounts to "cross-tab" subtypes.  E.g., orders might be subtyped according to the customer type, internal versus external, since there is different knowledge and behavior associated with those types.  But, orders might also be subtyped by delivery method - shipped, dropshipped, pick up, virtual or licensed, etc.  And, each of the delivery methods might apply to each of the customer types or nearly so.  Unless one of these classifications is clearly primary to the other, this creates a messy situation for generalization because one has to duplicate subtype breakdowns.  This is very fragile if there are changes and the duplication is a very bad sign.  Some such situations can be handled with multiple inheritance, but fortunately we haven't been given that particular way to shoot ourselves in the foot in ABL.  Instead, one looks at this and wonders if there is an opportunity here for a delegate.  My instinct in this particular case is to turn the shipping method into a delegate which has its various subtypes and to leave the customer type as subtypes of Order itself.  This solves the crosstab problem since we now have two separate simple generalization hierarchies.

There is some discussion of these ideas in

http://www.cintegrity.com/content/%E2%80%9CGang-Four%E2%80%9D-Decorator-Pattern-What-Its-Appropriate-Use

although the focus there is on a proposed third approach.

Posted by cwills on 10-May-2010 09:15

I try to look at the relationship between the two objects being modeled.

'Is a' Relationship - Use Inheritance

For example, a circle is a shape.

So you would expect the Circle class to inherit from the Shape class:

CLASS Circle INHERITS Shape:

...

'Has a' Relationship - Use Delegation

For example, a car has a drive shaft.

But a car has other parts as well - a car is not just a drive shaft, so you wouldn't use inheritance.

You would use composition (delegation).

CLASS Car:


     DEFINE PRIVATE VARIABLE driveShaft AS DriveShaft NO-UNDO.

...

Obviously real world examples are not always this easy or clear. But the rule should still apply.

Posted by Thomas Mercer-Hursh on 10-May-2010 15:49

I would not equate delegation and composition.

From http://www.cintegrity.com/content/Object-Oriented-Vocabulary-Introduction

Delegation: One object relying on another to implement  a part of its overall functionality.  A Delegate is created as a  separate object to further separation of concerns, particularly when the  main object is very complex and the Delegate has variations appropriate  for Specialization.  Once separated, the Delegate and the original  Object are peers, each with their own separate sphere of Responsibility.   It is important that this separation exist in the problem space, i.e.,  the Delegate should be an intrinsic decomposition recognizable in the  problem space, not merely an arbitrary cluster of knowledge and  behaviors.  The container object, i.e., the one that has Delegated some  of its behavior, may expose Methods by which that Delegated behavior can  be accessed so that Clients of that object need not be aware of the  Delegate.

Composition: A relationship between one Object and one  or more other Objects in which one object “contains” the other objects  or which one would describe by the phase “part of”, i.e., some  departments are “part of” a university.  Composition differs from  Aggregation in that in Composition, destroying the container object also  destroys the contained Objects, if a university is disbanded, the  departments no longer exist.

and, since Composition is contrasted to Aggregation

Aggregation: A relationship between one Object and one  or more other Objects in which one object “contains” the other objects  or which one would describe by the phrase “part of”, i.e., some group of  teachers is “part of” a school.  Aggregation differs from Composition  in that in Aggregation, the contained Object has the potential to stand  alone, i.e., if the school is disbanded, the teachers still exist.

This thread is closed