Reputation: 853
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;
}
Upvotes: 2
Views: 9246
Reputation: 29436
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());
}
}
Upvotes: 0
Reputation: 1854
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;
}
Upvotes: 2
Reputation: 7267
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
Upvotes: 2