Используйте декоратор и фабрику вместе, чтобы добавить свойства или специализировать объект

Я новичок в ООП и шаблоне проектирования.

У меня есть простое приложение, которое обрабатывает генерацию таблиц, столбцов (принадлежащих таблице), строк (принадлежащих столбцу) и значений (принадлежащих строкам). Каждый из этих объектов может быть коллекцией Property, которая в свою очередь определяется как enum.

Все они являются интерфейсами: я использовал фабрики, чтобы получить конкретные экземпляры этих продуктов.

Сейчас я сталкиваюсь с проблемой расширения этих классов. Допустим, мне нужен другой продукт с именем "SpecialTable", который, в свою очередь, имеет некоторые специальные свойства или новые методы, такие как "getSomethingSpecial" или расширенный набор Property. Единственный способ - расширить / специализировать все мои элементы (т.е. построить SpecialTableFactory, интерфейс SpecialTable и бетон SpecialTableImpl)? Допустим, я все еще хотел бы использовать стандартные методы, такие как addRow (column, name), которые не нужно наследовать...

Мне не нравится идея наследовать фабрики и интерфейс, но поскольку у SpecialTable больше методов, я думаю, что она не может использовать одну и ту же фабрику. Я ошибся?

Другой вопрос: если мне нужно определить свойства продукта во время выполнения (таблица, которая обновляется до SpecialTable), я думаю, что мне следует использовать декоратор. Можно ли (и как) совместить дизайн фабрики и декоратора?

1 ответ

Решение

SpecialTable нуждается в собственном механизме создания, поэтому да, ему понадобится собственный фабричный метод (или фабричный класс, если вы создаете группу элементов, которые должны быть связаны).

В качестве альтернативы: вы можете использовать стратегию шаблонов проектирования для своей фабрики. В этом случае вы настроите фабрику с желаемым механизмом создания во время выполнения.

Что касается оставшегося вопроса:

Три наиболее распространенных способа добавления функциональности в класс:

  1. Наследование
  2. Шаблон проектирования Adapter/Proxy, возможно, в сочетании с самоанализом. Категории действительно являются частным случаем этого подхода.
  3. Дизайн шаблона посетителя

Вы уже рассмотрели подклассы.

Шаблон проектирования Adapter / Proxy в основном таков: создайте новый класс, который имеет желаемый интерфейс, и реализует некоторые (или все) его методы, вызывая экземпляр вашего существующего класса.

Для Design pattern Visitor вы в некотором смысле объединяете Proxy с "Double Dispatch". Ваши добавленные функции находятся в объекте, который может вызывать экземпляр вашего существующего класса. Посмотрите шаблон посетителя - добавить новые классы ConcreteElement сложно? для примера.

Стратегия:

Это работает так:

public interface MyStrategyInterface {
  public void doWork();
}

public class MyStrategyAccessPoint implements MyStrategyInterface {

  private MyStrategyInterface current;

  public MyStrategyAccessPoint(final MyStrategyInterface initial) {
    current = initial;
  }

  public void doWork() {
    current.doWork();
  }

  public void setStrategy(final MyStrategyInterface newCurrent) {
    current = newCurrent;
  }
}

Как видите, теперь вы можете изменить, какая фактическая реализация MyStrategyInterface используется во время выполнения. Этот шаблон часто комбинируется с Singleton, делая статическую MyStrategyAccessPoint и его метод doWork.

Другие вопросы по тегам