Фабричный шаблон для времени компиляции (с аргументами) - PullRequest
0 голосов
/ 12 июня 2018

Следуя моему предыдущему вопросу, Шаблон фабрики для времени компиляции , очевидно, я упростил пример кода и пропустил некоторые части проблемы передачи аргументов в Событие экземпляр

Я пытаюсь определить правильный дизайн для этой проблемы

У меня есть три класса Поток , Потребитель и Событие

public class Thread {
    private Consumer _consumer = new Consumer();
}

public class Consumer {
    private someMethod() {
        Event event = new Event(arg1, arg2);
        // do something with event 
    }
}

В моем "главном" T создан и его зависимости инкапсулированы

Thread t = new Thread();

Теперь дизайн изменился, и нам нужно несколько Consumer s, и каждый из них должен построитьотличается Event.Код одинаков для всех, поэтому мне не нужно менять Consumer.

Я попытался сделать это с помощью дженериков, так как, похоже, это простой и понятный способ.Однако похоже, что невозможно использовать new для универсального типа.(Введено в заблуждение шаблонами C ++)

public class Thread<T extends Event> {
    private Consumer _c = new Consumer<T>();
}

public class Consumer<T extends Event> {
    private someMethod() {
        Event event = new T(arg1, arg2);
    }
}

Мой другой вариант - передать какую-то фабрику времени компиляции

public interface IEventFactory {
    public Event create(Arg1 arg1, Arg2 arg2);
}

public class EventFactory implements IEventFactory{
    public Event create(Arg1 arg1, Arg2 arg2) {
        return new Event1(arg1, arg2);
    }
}

public class Thread {
    private Consumer _consumer;

    public Thread (IEventFactory _factory) {
        _consumer = new Consumer(_factory);
    }
}

public class Consumer {
    private IEventFactory _factory;

    public C(IEventFactory factory) {
        _factory = factory;
    }

    private someMethod() {
        Event event = _factory.create(arg1, arg2);
    }
}

Есть ли лучший и более элегантный подход к этому?

1 Ответ

0 голосов
/ 12 июня 2018

Позвольте мне сначала указать, что ваш выбор имен классов не так хорош, как можно было бы предположить, что вы кодируете в Java.Я бы не использовал Thread, который является именем базового класса в Java и импортируется по умолчанию из java.lang.*.

. В последних версиях уже существует класс Consumer<T> (1.7+ или1.8+ не уверен), и поэтому я бы также избегал использовать это имя, хотя он не входит в список импорта по умолчанию, и это может сбить с толку многих, но многих сбить с толку.Кроме того, мне кажется, что вместо событий «Потреблять» оно предоставляет событие, поэтому, возможно, вам следует подумать о том, чтобы измениться к этому.

Я бы предложил использовать EventThread или EventProcessor или что-то в этом роде дляпервый и EventSupplier или EventFactory или аналогичный для последнего.

О фактическом дизайне ... Я бы сказал, что ваш Consumer сам по себе является фабрикой (поэтому я предлагаю так его назвать)так зачем вам нужен еще один тип для фабрики?

class Event {}
class EventSupplier<E extends Event> {
     public E get(Arg1 arg, Arg2 arg2);
}
class EventThread<E extends Event> {
     EventSupplier<E extends Event> supplier;

     public EventThread(EventSupplier<E> supplier) {
        this.supplier = supplier;
     }

     public process(Arg1 arg1, Arg2 arg2) {
           E event = supplier.get(arg1, arg2);
     }
}

Теперь, возможно, дьявол кроется в деталях, которые вы не раскрыли, например, в основном коде для класса потока (например, откуда берутся arg1, arg2 ?, как обрабатываются события одно за другим?) и для поставщика или потребителя (так что он фактически потребляет события, а не просто создает их?)

Возможно, вы хотитедобавьте вещественное значение EventConsumer, к которому поток будет передавать событие, созданное поставщиком:

class EventConsumer<E extend Event> {
     void receive(E event) {...}
} 

class EventThread<E extends Event> {
     EventSupplier<E> supplier;
     EventConsumer<E> consumer;

     public EventThread(EventSupplier<E> supplier, EventConsumer<E> consumer) { 
     this.supplier = supplier; 
     this.consumer = consumer 
   }

   void process(Arg1 arg1, Arg2 arg2) {
      E event = supplier.get(arg1, arg2);
      consumer.receive(event);
   }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...