-
-
Save mhlavac/465a0efc33ddaae61218 to your computer and use it in GitHub Desktop.
<?php | |
interface Greeter | |
{ | |
public function greet($name); | |
} | |
class ChainGreeter implements Greeter | |
{ | |
private $greeters = []; | |
public function addGreeter(Greeter $greeter) | |
{ | |
$this->greeters[] = $greeter; | |
} | |
public function greet($name) | |
{ | |
foreach ($this->greeters as $greeter) { | |
$greeter->greet($name); | |
} | |
} | |
} | |
class StringGreeter() implements Greeter | |
{ | |
private $sentence; | |
public function __construct($sentence) | |
{ | |
$this->sentence = $sentence; | |
} | |
public function greet($name) | |
{ | |
spritnf($sentence, $name); | |
} | |
} | |
$chainGreeter = new ChainGreeter(); | |
$chainGreeter->add(new StringGreeter('Hello %s')); | |
$chainGreeter->add(new StringGreeter('Good morning %s')); | |
$chainGreeter->greet('John Doe'); |
@jakubzapletal exactly, or at least if there is a foreach that goes over inner objects it ends as soon as it finds one. Like this example from ChainUserProvider:
/**
* {@inheritdoc}
*/
public function loadUserByUsername($username)
{
foreach ($this->providers as $provider) {
try {
return $provider->loadUserByUsername($username);
} catch (UsernameNotFoundException $notFound) {
// try next one
}
}
$ex = new UsernameNotFoundException(sprintf('There is no user with name "%s".', $username));
$ex->setUsername($username);
throw $ex;
}
@mhlavac accurate example of Chain of Responsibilities
This is not Chain of Responsibility pattern: https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern This is Composite: https://en.wikipedia.org/wiki/Composite_pattern
Haha the naming problem :)
Would agree with @pavel-dohnal-momentumft. To me this seems like the composite pattern.
So CompositeGreeter
? 😄
@pavel-dohnal-momentumft I also thought it's a composite, because this is how usuall composites are implemented.
So in the end I came with 2 ideas.
Command
where we can use just __invoke. So it feels almost like named closure
.
class GreetCommand
{
/**
* @var Greeter[]
*/
private $greeters;
public function __construct(array $greeters = [])
{
$this->greeters = $greeters;
}
public function __invoke($name)
{
foreach ($this->greeters as $greeter) {
$greeter->greet($name);
}
}
}
And simple Greeters
, because it's just multiple Greeters anyway.
class Greeters
{
/**
* @var Greeter[]
*/
private $greeters;
public function __construct(array $greeters = [])
{
$this->greeters = $greeters;
}
public function greet($name)
{
foreach ($this->greeters as $greeter) {
$greeter->greet($name);
}
}
}
What do you think? ;-)
@mhlavac I see
Collection
as a collection of objects being on the same level, but theChain
is an object inside an object inside an object (auto na auta na auta) :-).