Контекст стратегии

Sufir

Я не волшебник, я только учусь
Википедия предлагает следующий вариант реализации Стратегии
PHP:
<?php

interface NamingStrategy {
    function createName($filename);
}
class ZipFileNamingStrategy implements NamingStrategy {
    function createName($filename)
    {
        return "http://downloads.foo.bar/{$filename}.zip";
    }
}
class TarGzFileNamingStrategy implements NamingStrategy {
    function createName($filename)
    {
        return "http://downloads.foo.bar/{$filename}.tar.gz";
    }
}
class Context {
    private $namingStrategy;
    function __construct(NamingStrategy $strategy)
    {
        $this->namingStrategy = $strategy;
    }
    function execute()
    {
        $url[] = $this->namingStrategy->createName("Calc101");
        $url[] = $this->namingStrategy->createName("Stat2000");
        return $url;
    }
}
if (strstr($_SERVER["HTTP_USER_AGENT"], "Win"))
    $context = new Context(new ZipFileNamingStrategy());
else
    $context = new Context(new TarGzFileNamingStrategy());
$context->execute();
Однако мне остаётся не понятно, какую роль должен выполнять Context. Если мы имеем несколько классов реализующих необходимый интерфейс, то зачем эта обёртка и почему не пользоваться классами напрямую?
PHP:
// Как-то так
if (strstr($_SERVER["HTTP_USER_AGENT"], "Win")) {
    $strategy = new ZipFileNamingStrategy();
} else {
    $strategy = new TarGzFileNamingStrategy();
}
$strategy->createName("Stat2000");
$strategy->createName("Calc101");
Может кто-то объяснить или дать хороший пример в реальном коде?
 

HraKK

Мудак
Команда форума
потому что в Context у вас инкапсулирована логика дейстивй над стратегией. Читаем про инкапсуляцию.
 

Redjik

Джедай-мастер
Контекст реализует стратегию, на php тяжело понять весь глубинный смысл сего действа =)

В динамическом приложении у нас есть обьект - Рыцарь.
У него есть контекст - драка.
И стратегией мы подсовываем ему разные мечи, луки, кинжалы.
То есть во время жизни обьекта-рыцаря, мы можем изменить его оружие.

По поводу примера, можно использовать классы напрямую, но будут if-else или switch, и хардкод.
+ надо делать проверку
PHP:
if ($strategy implements NamingStrategy){
    $strategy->createName("Stat2000");
    $strategy->createName("Calc101");
} else {
    throw new Exception(...);
}
В примере с вики, тоже элементы хардкода, но тут надо подключать воображение и представлять, что
PHP:
if (strstr($_SERVER["HTTP_USER_AGENT"], "Win"))
    $context = new Context(new ZipFileNamingStrategy());
else
    $context = new Context(new TarGzFileNamingStrategy());
вот этот кусок заменен на фабрику
 

Sufir

Я не волшебник, я только учусь
Вот про вас-то @AmdY и говорил...
"Недоинженеринг" не на много лучше "оверинженеринга", экшны на полтысячи и более строк с развесистыми условиями и циклами тоже не радуют. Всегда нужно баланс находить и принимать решение исходя из конкретной задачи и конкретных требований. А знать и понимать лишним не будет никогда, даже если и не будешь применять... Я так думаю.
Redjik, благодарю. Да, если заменить этот кусок на фабрику, то всё становится на места. И всё же реальный пример увидеть хотелось бы. Может в каком-то фреймворке попадалось?
 
Последнее редактирование:

HraKK

Мудак
Команда форума
Реальный пример - я делаю аппликейшен под айпад и айфон. Но интерфейс у меня получается разный на одной и той же страницы могут быть разные элементы и разное поведение в зависимости от разных устройств. Но ощий лайаут с его поведением одинаковый. Поэтому в него я передаю стратегию где и как разворачивать этот лайаут.
 
  • Like
Реакции: AmdY

AmdY

Пью пиво
Команда форума
Для стратегии класическим примером является корзина в магазине, погугли, кучу презенташек найдёшь. Когда ты осуществляешь покупку она зависит не только от товаров, но и бонусных карт, текущих акций и т.д. Так что просто накидываешь нужные стратегии и получаешь счёт. А все эти синтетические примеры только путают людей.
 

Redjik

Джедай-мастер
Для стратегии класическим примером является корзина в магазине, погугли, кучу презенташек найдёшь. Когда ты осуществляешь покупку она зависит не только от товаров, но и бонусных карт, текущих акций и т.д. Так что просто накидываешь нужные стратегии и получаешь счёт. А все эти синтетические примеры только путают людей.
та не, тут стратегия не очень, лучше декорировать
 
Сверху