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

时间:2018-06-12 10:23:02

标签: java generics design-patterns

按照我之前的问题Factory pattern for compile time,显然,我过度简化了我的代码示例,并错过了将参数传递给事件实例

的部分问题

我想找出解决这个问题的正确设计

我有三个类线程消费者事件

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

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

在我的" main"创建T并封装其依赖项

Thread t = new Thread();

现在设计已经改变,我们需要多个Consumer,每个Event应该构建一个不同的Consumer。所有代码都相同,因此我不需要更改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); } }

我尝试用泛型来做,因为看起来这是一种简单而干净的方式。但是,看起来似乎无法在泛型类型上使用 new 。 (被C ++模板误导)

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);
    }
}

我的另一个选择是通过某种编译时工厂

obfuscateNums

是否有更好,更优雅的方式来接近这个?

1 个答案:

答案 0 :(得分:0)

首先我要指出,您在类名中的选择并不像您使用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);
   }
}