在Java中使用带有多个参数的Factory模式

时间:2014-05-18 08:47:59

标签: java design-patterns constructor factory

我有以下类结构: 一个基类'Message',它包含一些公共成员(/ fields), “Imessage”界面,其中包含所有消息应实现的一些方法, 许多不同的消息类扩展(继承)基础'Message'类并且有很多字段,每个消息类型的枚举和给定枚举的工厂类创建正确消息类的实例。

问题在于我不确定在何处/如何为每个消息类实现值的设置。 它不能在它的构造函数中,因为在工厂方法中我需要构建泛型实例。 我应该为每个将设置其所有成员的消息实现“创建”方法吗?

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

3 个答案:

答案 0 :(得分:2)

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

当你说:

时,我不知道你的意思
  

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

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

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

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

如果由于所需字段的变化太多而变得太复杂,那么可能值得升级到Builder模式:

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

答案 1 :(得分:1)

这是一种可能的解决方案。您可以在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;
        }

答案 2 :(得分:0)

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

另一方面,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());
    }
}