java - 推荐设计模式java动态调用

标签 java design-patterns

我有以下数据库表:

id method_id
1   1
1   2
1   3

和 2 个类:

EmailController 和Smscontroller

在我的代码中,我需要遍历表格并根据 method_id(1 或 2)调用 EmailController 或 Smscontroller 的发送方法。

推荐的设计模式是什么?

已编辑

可能有 100 种方法!我只放了 3 个。这就是为什么我不喜欢 if else 的原因。

同样,我发送到 EmailController 发送方法的对象与我发送到 SmsController 发送方法的对象不同。

在 EmailController 中,我需要发送用户对象。 在 SmsController 中,我需要发送 Manager 对象

最佳答案

我想不出设计模式。但为了获得最大的灵 active ,您可以采用类似这样的设计:

public interface Sendable /* or Sender, SendingManager, etc. */ {
  public int getId();
  public void send();
}

public class EmailController implements Sendable {
}

public class SmsController implements Sendable {
}

public class Sendables {

 private Map<Integer, Sendable> sendables = new HashMap<Integer, Sendable>();

 public void addSendable(Sendable s) {
   this.sendables.put(s.getId(), s);
 }

 public void sendById(Integer id) {
   this.sendables.get(id).send();
 }

}

然后你可以像这样使用它:

Sendables sendables = new Sendables();
sendables.add(new EmailController());
sendables.add(new SmsController());
sendables.add(new ChatController());
// etc.


Row row = table.getRow(...); // let's assume this gets a row from your table
sendables.send(row.getId());

另一个解决方案可能是有一个像这样的额外表:

TABLE: CLASS_NAMES
method_id class_name
1         "com.foo.SmsController"
2         "com.foo.EmailController"

然后将class_name传递给Class.forName,让它实例化出合适的controller供你使用。

编辑: Luis 建议的基于反射的代码版本。请注意,对于生产用途,您应确保传递的参数有效(不为空等),并严格处理异常。

表:CLASS_NAMES

method_id class_name                 param_class_name
1         "com.foo.SmsController"    "com.foo.Manager"
2         "com.foo.EmailController"  "com.foo.User"

发送管理器

public class SendManager {

    private static final String SEND_METHOD_NAME = "send";

    /* DAO for the CLASS_NAMES tables */
    private ClassNameDAO classNameDao;

    /**
     * Gets the row corresponding to methodId, for example
     * (1, "com.foo.SmsController", "com.foo.Manager") then using reflection
     * instantiates an instance of SmsController and invokes its send method
     * with <code>param</code> passed to it.
     */
    public void send(int methodId, Object param) throws Exception {
        ClassNameRow classNameRow = classNameDao.findByMethodId(methodId);

        String senderParameterClassName = className.senderParameterClassName();
        Class paramClass = Class.forName(senderParameterClassName);

        if (!paramClass.isInstance(param)) {
            throw new IllegalArgumentException("methodId and param are not compatible");
        }

        String senderClassName = classNameRow.getSenderClassName();
        Class senderClass = Class.forName(senderClassName);     

        /* Your sender classes must be JavaBeans and have no-arg constructors */
        Object sender = senderClass.newInstance();

        Class paramClass = Class.forName(senderParameterClassName);

        Method send = senderClass.getMethod(SEND_METHOD_NAME, paramClass);

        send.invoke(sender, param);
    }

}

示例用法

SendManager sendManager = new SendManager();

Manager m = ...;
sendManager.send(1, m);

User u = ...;
sendManager.send(2, u);

关于java - 推荐设计模式java动态调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8956802/

相关文章:

java - 整数数组列表到字符串的转换

java - log4j中使用的模式是什么

design-patterns - CQRS:命令返回值

design-patterns - 您想在哪里捕捉异常,为什么?

java - 使用输入循环动态创建对象

java - IntelliJ 中的 JSTL 在 JSP 中给出错误

java - 简单 while 循环的时间复杂度

c++ - 如何避免在父构造函数更改时更改每个子构造函数

java - 页面日志记录的设计模式

java - 从存在键的映射基础中提取值