Шаблон 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 необходимо создать контексты, которые должны быть отфильтрованы и обработаны.