Created
January 9, 2017 15:32
-
-
Save jjsaunier/e82f562097973f6f9662cc9e50012833 to your computer and use it in GitHub Desktop.
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 | |
$strategist = new Strategist(); | |
$strategist->respect(function () use ($var) { | |
return true === $var; | |
})->then(function () use ($whatever) { | |
return $whatever->getTrue(); | |
}); | |
$strategist->respect(function () use ($var) { | |
return false === $var; | |
})->then(function () use ($whatever) { | |
return $whatever->getFalse(); | |
}); | |
$strategist->otherwise(function () use ($whatever) { | |
return $whatever->default(); | |
}); | |
$result = $strategist->resolve(); // depend of matched strategy |
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 | |
declare(strict_types=1); | |
namespace Strategy; | |
class Strategist | |
{ | |
/** | |
* @var Strategy[] | |
*/ | |
private $strategies; | |
/** | |
* @var callable | |
*/ | |
private $otherwise; | |
public function __construct() | |
{ | |
$this->strategies = []; | |
} | |
/** | |
* @param $spec | |
* | |
* @return Strategy | |
*/ | |
public function respect($spec) : Strategy | |
{ | |
$strategy = new Strategy($spec); | |
$this->strategies[] = $strategy; | |
return $strategy; | |
} | |
/** | |
* @param callable $callable | |
* | |
* @return Strategist | |
*/ | |
public function otherwise(callable $callable) : self | |
{ | |
$this->otherwise = $callable; | |
return $this; | |
} | |
/** | |
* @return mixed | |
*/ | |
public function resolve() | |
{ | |
$result = null; | |
$otherwise = $this->otherwise; | |
foreach ($this->strategies as $strategy) { | |
if (false === $strategy->isStatisfied()) { | |
continue; | |
} | |
$result = null; | |
$stack = $strategy->getHandlerStack(); | |
$stack->rewind(); | |
while ($stack->valid()) { | |
$handler = $stack->current(); | |
try { | |
$result = $handler($result); | |
} catch (\Throwable $e) { | |
return $otherwise($e); | |
} | |
$stack->next(); | |
} | |
$this->strategies = []; | |
return $result; | |
} | |
return $otherwise(); | |
} | |
} |
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 | |
declare(strict_types=1); | |
namespace Strategy; | |
class Strategy | |
{ | |
/** | |
* @var callable | |
*/ | |
private $spec; | |
/** | |
* @var callable[] | |
*/ | |
private $handlerStack; | |
/** | |
* Strategy constructor. | |
* | |
* @param callable $spec | |
*/ | |
public function __construct(callable $spec) | |
{ | |
$this->spec = $spec; | |
$this->handlerStack = new \SplStack(); | |
} | |
/** | |
* @return bool | |
*/ | |
public function isStatisfied() : bool | |
{ | |
return ($this->spec)(); | |
} | |
/** | |
* @param callable $callable | |
* | |
* @return Strategy | |
*/ | |
public function then(callable $callable) : self | |
{ | |
$this->handlerStack->push($callable); | |
return $this; | |
} | |
/** | |
* @return \SplStack | |
*/ | |
public function getHandlerStack() : \SplStack | |
{ | |
return $this->handlerStack; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment