И наконец... наследование

У нас есть несколько типов фильмов, которые по-разному отвечают на один и тот же вопрос. Похоже на то, что дело идет к подклассам. Можно унаследовать три класса от Movie, каждый из которых будет содержать свой вариант расчёта задолженности (Рис 1.14).

Рис 1.14 Наследование от класса Movie
Это позволит нам заменить switch на полиморфизм. Правда, есть небольшая неприятность: это не будет работать. Фильмы могут менять классификацию в процессе жизни (например, из новинки стать обычным или детским фильмом). Но ведь объекты не могуг изменять свой тип в процессе жизни. К счастью, у этой проблемы есть решение, паттерн State, разработанный "Бандой четырёх" (Gang of Four). При этом наши классы будут выглядеть следующим образом (см. Рис 1.15)

Рис 1.15 Применение паттерна State к классу Movie
Отвязав класс Movie от его, мы можем строить иерархию классов от объекта Price и менять цену в любое время.

Если вы хорошо знакомы с паттернами "Банды четырех", то, возможно, у вас возникнет сомнение: "Это State или Strategy?" Представляет ли класс Price алгоритм для расчёта цены (в этом случае я предпочёл бы назвать его Pricer или PricingStrategy), или же он представляет статус фильма (Star Trek X -- это новинка). На этом этапе выбор паттерна (и имён классов) зависит от того, как вы себе видите структуру. На данный момент я считаю, что это статус фильма. Если, позднее, я решу, что стратегия лучше отражает сущность происходящего, то я сделаю рефакторинг и изменю имена классов.

Чтобы перейти к паттерну State, нам придётся применить три рефакторинга. Первым делом переместим код типа фильма в паттерн State, применив рефакторинг Replace Type Code with State/Strategy (227). После этого используем Move Method (142), чтобы переместить switch в класс Price. И, наконец, используем Replace Conditional with Polymorphism (255), чтобы избавиться от switch.


В начало | предыдущая | следующая