Composition over inheritance

Composition over inheritance

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".

Contents

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

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.

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 Model : 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.

See also

References

Further reading


Wikimedia Foundation. 2010.

Игры ⚽ Нужна курсовая?

Look at other dictionaries:

  • inheritance — /in her i teuhns/, n. 1. something that is or may be inherited; property passing at the owner s death to the heir or those entitled to succeed; legacy. 2. the genetic characters transmitted from parent to offspring, taken collectively. 3.… …   Universalium

  • Inheritance (object-oriented programming) — In object oriented programming (OOP), inheritance is a way to reuse code of existing objects, establish a subtype from an existing object, or both, depending upon programming language support. In classical inheritance where objects are defined by …   Wikipedia

  • Inheritance (computer science) — In object oriented programming, inheritance is a way to form new classes (instances of which are called objects) using classes that have already been defined. The inheritance concept was invented in 1967 for Simula. [ [http://heim.ifi.uio.no/… …   Wikipedia

  • musical composition — Introduction       the act of conceiving a piece of music, the art of creating music, or the finished product. These meanings are interdependent and presume a tradition in which musical works exist as repeatable entities. In this sense,… …   Universalium

  • Virtual inheritance — For inheritance of virtual functions, see virtual function. In the C++ programming language, virtual inheritance is a kind of inheritance that solves some of the problems caused by multiple inheritance (particularly the diamond problem ) by… …   Wikipedia

  • Class invariant — This article is about class invariants in computer programming, for use of the term in mathematics, see equivalence class and invariant. In computer programming, specifically object oriented programming, a class invariant is an invariant used to… …   Wikipedia

  • BaseBean — In object oriented programming, a BaseBean is a utility object from which concrete entities are derived (via subclassing). Proper design suggests that the inherited functionality should be provided via delegation instead. The BaseBean is an… …   Wikipedia

  • Class (computer science) — In object oriented programming, a class is a programming language construct that is used as a blueprint to create objects. This blueprint includes attributes and methods that the created objects all share.More technically, a class is a cohesive… …   Wikipedia

  • Design Patterns — Not to be confused with the concept of a Design pattern. Design Patterns: Elements of Reusable Object Oriented Software …   Wikipedia

  • Object-oriented design — OOD redirects here. OOD may also refer to Officer of the Deck, Officer of the day, or the Ood. Object oriented design is the process of planning a system of interacting objects for the purpose of solving a software problem. It is one approach to… …   Wikipedia

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”