Pattern Strategy implementation
(По книге O’Reilly — Head First — "Design Patterns")
На мой взгляд, книга O’Reilly "Head First — Design Patterns" - одна из лучших книг по паттернам - но когда я читал ее, у меня были кое-где неясности, и поэтому я решил написать эту статью.
Паттерн стратегия — самый простой из паттернов.
Паттерн Стратегия определяет семейство алгоритмов, инкапсулирует каждый из них и обеспечивает их взаимозаменяемость. Он позволяет модифицировать алгоритмы независимо от их использования на стороне клиента.
Для примера возьмем класс «утка» с методами «квак» и «показать».
Класс утка — суперкласс. От него мы будем наследовать.
Пусть у нас будут еще две утки — WildDuck и CityDuck.
У всех уток есть метод «display». Добавим еще резиновую утку, а в наш суперкласс добавим метод fly() - «летать».
Добавим еще несколько уток.
Но резиновые утки не летают. А у CloudDuck и MountainDuck один и тот же способ полета.
Т.е. у CloudDuck и MountainDuck будет одинаковый метод fly(), но отличающийся от метода fly() утки CloudDuck. Значит нужен другой класс для нового способа полета. Но это неправильный путь.
А что если нам нужно добавить метод eat(), и у разных видов уток он будет иметь разную реализацию? У нас в джаве нет множественного наследования (см. Ромбовидная проблема). Поэтому нам нужно другое решение.
Перейдем к решению проблемы.
Все наши классы — это клиенты для алгоритмов и они используют различные алгоритмы для реализации метода fly().
У нас есть алгоритм для метода fly() и алгоритм для метода Quack(). То есть мы должны создать стратегию для метода fly() и для метода Quack(). Мы должны извлечь эти методы чтобы использовать различные реализации.
Создадим интерфейс IQuackBehaviour для метода quack().
И создадим интерфейс IFlyBehaviour для метода fly().
Возможно даже было бы сделать из этих двух интерфейсов один интерфейс IDuckBehaviour.
Таким образом мы вынесли поведение уток за пределы класса Duck.
Интерфейс поведения будет реализовываться классами поведения, а не классом Duck.
Каждая утка будет иметь свой IFlyBehaviour и свой IQuackBehaviour.
Класс SimpleQuack реализует интерфейс IQuackBehaviour.
Мы можем сказать, что Quack() метод класса Duck передает полномочия интерфейсу IQuackBehaviour.
Когда мы вызываем метод Quack() класса Duck — мы запускаем метод Quack() класса SimpleDuck.
Резиновая утка не крякает, поэтому для нее будет еще одна реализация интерфейса.
Теперь класс Duck не должен заботиться о реализации кваканья уток. Класс Duck только должен иметь доступ к реализации интерфейса IQuackBehaviour.
Сделаем то же для IFlyBehaviour.
Можем поступить аналогично для метода Display().
SipmpleQuack, NoQuack, SimpleFly… — это конкретные стратегии.
На самом деле нам теперь не нужны сублассы WildDuck и CityDuck и мы можем их убрать.
Для удобства кодирования приведем нашу схему к следующему виду:
В IDE наши классы выглядят следующим образом:
Посмотрим на код.
Код класса "Реальная утка" выглядит следующим образом:
public MallardDuck(){quackBehavior = new Quack(); flyBehaviour = new FlyWithWings()} @Override public void display(){System.out.println("I am a real Mallard Duck ")} }
Абстрактная утка — наш суперкласс. Код класса "Абстрактная утка" приведен ниже:
public QuackBehavior quackBehavior; public FlyBehaviour flyBehaviour; public Duck(){} public abstract void display(); public void performFly(){flyBehaviour.fly()} public void performQuack(){quackBehavior.quack()} public void swim(){System.out.println("All ducks float, even decoys!")} }
Рассмотрим интерфейсы с описанием поведения уток.
Код интерфейса "FlyBehaviour" приведен ниже:
Код интерфейса "QuackBehavior":
Ниже приведен код конкретных стратегий поведения. Стратегия FlyNoWay:
Стратегия FlyWithWings:
Стратегия MuteQuack:
Стратегия Quack:
Стратегия Squeak:
Ниже приведен код класса "мини утиный симулятор":
public static void main(String[] args){Duck mallard = new MallardDuck(); mallard.performQuack(); mallard.performFly()} }
В данной статье мы рассмотрели самый простой из паттернов - паттерн "Стратегия".
Весь код можно посмотреть на моем гитхабе https://github.com/alexandroid1/PatternStrategy
Меня можно найти в соц сетях: Мой Linkedin https://www.linkedin.com/in/alexandroid1/ Моя личная страница ВК https://vk.com/sashapavlov Мой Instagramm https://www.instagram.com/aleksandr_7017/ Я в Facebook https://www.facebook.com/aleksandr7017
1. Элизабет Фримен, Эрик Фримен, Кэти Сиерра, Берт Бейтс - "Паттерны проектирования". 2. Strategy Pattern – Design Patterns (ep 1) - https://www.youtube.com/watch?v=v9ejT8FO-7I











