$composite = new \CompositeAndStrategy\CompositeStrategy( new \CompositeAndStrategy\CompositeStrategyAnd( new \CompositeAndStrategy\CompositeStrategyOr( new \CompositeAndStrategy\StrategyFirst(), new \CompositeAndStrategy\StrategySecond() ), new \CompositeAndStrategy\StrategyThird() ), new \CompositeAndStrategy\CompositeStrategyOr( new \CompositeAndStrategy\StrategyFourth(), new \CompositeAndStrategy\StrategyFifth() ) ); $result = $composite->perform();
namespace CompositeAndStrategy; interface IStrategy { function perform(); }
namespace CompositeAndStrategy; interface ICompositeStrategy { function getAll(); function add(IStrategy $strategy); }
namespace CompositeAndStrategy; class CompositeStrategy implements ICompositeStrategy, IStrategy { public function __construct() { $strategies = func_get_args(); if ($strategies) { foreach($strategies as $strategy) { if ($strategy instanceof IStrategy) { $this->add($strategy); } } } } /** * @var IStrategy[] */ protected $collection; /** * @param IStrategy $strategy */ public function add(IStrategy $strategy) { $this->collection[] = $strategy; } /** * @return IStrategy[] */ public function getAll() { return $this->collection; } /** * @return IStrategy */ public function perform() { foreach($this->getAll() as $strategy) { if ($strategy->perform()) { return $strategy; } } } }
namespace CompositeAndStrategy; class CompositeStrategyAnd extends CompositeStrategy { /** * @return bool|CompositeStrategyAnd */ public function perform() { foreach($this->getAll() as $strategy) { if (!$strategy->perform()) { return false; } } return $this; } }
namespace CompositeAndStrategy; class CompositeStrategyOr extends CompositeStrategy { /** * @return CompositeStrategyOr */ public function perform() { foreach($this->getAll() as $strategy) { if ($strategy->perform()) { return $this; } } } }
namespace CompositeAndStrategy; class StrategyFirst implements IStrategy { /** * @param $bool * @return mixed */ protected function drawLog($bool) { echo get_called_class().' - ' . (int)$bool.'<hr />'; return $bool; } /** * @return bool|StrategyFirst */ public function perform() { if ($operation = $this->drawLog(rand(0, 1))) { return $this; } return false; } }
namespace CompositeAndStrategy; class StrategySecond extends StrategyFirst { }
namespace CompositeAndStrategy; class StrategyThird extends StrategyFirst { }
namespace CompositeAndStrategy; class StrategyFourth extends StrategyFirst { }
namespace CompositeAndStrategy; class StrategyFifth extends StrategyFirst { }
Source: https://habr.com/ru/post/137190/
All Articles