The primary goal of the Delegate design pattern is to delegate tasks to one or more other objects. This is highly useful when you need to abstract out logic to a higher level, as it helps you avoid lots of difficult-to-maintain nested if statements and fits nicely with encapsulation’s [[PHPBook:Encapsulation|”Don’t Ask, Tell” methodology]].

The Pattern

class Worker { public function liftBox() { echo “lifted a box.”; } }

class Delegator { private $worker; public function __construct() { $this->worker = new Worker; }

public function liftBox()
{
    return $this->worker->liftBox();
}

}

Delegator did nothing itself and instead told Worker what to do and passed on its results with little or no modification.

= Real World Example =

With Rosetta Blog, I quickly discovered that Drupal 6 uses a dramatically different database schema for articles. Since I want to support both (and drupal 7, wordpress, etc.) I knew I’d have to abstract out the logic.

A new developer would have done something like this:

// ArticleController if ($config[‘blogPlatform’] = ‘Drupal5’) { $articleManager = new Drupal5ArticleManager; } else if ($config[‘blogPlatform’] = ‘Drupal6’) { $articleManager = new Drupal6ArticleManager; }

$article = $articleManager->getMessageByID($id);

But this breaks the laws of encapsulation, because the Controller aspect of MVC has to know way too much about the Article model (e.g. that Drupal5 and 6 are supported…)

A better system is to use the delegate system:

interface ArticleManagerI { public function fetchArticleByName($articleName); public function fetchArticleByID($articleID); public function fetchArticleSummaries($articleLimit, $offset = 0); }

class ArticleManager implements ArticleManagerI { /** @var ArticleManagerI **/ private $articleManager;

public function __construct($blogPlatform)
{
    $className = $blogPlatform . 'ArticleManager';
    $this->articleManager = new $className();
}

public function fetchArticleByID($articleID)
{
    return $this->articleManager->fetchArticleByID($articleID);
}

}

It may not look like much but now the controller doesn’t have to give a damn about what platforms your blog supports.

$article = new ArticleManager($config[‘blogPlatform’]);