<?php
namespace RefactoringGuru\Strategy\Conceptual;
/**
* The Context defines the interface of interest to clients.
*/
class Context
{
/**
* @var Strategy The Context maintains a reference to one of the Strategy
* objects. The Context does not know the concrete class of a strategy. It
* should work with all strategies via the Strategy interface.
*/
private $strategy;
/**
* Usually, the Context accepts a strategy through the constructor, but also
* provides a setter to change it at runtime.
*/
public function __construct(Strategy $strategy)
{
$this->strategy = $strategy;
}
/**
* Usually, the Context allows replacing a Strategy object at runtime.
*/
public function setStrategy(Strategy $strategy)
{
$this->strategy = $strategy;
}
/**
* The Context delegates some work to the Strategy object instead of
* implementing multiple versions of the algorithm on its own.
*/
public function doSomeBusinessLogic(): void
{
// ...
echo "Context: Sorting data using the strategy (not sure how it'll do it)\n";
$result = $this->strategy->doAlgorithm(["a", "b", "c", "d", "e"]);
echo implode(",", $result) . "\n";
// ...
}
}
/**
* The Strategy interface declares operations common to all supported versions
* of some algorithm.
*
* The Context uses this interface to call the algorithm defined by Concrete
* Strategies.
*/
interface Strategy
{
public function doAlgorithm(array $data): array;
}
/**
* Concrete Strategies implement the algorithm while following the base Strategy
* interface. The interface makes them interchangeable in the Context.
*/
class ConcreteStrategyA implements Strategy
{
public function doAlgorithm(array $data): array
{
sort($data);
return $data;
}
}
class ConcreteStrategyB implements Strategy
{
public function doAlgorithm(array $data): array
{
rsort($data);
return $data;
}
}
// USAGE
/**
* The client code picks a concrete strategy and passes it to the context. The
* client should be aware of the differences between strategies in order to make
* the right choice.
*/
$context = new Context(new ConcreteStrategyA);
echo "Client: Strategy is set to normal sorting.\n";
$context->doSomeBusinessLogic();
echo "\n";
echo "Client: Strategy is set to reverse sorting.\n";
$context->setStrategy(new ConcreteStrategyB);
$context->doSomeBusinessLogic();
<?php
interface InterfaceLogger {
function log($message);
}
class FileLogger implements InterfaceLogger {
public function log($message) {
// code to write logging information to file system
}
}
class DatabaseLogger implements InterfaceLogger {
public function log($message) {
// code to write logging information to database
}
}
class EmailLogger implements InterfaceLogger {
public function log($message) {
// code to write logging information to email
}
}
// usage
$loggerType = 'file'; // file, database ...
switch($loggerType) {
case "file":
$logger = new FileLogger();
break;
case "database":
$logger = new DatabaseLogger();
break;
case "email":
$logger = new EmailLogger();
break;
default:
$logger = new FileLogger();
}
$logger->log();