Вот мой взгляд на это:
Вместо расширения MessageHandler у меня есть один класс MessageHandler, который представляет собой композицию IMessageProcessor и IMessageValidator:
Надеюсь, я правильно понял UML-диаграмму, это было давно ...
В любом случае, давайте посмотрим на MessageHandler:
class MessageHandler
{
private IMessageProcessor processor;
private IMessageValidator validator;
public MessageHandler(IMessageProcessor processor)
{
this.processor = processor;
//Use the given processor as validator, if it implements the IMessageValidator-interface
if(IMessageValidator.class.isAssignableFrom(processor.getClass()))
{
this.validator = (IMessageValidator)processor;
}
}
public void setMessageValidator(IMessageValidator validator)
{
this.validator = validator;
}
public void handleMessage(Message message)
{
validateMessage(message);
processor.processMessage(message);
System.out.println("Message " + message + " handled by MessageHandler");
}
protected void validateMessage(Message message)
{
if(validator != null)
{
validator.validateMessage(message);
}
else
{
System.out.println("No IMessageValidator-implementation set, using default validation for message " + message);
}
}
}
MessageHandler имеет два закрытых члена, IMessageProcessor и IMessageValidator (это состав из процессора и валидатора). Валидатор можно оставить неустановленным, в этом случае при обработке сообщения будет задействована логика проверки по умолчанию.
В этом примере, если переданный процессор также реализует интерфейс IMessageValidator, он будет использоваться в качестве валидатора. Это, вероятно, то, что вы хотели, потому что вы можете использовать один и тот же конструктор для построения MessageHandlers, используя логику валидации или пользовательской валидации по умолчанию, в зависимости от того, реализует ли переданный объект только IMessageProcessor или IMessageProcessor и IMessageValidator (для удобства я расширил третий интерфейс, IValidatingMessageProcessor из этих интерфейсов). Если логика валидатора реализована отдельно (реализует только IMessageValidator), ее можно установить с помощью метода setValidator.
Нет необходимости расширять MessageHandler, поскольку вы можете реализовать логику обработки и проверки вне обработчика, либо отдельно, либо в одном классе, который реализует как обработку, так и проверку.
Вот классы, которые я использовал, надеюсь, это поможет:
Zip-пакет в MediaFire
Text-форма:
Message.java:
public class Message
{
private int number;
public Message(int number)
{
this.number = number;
}
public String toString()
{
return "Msg " + number;
}
}
IMessageProcessor.java:
interface IMessageProcessor
{
public void processMessage(Message m);
}
IMessageValidator.java:
public interface IMessageValidator
{
public void validateMessage(Message m);
}
IValidatingMessageProcessor.java:
public interface IValidatingMessageProcessor extends IMessageProcessor, IMessageValidator
{
}
FakeMessageProcessor.java:
public class FakeMessageProcessor implements IMessageProcessor
{
public void processMessage(Message m)
{
System.out.println("Using FakeMessageProcessor to process message " + m);
}
}
FakeMessageValidator.java:
public class FakeMessageValidator implements IMessageValidator
{
public void validateMessage(Message m)
{
System.out.println("Using FakeMessageValidator to validate message " + m);
}
}
FakeMessageProcessorAndValidator.java:
public class FakeMessageProcessorAndValidator implements IValidatingMessageProcessor
{
public void validateMessage(Message m)
{
System.out.println("Using FakeMessageProcessorAndValidator for validating message " + m);
}
public void processMessage(Message m)
{
System.out.println("Using FakeMessageProcessorAndValidator for processing message " + m);
}
}
Простое тестирование main для вышеперечисленных классов (только вывод данных):
public class MessageTest
{
public static void main(String[] args)
{
//Using processor implementing only IMessageProcessor, MessageHandler will use default validation
IMessageProcessor processor = new FakeMessageProcessor();
MessageHandler handler = new MessageHandler(processor);
handler.handleMessage(new Message(1));
//Setting separate validator to existing MessageHandler-instance
handler.setMessageValidator(new FakeMessageValidator());
handler.handleMessage(new Message(2));
//Using processor implementing both IMessageProcessor and IMessageValidator
processor = new FakeMessageProcessorAndValidator();
handler = new MessageHandler(processor);
handler.handleMessage(new Message(3));
}
}
выход:
No IMessageValidator-implementation set, using default validation for message Msg 1
Using FakeMessageProcessor to process message Msg 1
Message Msg 1 handled by MessageHandler
Using FakeMessageValidator to validate message Msg 2
Using FakeMessageProcessor to process message Msg 2
Message Msg 2 handled by MessageHandler
Using FakeMessageProcessorAndValidator for validating message Msg 3
Using FakeMessageProcessorAndValidator for processing message Msg 3
Message Msg 3 handled by MessageHandler