Используйте декоратор и фабрику вместе, чтобы добавить свойства или специализировать объект
Я новичок в ООП и шаблоне проектирования.
У меня есть простое приложение, которое обрабатывает генерацию таблиц, столбцов (принадлежащих таблице), строк (принадлежащих столбцу) и значений (принадлежащих строкам). Каждый из этих объектов может быть коллекцией Property, которая в свою очередь определяется как enum.
Все они являются интерфейсами: я использовал фабрики, чтобы получить конкретные экземпляры этих продуктов.
Сейчас я сталкиваюсь с проблемой расширения этих классов. Допустим, мне нужен другой продукт с именем "SpecialTable", который, в свою очередь, имеет некоторые специальные свойства или новые методы, такие как "getSomethingSpecial" или расширенный набор Property. Единственный способ - расширить / специализировать все мои элементы (т.е. построить SpecialTableFactory, интерфейс SpecialTable и бетон SpecialTableImpl)? Допустим, я все еще хотел бы использовать стандартные методы, такие как addRow (column, name), которые не нужно наследовать...
Мне не нравится идея наследовать фабрики и интерфейс, но поскольку у SpecialTable больше методов, я думаю, что она не может использовать одну и ту же фабрику. Я ошибся?
Другой вопрос: если мне нужно определить свойства продукта во время выполнения (таблица, которая обновляется до SpecialTable), я думаю, что мне следует использовать декоратор. Можно ли (и как) совместить дизайн фабрики и декоратора?
1 ответ
SpecialTable нуждается в собственном механизме создания, поэтому да, ему понадобится собственный фабричный метод (или фабричный класс, если вы создаете группу элементов, которые должны быть связаны).
В качестве альтернативы: вы можете использовать стратегию шаблонов проектирования для своей фабрики. В этом случае вы настроите фабрику с желаемым механизмом создания во время выполнения.
Что касается оставшегося вопроса:
Три наиболее распространенных способа добавления функциональности в класс:
- Наследование
- Шаблон проектирования Adapter/Proxy, возможно, в сочетании с самоанализом. Категории действительно являются частным случаем этого подхода.
- Дизайн шаблона посетителя
Вы уже рассмотрели подклассы.
Шаблон проектирования 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.