【问题标题】:Creating a new instance of implemented class, based on argument class type根据参数类类型创建实现类的新实例
【发布时间】:2019-06-13 09:11:26
【问题描述】:

我将简要描述一下我的代码结构:

  • Aaa 类实现 EventEmmiter

  • Bbb 类实现 EventEmmiter

  • Class Aaa Event 实现 Event:

    public class AaaEvent implements Event {
    
        private final Aaa aaa;
    
        public AaaEvent(Aaa aaa) {
            this.aaa = aaa;
        }
    }
    
  • 类 BbbEvent 实现事件:

    public class BbbEvent implements Event {
       private final Bbb bbb;
       public BbbEvent(Bbb bbb) {
       this.bbb = bbb;
       }
    }
    

我想创建一个“createSomething”方法来避免代码重复。我希望这个方法根据参数类型(可以是 Aaa 或 Bbb)创建一个从 Event 实现的类的新实例。

//已编辑

您可以在下面找到 EventPublisher 类,它可以正常工作但看起来不是很好。我想避免 if/else 或 switch 实现,因为新类可能会越来越多。

public class EventPublisher {
    public void createSomething(EventEmitter eventEmitter) {
        DomainEvent event = null;
        Class<? extends EventEmitter> eventClass = eventEmitter.getClass();
        if (eventClass.isAssignableFrom(Aaa.class)) {
            event = new AaaEvents((Aaa) eventEmitter);
        } else if (eventClass.isAssignableFrom(Bbb.class)) {
            event = new BbbEvents((Bbb) eventEmitter);
        } else if () {
            some next (eg.CccEvents) class
        }

        domainEventBus.publish(event);
    }
}

例如。如果作为方法参数传递的 EventEmmiter 类型是 Aaa,我想创建一个新的 AaaEvent 实例。

还有一件事。我不能使用来自 AaaEvent 的 Aaa 东西的内部包。它在另一个方向上起作用。我可以在 AaaEvent 中使用 Aaa 包中的东西。

你能给我一些如何实现这些东西的提示吗?

【问题讨论】:

  • Aaa 和 AaaEvent 以及 Bbb 和 BbbEvent 之间没有直接联系,所以我想完成你想要的唯一方法是使用一些开关来检查 eventEmitter 类并创建相应的事件
  • 我也刚刚想到 - 您可以向EventEmitter 添加一些函数,该函数将创建所需类的事件,然后在 Aaa 和 Bbb 中覆盖此函数
  • 我编辑了我的问题。现在您看到 Aaa 事件中有 Aaa 参数。对于第二个答案,这是不可能的 - 看看我对 @Seelenvirtuose 的回答
  • 第一个(也是最重要的)结构问题:您的事件知道事件发射器。一个事件应该是一个没有任何进一步依赖的轻量级类。

标签: java design-patterns generic-programming


【解决方案1】:

你想实现factory method pattern:

public interface EventEmmiter {
    Event createEvent();
    ...
}

public class Aaa implements EventEmitter {
    @Override public AaaEvent createEvent() { return new AaaEvent(); }
    ...
}

public class Bbb implements EventEmitter {
    @Override public BbbEvent createEvent() { return new BbbEvent(); }
    ...
}

现在您可以简单地将其用作:

public void createSomething(EventEmitter eventEmitter) {
    Event someEvent = eventEmitter.createEvent();
    ...
}

【讨论】:

  • 嗯,问题是 Aaa 无法创建新的 AaaEvent 实例,因为包依赖。假设在 Aaa 模块中我不能使用 AaaEvent 模块的东西。它只在另一个方向起作用。这就是为什么我在考虑通用的实现方式
  • 那你好像遇到了结构性问题,应该先解决。这种模式绝对是要走的路。
  • 我稍微编辑了我的帖子以更好地描述我的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-03
  • 1970-01-01
相关资源
最近更新 更多