[Moscow.pm] Strategy ("Стратегия") и "Декоратор"(Decorator/Wrapper) реализация на Perl

Shrub Alexey ashrub на agava.com
Ср Июл 9 23:01:32 PDT 2008


Can't bless non-reference value at ./decorator.pl line 31
поправил, получил
Can't use string ("f") as an ARRAY ref while "strict refs" in use at 
./decorator.pl line 120.

дальше смотреть поленился, что не так?
perl, v5.8.8 built for i486-linux-gnu-thread-multi, Debian GNU/Linux

Orlovsky Alexander wrote:
> Итак, первыми паттернами для реализации я выбрал родственные шаблоны Strategy ("Стратегия") и "Декоратор"(Decorator/Wrapper).
> В начале немного теории. (Не забываем про поисковики :)
> 
> Несмотря на то, что "Декоратор" и "Стратегия" в GoF-буке находятся в разных разделах ("Структурные паттерны" и "Паттерны поведения" соответственно), эти паттерны решают похожие задачи. Оба могут удалять условную логику и оба делают это, перемещая такое поведение в один или несколько новых классов вне рамок существующего класса.
> 
> Различие заключается в способе использования этих новых классов.
> 
> Декораторы (их экземпляры) представляют собой оболочки вокруг объекта (или друг друга), в то время, как один или несколько экземпляров стратегии  используются внутри объекта.
> 
> Декораторы несколько более тяжеловесны, т.к. базовые классы в общем случае не могут разделять их объекты (в отличие от стратегий).
> 
> Интерфейс стратегии может быть произвольным, в отличие от интерфейса декоратора. Класс декоратора должен реализовывать те же методы, что и классы которые он декорирует (имеет общий с ними интерфейс).
> 
> Классы, вокруг которых оборачивается декоратор, ничего не знают о нем, но если мы используем шаблон стратегии, то класс знает о существовании объектов стратегий и должен уметь их использовать.
> 
> Внутри классов, содержащих много данных и реализующих много открытых методов, традиционно используют одну или несколько стратегий.
> 
> ------------------------------------------------------------------------------------
> 1) "Декоратор":
> 
> Дополнительная информация, а также UML-схема примера реализации:
> http://codelab.ru/pattern/decorator/
> http://en.wikipedia.org/wiki/Decorator_pattern
> 
> Пример кода: http://paste.org/index.php?id=3271
> 
> Комментарий к коду:
> 
> В коде реализованы два "компонента": SimpleArrayPrinter, PrettyArrayPrinter, наследующих от общего предка ArrayPrinter.
> ArrayPrinter служит аналогом абстрактного класса "Component" в схеме из [1]  (см. также ссылки выше).
> 
> SimpleArrayPrinter, PrettyArrayPrinter -- это реализации "ConcreteComponent".
> SimpleArrayPrinter -- выводит матрицу на экран практически без какого-либо оформления. (не считая разделитель) 
> PrettyArrayPrinter -- выводит матрицу с помощью CPAN-модуля Pretty::Table (это сделано для простоты и наглядности, в реальном декораторе, скорее всего содержалась бы больше логики оформления)
> 
> Decorator -- аналог абстрактного класса "Decorator" [1], от него наследуются два подкласса декораторов (на схеме это "ConcreteDecorator"-ы)
> c именами: VerticalDecorator, ReverseDecorator.
> Класс Decorator, в свою очередь, наследует от ArrayPrinter, т.к. должен реализовывать общий с ним интерфейс (чтобы быть прозрачным для 
> 
> клиента и других декораторов в цепочке).
> 
> VerticalDecorator -- "переворчивает" матрицу на 90%
> ReverseDecorator  -- обращает списки элементов в каждой из строк.
> 
> На примере можно убедиться, что можно оборачивать любой из объектов семейства ArrayPrinter декораторами в любой последовательности. 
> 
> Попробуйте поменять местами вызов декораторов, а также подставить вместо "PrettyArrayPrinter->new(" строку "SimpleArrayPrinter->new(".
> Также можно убрать какой-либо декоратор из цепочки (либо убрать все декораторы вовсе), после чего увидеть как измененилось поведение объекта.
> 
> Можно отметить, что конструктор декоратора помимо декорируемого объекта может принимать и дополнительные параметры, которые могут менять его поведение. 
> 
> ( см. также Class::Decorator на CPAN )
> 
> ------------------------------------------------------------------------------------
> 1) "Стратегия":
> 
>  Шаблон "Стратегия" обычно применяют как способ для исключения условной логики.
> 
> Дополнительная информация, а также UML-схема примера реализации:
> http://codelab.ru/pattern/strategy/
> http://en.wikipedia.org/wiki/Strategy_pattern
> 
> Пример кода: http://paste.org/index.php?id=3272
> 
> Комментарии к коду:
> Вообще код достаточно простой и не нуждается в дополнительных комментариях. 
> 
> Замечу, что можно реализовать паттерн стратегия и не используя классы стратегий ("ConcreteStartegy").
> Вместо ссылки на объект, можно ссылку на функцию, нужным образом обрабатывающую данные. 
> Это также будет шаблон "Стратегия". Объекты конкретных стратегий могут понадобится при достаточно сложном внутреннем устройстве реализации стратегии. (к сожалению затрудняюсь привести хороший пример, может быть подписчики помогут?)
> ---------------------------------------------------------
> 
> Литература:
> [1] "Приемы объектно-ориентированного проектирования. Паттерны проектирования." Гамма, Хели, Джонсон, Влиссидес
> [2] "Рефакторинг с использованием шаблонов" Д. Кириевски
> [3] "Рефакторинг" Фаулер
> --
> Moscow.pm mailing list
> moscow-pm на pm.org | http://moscow.pm.org

-- 
Шруб Алексей
developer
icq: 345894734
http://www.agava.ru/


Подробная информация о списке рассылки Moscow-pm