Организация Factory method
У меня возникла необходимость написать объекты, связанные посредником
Структура проекта выглядит сейчас примерно так:
Интерфейс посредника
public interface ForkMediator {
void appendFork(ForkedObject forkedObject); //добавление объекта к посреднику
ForkedObject[] getForkData(ForkedObject forkedObject); //вернуть все объекты связанные с forkedObject
}
Интерфейс объектов соединяемых посредником
public interface ForkedObject{
double getPositive();
double getNegative();
double getJPositive();
double getJNegative();
void Run();
}
Конечному пользователю я не хочу предоставлять знание о том, что ForkedObject используют ForkMediator. ForkMediator имеет разную логику для различного количества добавленных к нему ForkedObject. Т.е если ForkMediator следит за 2 объектами, то его логика принципиально отличается от логики ForkMediator, который следит за 3 объектами
Я хочу предоставить пользователю интерфейс ForkObjectsFactory и некоторый набор классов конкретных фабрик: TwoForkObjects (создает 2 объекта и посредника для них), ThreeForkObjects(создает три объекта и посредника для них). В целом количество фабрик будет не очень большим.
Проблема в следующем: Все конкретные ForkObject имеют 2 обязательных параметра, мне в голову приходит только такая реализация фабрики для создания этих объектов
Интерфейс фабрики
public interface ForkFactory {
ForkedObject[] getObjects();
}
Конкретный класс фабрики возвращающей массив из 2 ForkedObject связанных посредником
public class TwoForkFactory implements ForkFactory {
private Fork[] forks=new Fork[2];
public TwoForkFactory(double field1Fork1, double field2Fork1,double field1Fork2, double field2Fork2){
ForkMediator twoForkMediator=new TwoForkMediator();
forks[0]=new Fork(field1Fork1, field2Fork1, twoForkMediator);
forks[1]=new Fork(field1Fork2, field2Fork2, twoForkMediator);
}
@Override
public ForkedObject[] getObjects() {
return forkPipelines;
}
Вызов в пользовательском коде
ForkFactory factory= new TwoForkFactory (1.0, 2.0, 1.1, 2.5);
ForkedObject[] forkObjects=factory.getObjects();
forkObjects[0].Run(); //в этом методе посредник передает данные между forkObjects
Может быть есть более аккуратное решение, чтобы не передавать в конструктор TwoForkFactory 4 параметра (а для ThreeForkFactory их уже станет 6)?
Ответы (1 шт):
По описанию это выглядит странно. Если вы сможете выложить код со всеми указанными классами, я думаю, найдется решение на много проще описанного. Кроме того, GoF - это не готовые решения и тем более не ответ на все вопросы. Адаптировать GoF под текущую задачу нужно самому. Зачастую необходимо скручивать гибрид из нескольких паттернов. В данном случае вам нужен фабричный метод, который создает медиаторы. Канонически это отдельные классы (я имею в виду классы для реализации самого фабричного метода). Практически так уже никто не пишет. Для реализации фабричного метода используют статический метод в классе-родителе (интерфейсе), возвращающий переменную типа самого себя. Посмотрите в джаве на лист или сет, тем есть метод of() или в спринге Page.of(). никаких дополнительных классов. Что касается логики инициализации и определения , что именно создавать зависит только от вас. Посему то, что у вас называется фабрики, вообще не нужны. я сделал ForkMediator абстрактным классом просто для того, чтобы реализовать приватный метод. инициализирующий массивы. вы можете вывести интерфейс. пеоскольку я не понял логики преобразования массива Fork в ForkedObject, я возвращаю вам массив Fork. Дальше все просто. Привожу класс ForkMediator и клиентский код.
import java.util.ArrayList;
import java.util.List;
public abstract class ForkMediator {
public static Fork[] of(double ... args){
switch(args.length/2){
case 2: return createFork(new TwoForkMediator(), args);
}
}
private Fork[] createFork (ForkMediator forkMediator, double ... args){
final List<Fork> forks = new ArrayList<>();
for (int i = 1; i < args.length; i+=2)
forks.add(new Fork(args[i-1], args[i], forkMediator));
return forks.toArray(new Fork[forks.size()]);
}
abstract void appendFork(ForkedObject forkedObject); //добавление объекта к посреднику
abstract ForkedObject[] getForkData(ForkedObject forkedObject); //вернуть все объекты связанные с forkedObject
}
//вызов из клиента
Fork[] result = ForkMediator.of(1.0, 2.0, 1.1, 2.5);
опять же, если покажете весь код (можете на гите), то думаю, что решение будет другое