遵循我之前的问题,编译时的工厂模式,显然,我过度简化了我的代码示例,并错过了将参数传递给事件实例的部分问题
我正在尝试找出解决此问题的正确设计
我有三个类线程、使用者和事件
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+ 不确定(,所以我也会避免使用该名称,尽管它不在默认导入中,但它仍然会让许多人感到困惑,但许多人仍然感到困惑。此外,在我看来,它提供的不是消费事件,所以也许您也应该考虑改变这一点。
我建议你对前者使用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);
}
}