2

I have the following class structure: a base class 'Message' which contains some common members (/fields), 'Imessage' interface that has some methods that all messages should implement, a lot of different message classes that extends (inherits) the base 'Message' class and have a lot of fields, an enum for each message type and a factory class which given an enum creates an instance of the proper message class.

The issue is that I'm not sure where/how to implement the setting of values for each of the message classes. It can't be in it's constructor because in the factory method i need to build generic instances. Should i implement a 'Create' method for each of the messages that will set all of it's members?

    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;
        }
1
  • Can you explain the generic problem from the constructor a little bit more. With an example or something else? Commented May 18, 2014 at 8:54

3 Answers 3

2

The factory pattern should return a valid, fully populated object so adding a Create method for each type of Message object would not be ideal (unless it is called from within buildMessage).

I don't know what you mean when you say:

It can't be in it's constructor because in the factory method i need to build generic instances.

It's completely valid to initialise an objects like this:

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

In which case your buildMessage method can take in all objects required to build all the sub types of your message.

If this becomes too complex because there are too many variations of required fields then it might be worth upgrading to the Builder Pattern:

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

Sign up to request clarification or add additional context in comments.

Comments

2

This is one possible solution. You can write a constructor in Message and override it in the subclasess.

public class Message {
    private final String commonField;

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

And in the subclassess

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

And in the factory do

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

Comments

0

If message definitions are rigid and you are not creating combinations of messages or configuring their properties, then why have a factory class ?

On another note, The enum alone is capable of much:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.