You can use the Visitor pattern:
interface MessageVisitor {
void visitUserMessage(UserMessage message);
void visitBotMessage(BotMessage message);
}
Then add to your Message
interface:
...
void accept(MessageVisitor visitor);
...
Which is implemented as:
class UserMessage implements Message {
...
void accept(MessageVisitor visitor) {
visitor.visitUserMessage(this);
}
and
class BotMessage implements Message {
...
void accept(MessageVisitor visitor) {
visitor.visitBotMessage(this);
}
so loadMessage
looks like:
MessageVisitor visitor = new MessageVisitor() {
void visitUserMessage(UserMessage message) {
LOGGER.info("it's a user message");
}
void visitBotMessage(UserMessage message) {
LOGGER.info("it's a bot message");
}
}
message.accept(visitor);
The nice thing about this is that if you create a new class which implements Message
you are forced to implement accept
, which will prompt you to add a new method to MessageVisitor
, and so add its implementation to all MessageVisitor
implementations. Using instanceof
allows you to forget to add new cases to your code when new classes are introduced.
It also keeps your business logic separate from your Message classes -- they just implement the mechanism of the visitor pattern, not any actual functionality.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…