编译时的工厂模式(带参数)



遵循我之前的问题,编译时的工厂模式,显然,我过度简化了我的代码示例,并错过了将参数传递给事件实例的部分问题

我正在尝试找出解决此问题的正确设计

我有三个类线程使用者事件

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,每个都应该构建一个不同的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);
}
}

有没有更好、更优雅的方法来解决这个问题?

首先让我指出,你在类名中的选择不如你用Java编码所能做的那么好。我会避免使用Thread,它是 Java 中基本类的名称,默认情况下从java.lang.*导入。

在最新版本中已经有一个Consumer<T>类(1.7+ 或 1.8+ 不确定(,所以我也会避免使用该名称,尽管它不在默认导入中,但它仍然会让许多人感到困惑,但许多人仍然感到困惑。此外,在我看来,它提供的不是消费事件,所以也许您也应该考虑改变这一点。

我建议你对前者使用EventThreadEventProcessor或类似的东西,对后者使用EventSupplierEventFactory或类似的东西。

关于实际设计...我会说你的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);
}
}

最新更新