Шаблон Chain of Responsibility
Создан абстрактный класс AbstractHandler с абстрактным методом process, который должен быть переопределен в классах наследниках, а также два метода: setNextHandler для задания следующего Handler в цепочке Handler и метод handle, который обрабатывает контекст переданный в параметре этого метода. Созданы три класса-потомка AbstractHandler: InitiatorHandler, PriorityHandler и ToHandler, в которых переопределен метод process. В InitiatorHandler метод process возвращает true, если инициатор, определенный в контексте задан, как boss. В PriorityHandler метод process возвращает true, если приоритет заданный в контексте задан менее 10 (т.е. 0 – самый большой, а 10 – самый маленький для которых возвращается true). В ToHandler метод process возвращает true, если в контексте поля to имеет значение support. Также создан класс SampleContext с четырьмя полями from, to, priority и msg. В классе ChainPatternDemo рассмотрено использование шаблона Chain of Responsibility на примере следующей задачи: отфильтровать все сообщения и показать только те, которые пришли в службу поддержки (support) от начальника (boss) с приоритетом от 0 до 10.
AbstractHandler.java
package by.bsac.patterns.chainofresponsibility;
public abstract class AbstractHandler {
// next element in chain or responsibility
protected AbstractHandler nextHandler;
public void setNextHandler(AbstractHandler nextHandler) {
this.nextHandler = nextHandler;
}
public boolean handle(SampleContext context) {
boolean processedChain = process(context);
if (processedChain && nextHandler != null) {
processedChain = nextHandler.handle(context);
}
return processedChain;
}
abstract protected boolean process(SampleContext context);
}
InitiatorHandler.java
package by.bsac.patterns.chainofresponsibility;
public class InitiatorHandler extends AbstractHandler {
private String initiator = "boss";
@Override
protected boolean process(SampleContext context) {
boolean result = context.getFrom().equalsIgnoreCase(initiator);
System.out.println(this.getClass() + ": result = " + result);
return result;
}
}
PriorityHandler.java
package by.bsac.patterns.chainofresponsibility;
public class PriorityHandler extends AbstractHandler {
//process only if context.priority < priorityLevel
private int priorityLevel = 10;
@Override
protected boolean process(SampleContext context) {
boolean result = context.getPriority() < priorityLevel;
System.out.println(this.getClass() + ": result = " + result);
return result;
}
}
ToHandler.java
package by.bsac.patterns.chainofresponsibility;
public class ToHandler extends AbstractHandler {
private String validTo = "support";
@Override
protected boolean process(SampleContext context) {
boolean result = validTo.equalsIgnoreCase(context.getTo());
System.out.println(this.getClass() + ": result = " + result);
return result;
}
}
SampleContext.java
package by.bsac.patterns.chainofresponsibility;
public class SampleContext {
public String from;
public String to;
public int priority;
public String msg;
public SampleContext(String from, String to, int priority, String msg) {
this.from = from;
this.to = to;
this.priority = priority;
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getFrom() {
return from;
}
public void setFrom(String from) {
this.from = from;
}
public String getTo() {
return to;
}
public void setTo(String to) {
this.to = to;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
}
ChainPatternDemo.java
package by.bsac.patterns.chainofresponsibility;
public class ChainPatternDemo {
private static AbstractHandler getChainOfLoggers() {
AbstractHandler initiatorHandler = new InitiatorHandler();
AbstractHandler toHandler = new ToHandler();
AbstractHandler priorityHandler = new PriorityHandler();
priorityHandler.setNextHandler(initiatorHandler);
initiatorHandler.setNextHandler(toHandler);
return priorityHandler;
}
public static void main(String[] args) {
SampleContext context = new SampleContext("boss", "support", 1, "Fix security system!");
AbstractHandler handlerChain = getChainOfLoggers();
boolean validContext = handlerChain.handle(context);
if (validContext) {
System.out.println(context.msg);
}
}
}
4. Структура проекта:
Индивидуальные задания:
1. В реализации шаблона Factory добавить текущую дату сообщения (в консоль и в файл), а также создать буфер сообщений для FileLogger (если накапливается более 5 сообщений, которые были еще не записаны в файл, то записать их).
2. В реализации шаблона Chain of Responsibility необходимо создать контексты, которые должны быть отфильтрованы и обработаны.