Composition over inheritance & Diamond problem (cited from Wikepedia)

http://en.wikipedia.org/wiki/Composition_over_inheritance

http://en.wikipedia.org/wiki/Diamond_problem

Composition over inheritance in object-oriented programming is a technique by which classes may achieve polymorphic behavior and code reuse by containing other classes which implement the desired functionality instead of through inheritance.[1]

This technique is also referred to as “Composite Reuse Principle”.

Basics

An implementation of composition over inheritance typically begins with the creation of various interfaces representing the behaviors which the system must exhibit. The use of interfaces allows this technique to support the polymorphic behavior that is so valuable in object-oriented programming. Classes implementing the identified interfaces are built and added to Business Domain classes as needed. Thus system behaviors are realized without inheritance. In fact, business domain classes may all be base classes without any inheritance at all. Alternative implementation of system behaviors are accomplished by providing another class which implements the desired behavior interface. Any business domain class that contains a reference to the interface can easily support any implementation of that interface and the choice can even be delayed until run time.

Example

[edit]Inheritance

class Object {
  public:
     virtual void update() {} ;
     virtual void draw() {} ;
     virtual void collide(Object objects[]) {} ;
};
class Visible : public Object {
  public:
     virtual void draw() { /* draw model at position of this object*/ };
  private:
     Model* model;
};
class Solid : public Object {
  public:
     virtual void collide(Object objects[]) { /*check and react to collisions with objects */ };
};
class Movable : public Object {
  public:
     virtual void update() { /* update position */ };
};

Then we have concrete classes:

  • class Player – which is Solid, Movable and Visible
  • class Cloud – which is Movable and Visible, but not Solid
  • class Building – which is Solid and Visible, but not Movable
  • class Trap – which is Solid and not Visible nor Movable

Using inheritance we either have to do multiple inheritance, which leads to the diamond problem, or make classes like VisibleAndSolid, VisibleAndMovable, VisibleAndSolidAndMovable, etc. for every needed combination, which leads to a large amount of repetitive code.

[edit]Composition (and a little inheritance)

class Object {
  public:
    Object(VisibilityDelegate* v, UpdateDelegate *u, CollisionDelegate *c):_v(v),_u(u),_c(c) {};

    void update() { _u->update(); };
    void draw()   { _v->draw(); };
    void collide(Object objects[]) { _c->collide(objects); };
  private:
    VisibilityDelegate* _v;
    UpdateDelegate *_u;
    CollisionDelegate *_c;
};

class VisibilityDelegate {
  public:
     virtual void draw() = 0;
};
class Invisible : public VisibilityDelegate {
  public:
     virtual void draw() {};
};
class Visible: public VisibilityDelegate {
  public:
     virtual void draw() { /*draw model*/ };
};

class CollisionDelegate {
  public:
     virtual void collide(Object objects[]) = 0;
};
class Solid : public CollisionDelegate {
  public:
     virtual void collide(Object objects[]) { /* check collisions with object and react*/ };
};
class NotSolid : public CollisionDelegate {
  public:
    virtual void collide(Object objects[]) {};
};

class UpdateDelegate {
  public:
     virtual void update() = 0;
};
class Movable : public UpdateDelegate {
  public:
     virtual void update() { /*move object*/ };
};
class NotMovable : public UpdateDelegate {
  public:
     virtual void update() { };
};

Then concrete classes would look like:

class Player : public Object {
  public:
    Player():Object(new Visible(), new Movable(), new Solid()) {};
...
};
class Smoke : public Object {
  public:
    Smoke():Object(new Visible(), new Movable(), new NotSolid()) {};
...
};

Benefits

Composition over inheritance can simplify the initial design of Business Domain classes and provide a more stable business domain in the long term. Its advantage over inheritance is a more thorough isolation of interests than can be described by a hierarchy of descendant classes. Additionally, inheritance models are often contrived during the definition of business domain classes in order to make sense of the information in the problem domain and do not necessarily reflect the true relationship of various system objects.

Initial design is simplified by identifying system object behaviors in separate interfaces instead of creating a hierarchical relationship to distribute behaviors among business domain classes via inheritance. This approach more easily accommodates future requirements changes that would otherwise require a complete restructuring of business domain classes in the inheritance model. Additionally, it avoids problems often associated with relatively minor changes to an inheritance-based model that includes several generations of classes.

Diamond Problems: 

In object-oriented programming languages with multiple inheritance, the diamond problem (sometimes referred to as the “deadly diamond of death[1]) is an ambiguity that arises when two classes B and C inherit from A, and class D inherits from both B and C. If D calls a method defined in A (and does not override the method), and B and C have overridden that method differently, then from which class does it inherit: B, or C?

For example, in the context of GUI software development, a class Button may inherit from both classes Rectangle (for appearance) and Clickable (for functionality/input handling), and classes Rectangle and Clickable both inherit from the Object class. Now if the equals method is called for a Button object and there is no such method in the Button class but there is an overridden equals method in both Rectangle andClickable, which method should be eventually called?

Business domain:

business domain in object oriented programming is the set of classes that represent objects in the business model being implemented. The business domain is distinguishable from the business model in that the business model is an understanding and explanation of information and behaviors in the problem domain while the business domain is an implementation of that model in a specific programming language.

Domain model:

domain model in problem solving and software engineering can be thought of as a conceptual model of a domain of interest (often referred to as a problem domain) which describes the various entities, their attributes, roles and relationships, plus the constraints that govern the integrity of the model elements comprising that problem domain.

An important advantage of a domain model is that it describes and constrains the scope of the problem domain. The domain model can be effectively used to verify and validate the understanding of the problem domain among various stakeholders. It is especially helpful as a communication tool and a focusing point both amongst the different members of the business team as well as between the technical and business teams.

In UML, a class diagram is used to represent the domain model.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s