Composition is the art of using one or more objects to handle different parts of the logic of a parent class. The code is almost always much less tightly coupled than the inherited model.

Say, you have a bunch of hierarchical, tightly coupled classes:

class CartLine
{
    private $quantity;

    public function addQuantity($quantity)
    {
        // Some stupid bug years ago required this stupid fix.
        if ($quantity > 5) { $quantity = 5; }
        $this->quantity = $quantity;
    }
}

class ItemCartLine extends CartLine
{
    public function addQuantity($quantity)
    {
        parent::addQuantity($quantity);
        $this->doSomeItemFunction();
    }
}

class WishlistItemLine extends ItemCartLine { }
class GiftCardCartLine extends CartLine { }

What happens if you ever have the need for ItemCartLine to have a quantity greater than five for a specific application? A complicated if-statement, that’s what. And that breaks encapsulation, as now your library has to know operational logic of the entire application.

In the above example, the code is not so much concerned about line types and hierarchies as it is about organizing operational logic for different CartLine ”contexts”. Instead, composition could be used as such:

interface CartLineLogic
{
    public function addQuantity($quantity);
}

// Since this is a Struct, it is perfectly acceptable to use it under the ''everything-public'' encapsulation doctrine.
class GenericCartLineProperties
{
    public $quantity;
}

class CartLine
{
    private $properties;
    private $lineLogic;

    public function __construct(CartLineLogic $lineLogic)
    {
        $this->lineLogic = $lineLogic;
        $this->lineLogic->setProperties($this->properties);
    }

    public function addQuantity($quantity)
    {
        return $this->lineLogic->addQuantity($quantity);
    }
}

class GenericLineLogic implements LineLogic
{
    protected $properties;

    public function setProperties(&$properties)
    {
        $this->properties = $properties;
    }

    public function addQuantity($quantity)
    {
        $this->properties->quantity = $quantity;
    }
}

class ItemLineLogic extends GenericLineLogic
{
    public function addQuantity($quantity)
    {
        // Some stupid bug years ago required this stupid fix.
        if ($quantity > 5) { $quantity = 5; }
        $this->properties->quantity = $quantity;
    }
}

class SpecificClientItemLineLogic extends GenericLineLogic
{
}

// Implementation:
$cartLine = new CartLine(new SpecificClientItemLineLogic());

It may look like more code, but for any sufficiently advanced system, composition can really save the day.

A great example of composition is found in the Cash Register Class of the Store project.