Стратегия (Strategy)

Стратегия — это поведенческий паттерн, выносит набор алгоритмов в собственные классы и делает их взаимозаменимыми.

Особенности паттерна на PHP

Стратегию часто используют в PHP-коде, особенно там, где нужно подменять алгоритм во время выполнения программы. Но у паттерна есть довольно сильный конкурент в лице анонимных функций, которые PHP уже довольно давно поддерживает.

Признаки применения паттерна: Класс делегирует выполнение вложенному объекту абстрактного типа или интерфейса.

<?php
 
/**
 * Интерфейс IFileSave объявляет операции, общие для всех поддерживаемых версий
 * некоторого алгоритма.
 * Interface IFileSave
 */
interface IFileSave
{
    public function save();
}
 
abstract class BaseSave implements IFileSave
{
    protected $filepath;
 
    public function __construct(string $filepath)
    {
        $this->filepath = $filepath;
    }
}
 
 
class DocumentsSave extends BaseSave
{
 
    /**
     * Конкретные Стратегии реализуют алгоритм, следуя базовому интерфейсу
     * Стратегии.
     */
    public function save()
    {
        if(file_exists('tmp/'.$this->filepath))
        {
            copy('tmp/'.$this->filepath, 'documents/'.$this->filepath);
        }
    }
}
 
class ImagesSave extends BaseSave
{
    /**
     * Конкретные Стратегии реализуют алгоритм, следуя базовому интерфейсу
     * Стратегии.
     */
    public function save()
    {
        if(file_exists('tmp/'.$this->filepath))
        {
            copy('tmp/'.$this->filepath, 'images/'.$this->filepath);
        }
    }
}
 
class BaseLogic
{
    private $saver;
 
    public function __construct(IFileSave $saver) {
        $this->saver = $saver;
    }
 
    public function execute() {
        $this->saver->save();
        return true;
    }
}
 
/**
 * Клиентский код выбирает конкретную стратегию и передаёт её в BaseLogic. Клиент
 * должен знать о различиях между стратегиями, чтобы сделать правильный выбор.
 */
$obj = new BaseLogic(new ImagesSave('builder.png'));
$obj->execute();
 
$obj = new BaseLogic(new DocumentsSave('patterns.docx'));
$obj->execute();