(ищу паттерн) Подмешивание фичи в дерево классов
От: sharez  
Дата: 04.06.17 08:12
Оценка:
Всем привет!

Сначала предыстория. Всё дело идёт в вебе, но это не столь важно.
Допустим, есть класс Dialog — окошко. У нас есть 3 типа отображения (не просто стилизация CSS, а даже разная структура HTML — это действительно требуется).
Сейчас код разных методов (buildDialogHtml(), getCssClass() и т. д.) представляют собой ветвистые if'ы:

protected buildDialogHtml() {
    if (ui == 0)
        this.buildDialogHtmlType0();
    else if (ui == 1)
        this.buildDialogHtmlType1();
    else 
        this.buildDialogHtmlType2();


Парадигма ООП говорит, что такой код можно и нужно разделить на иерархию классов:

- Dialog
  - DialogType0
  - DialogType1
  - DialogType2


OK, делаем приватный конструктор, публичный фабричный метод create(), который и возвращает нам инстанс нужного класса.

Всё бы ничего, но у нас вот была такая иерархия:

- ABaseDialog (lib)
  - VeryCustomUserDialog (user)
  - Dialog (lib)
    - MessageDialog (lib)
    - StandardUserDialog (user)


Как видите, получается, мы не можем вклиниться нашим ООП в такую структуру. Т. е. такое ветвление классов подходит только когда тип UI является гарантированно последним звеном в иерархии.

Как реализовать такую штуку, чтобы было красиво и расширяемо?
Может есть какой-то паттерн? Пока на ум приходит только паттерн делегата: создание какого-то объекта UIType внутри Dialog, которому и делегируются данные методы. Но это плодит кучу кода, навигация по которому так себе, и кажется, что уж лучше if'ы. Кроме того ведь пользователь нашей библиотеки может случайно переопределить метод, который вызывает делегата, и не будет понимать, почему всё сломалось (или сломалось только на конкретном типе UI).
Отредактировано 04.06.2017 8:14 sharez . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.