Last active
February 5, 2016 08:00
-
-
Save u-mulder/094846474c57717fbba1 to your computer and use it in GitHub Desktop.
PHP version of Visitor pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Интерфейс для посещаемого | |
* Посещаемые объекты должны реализовывать | |
* - метод accept - принятие посетителя | |
* - метод getTotalCount - получение общей суммы чего-либо | |
* | |
*/ | |
interface IDlvVisitee | |
{ | |
public function accept(IDeliveryVisistor $visitor); | |
public function getTotalCount(); | |
} | |
/** | |
* Три конкретных реализации посещаемых объектов | |
* В данном случае это некие гипотетические службы | |
* доставки, позволяющие рассчитать стоимость | |
* доставки для каждой из них. | |
*/ | |
class Dlv1 implements IDlvVisitee | |
{ | |
private $data; | |
public function __construct($params) | |
{ | |
$this->data = $params; | |
} | |
public function getTotalCount() | |
{ | |
return __CLASS__ . ' of TOTAL!'; | |
} | |
public function accept(IDeliveryVisistor $visitor) | |
{ | |
return $visitor->visit($this); | |
} | |
} | |
class Dlv2 implements IDlvVisitee | |
{ | |
private $data; | |
public function __construct($params) | |
{ | |
$this->data = $params; | |
} | |
public function getTotalCount() | |
{ | |
return __CLASS__ . ' of TOTAL!'; | |
} | |
public function accept(IDeliveryVisistor $visitor) | |
{ | |
return $visitor->visit($this); | |
} | |
} | |
class Dlv3 implements IDlvVisitee | |
{ | |
private $data; | |
public function __construct($params) | |
{ | |
$this->data = $params; | |
} | |
public function getTotalCount() | |
{ | |
return __CLASS__ . ' of TOTAL!'; | |
} | |
public function accept(IDeliveryVisistor $visitor) | |
{ | |
return $visitor->visit($this); | |
} | |
} | |
/** | |
* Интерфейс посетителя | |
* Объект посетителя должен поддерживать метод visit | |
* в который передается посещаемый объект. | |
* В данном случае необходимо чтобы посещаемый | |
* объект расширял интерфейс IDlvVisitee | |
*/ | |
interface IDeliveryVisistor { | |
public function visit(IDlvVisitee $visitee); | |
} | |
/** | |
* Реализация простого посетителя | |
* С полученного объекта $visitee | |
* вызывается метод getTotalCount() | |
* возвращающий необходимые данные | |
*/ | |
class DeliveryVisitor implements IDeliveryVisistor | |
{ | |
public function __construct() | |
{ | |
} | |
/** | |
* На самом деле не совсем тру, ибо | |
* мы все-таки заставляем $visitee | |
* что-то реализовывать самостоятельно | |
* а по идее этого быть не должно. | |
* Мы должны просто получать свойства | |
* объекта и группировать их как | |
* надо конкретному посетителю | |
* | |
*/ | |
public function visit(IDlvVisitee $visitee) | |
{ | |
echo'<pre>',print_r($visitee),'</pre>'; // TODO | |
return $visitee->getTotalCount(); | |
} | |
} | |
/* Пример */ | |
/* Создаем набор доставок */ | |
$deliveries_pool = array( | |
new Dlv1, | |
new Dlv2, | |
new Dlv3, | |
); | |
echo'<pre>Pool files: ',print_r($deliveries_pool),'</pre>'; | |
echo'<hr />'; | |
/* Создаем посетителя */ | |
$visitor = new DeliveryVisitor; | |
echo'<pre>',print_r($visitor),'</pre>'; | |
echo'<hr />'; | |
/* Посещаем все доставки и получаем отдаваемые ими данные */ | |
$results = []; | |
foreach ($deliveries_pool as $dlv) { | |
$results[] = $dlv->accept($visitor); | |
} | |
echo'<hr />'; | |
echo'<pre>$results: ',print_r($results),'</pre>'; | |
die('Dead in ' . __FILE__ . ' on line '. __LINE__ . PHP_EOL); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment