【问题标题】:Using Factory pattern with multiple arguments in Java在 Java 中使用具有多个参数的工厂模式
【发布时间】:2014-05-18 08:47:58
【问题描述】:

我有以下类结构: 包含一些常见成员(/字段)的基类“消息”, 'Imessage' 接口有一些所有消息都应该实现的方法, 许多不同的消息类扩展(继承)了基本的“消息”类并具有许多字段,每个消息类型的枚举和一个工厂类,给定一个枚举创建正确消息类的实例。

问题是我不确定在哪里/如何实现每个消息类的值设置。 它不能在它的构造函数中,因为在工厂方法中我需要构建通用实例。 我应该为每条消息实现一个“创建”方法来设置它的所有成员吗?

    public static Message buildMessage(MessageType messageType)
        {
            Message message = null;
            switch (messageType) //TODO: add all messages!
            {
                case CONNECT: 
                    message = new ConnectMessage();
                    break;
                case CONNECT_RESPONSE: 
                    message = new ConnectResponseMessage();
                    break;  
                case DISCONNECT: 
                    message = new DisconnectMessage();
                    break;
                case FLOWSTART: 
                    message = new FlowStartMessage();
                    break;
                default: return null;
            }

            return message;
        }

【问题讨论】:

  • 你能从构造函数中解释一下通用问题吗?举个例子还是别的?

标签: java design-patterns constructor factory


【解决方案1】:

工厂模式应该返回一个有效的、完全填充的对象,因此为每种类型的 Message 对象添加一个 Create 方法并不理想(除非从 buildMessage 中调用它)。

我不知道你说的是什么意思:

它不能在它的构造函数中,因为在工厂方法中我需要 构建通用实例。

这样初始化一个对象是完全有效的:

Message message = new ComplexMessage(type, value, something, somethingElse);
Message message = new LessComplexMessage(type, value);

在这种情况下,您的 buildMessage 方法可以接收构建消息的所有子类型所需的所有对象。

如果这变得过于复杂,因为必填字段的变化太多,那么可能值得升级到构建器模式:

http://javarevisited.blogspot.co.uk/2012/06/builder-design-pattern-in-java-example.html

【讨论】:

    【解决方案2】:

    这是一种可能的解决方案。您可以在Message 中编写一个构造函数并在子类中覆盖它。

    public class Message {
        private final String commonField;
    
        public Message(String commonField){
            this.commonField = commonField;
        }
    }
    

    在子类中

    public ConnectMessage(String commonField){
        super(commonField);
        //initialize
    }
    

    在工厂里做

    public static Message buildMessage(MessageType messageType, String commonValue)
            {
                Message message = null;
                switch (messageType) //TODO: add all messages!
                {
                    case CONNECT: 
                        message = new ConnectMessage(commonValue);
                        break;
                    case CONNECT_RESPONSE: 
                        message = new ConnectResponseMessage(commonValue);
                        break;  
                    case DISCONNECT: 
                        message = new DisconnectMessage(commonValue);
                        break;
                    case FLOWSTART: 
                        message = new FlowStartMessage(commonValue);
                        break;
                    default: return null;
                }
    
                return message;
            }
    

    【讨论】:

      【解决方案3】:

      如果消息定义是严格的,并且您没有创建消息组合或配置它们的属性,那么为什么要有工厂类?

      另一方面,enum 本身就可以做很多事情:

      public class Main {
      
          public static interface IMessage{
              public String getName();
          }
      
          public static class GoodMessage implements IMessage{
              @Override
              public String getName() {
                  return "Good";
              }
          }
      
          public static class BadMessage implements IMessage{
              @Override
              public String getName() {
                  return "Bad";
              }
          }
      
          public static interface IMsgGen{
              public IMessage create();
          }
      
          public static enum Messages implements IMsgGen {
      
              GOOD_MSG(GoodMessage.class),
      
              BAD_MSG(BadMessage.class),
      
              CUSTOM_MSG(null){
                  @Override
                  public IMessage create() {
                      return new IMessage() {
                          @Override
                          public String getName() {
                              return "Custom";
                          }
                      };
                  }
              };
      
              private final Class<? extends IMessage> mClass;
              private Messages(Class<? extends IMessage> aClass) {
                  mClass = aClass;
              }
      
              @Override
              public IMessage create() {
                  try {
                      return mClass.newInstance();
                  } catch (Exception e) {
                      throw new RuntimeException(e.getMessage(),e);
                  }
              }
          }
      
          public static void main(String[] args){
              IMessage msg = Messages.GOOD_MSG.create();
              System.out.println(msg.getName());
      
              msg = Messages.BAD_MSG.create();
              System.out.println(msg.getName());
      
              msg = Messages.CUSTOM_MSG.create();
              System.out.println(msg.getName());
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-11-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-11
        • 2018-07-27
        • 1970-01-01
        相关资源
        最近更新 更多