设计模式-行为型模式(一)

一、责任链模式

用于避免请求发送者与多个请求处理者耦合在一起,让所有请求的处理者持有下一个对象的引用,从而将请求串联成一条链,在有请求发生时,可将请求沿着这条链传递,直到遇到该对象的处理器。

通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

以用户发送Web请求,经过用户鉴权、业务调用、结果反馈流程为例:

(1)定义Handler接口:

public interface Handler {
    void operator();
}

(2)定义AbstractHandler类:

public abstract class AbstractHandler {
    private Handler handler;

    public Handler getHandler() {
        return handler;
    }

    public void setHandler(Handler handler) {
        this.handler = handler;
    }
}

(3)定义用户授权类AuthHandler、业务处理类BusinessHandler、结果反馈类ResponseHandler

public class AuthHandler extends AbstractHandler implements Handler {
    private final static Log logger = LogFactory.getLog(AuthHandler.class);
    private String name;
    public AuthHandler(String name){
        this.name = name;
    }
    @Override
    public void operator() {
        logger.info("user auth");
        if(getHandler()!=null){
            //执行责任链下一流程
            getHandler().operator();
        }
    }
}

public class BusinessHandler extends AbstractHandler implements Handler {
    private final static Log logger = LogFactory.getLog(BusinessHandler.class);
    private String name;
    public BusinessHandler(String name){
        this.name = name;
    }
    @Override
    public void operator() {
        logger.info("Business info handler");
        if(getHandler()!=null){
            //执行责任链下一流程
            getHandler().operator();
        }
    }
}

public class ResponseHandler extends AbstractHandler implements Handler {
    private final static Log logger = LogFactory.getLog(ResponseHandler.class);
    private String name;
    public ResponseHandler(String name){
        this.name = name;
    }
    @Override
    public void operator() {
        logger.info("message response");
        if(getHandler()!=null){
            //执行责任链下一流程
            getHandler().operator();
        }
    }
}

(4)使用责任链模型:

public class Main {
    public static void main(String[] args) {
        AuthHandler authHandler = new AuthHandler("auth");
        BusinessHandler businessHandler = new BusinessHandler("business");
        ResponseHandler responseHandler = new ResponseHandler("response");
        authHandler.setHandler(businessHandler);
        businessHandler.setHandler(responseHandler);
        authHandler.operator();
    }
}

结果:

十二月 30, 2019 10:06:15 下午 com.jzq.sign.Responsibility.AuthHandler operator
信息: user auth
十二月 30, 2019 10:06:15 下午 com.jzq.sign.Responsibility.BusinessHandler operator
信息: Business info handler
十二月 30, 2019 10:06:15 下午 com.jzq.sign.Responsibility.ResponseHandler operator
信息: message response

二、命令模式

请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

 (1)创建一个Command接口:

public interface Command {
    void execute();
}

(2)创建请求类Stock:

public class Stock {

    private String name = "ABC";
    private int quantity = 10;

    public void buy(){
        System.out.println("Stock [ Name: "+name+",Quantity: " + quantity +" ] bought");
    }
    public void sell(){
        System.out.println("Stock [ Name: "+name+",Quantity: " + quantity +" ] sold");
    }
}

(3)创建实现了Command 接口的实体类BuyStock和SellStock

public class BuyStock implements Command {
    private Stock abcStock;

    public BuyStock(Stock abcStock){
        this.abcStock = abcStock;
    }
    @Override
    public void execute() {
        abcStock.buy();
    }
}

public class SellStock implements Command {
    private Stock abcStock;

    public SellStock(Stock abcStock){
        this.abcStock = abcStock;
    }
    @Override
    public void execute() {
        abcStock.sell();
    }
}

(4)定义命令调用类Broker

public class Broker {
    private List<Command> CommandList = new ArrayList<Command>();

    public void takeCommand(Command Command){
        CommandList.add(Command);
    }

    public void placeCommands(){
        for (Command Command : CommandList) {
            Command.execute();
        }
        CommandList.clear();
    }
}

(5)使用 Broker 类来接受并执行命令:

public class Main {
    public static void main(String[] args) {
        Stock abcStock = new Stock();

        BuyStock buyStockOrder = new BuyStock(abcStock);
        SellStock sellStockOrder = new SellStock(abcStock);

        Broker broker = new Broker();
        broker.takeCommand(buyStockOrder);
        broker.takeCommand(sellStockOrder);

        broker.placeCommands();
    }
}

结果:

Stock [ Name: ABC,Quantity: 10 ] bought
Stock [ Name: ABC,Quantity: 10 ] sold

三、访问者模式

访问者模式将数据结构和对数据的操作分离开,使其在不改变数据结构的前提下动态添加作用于这些元素上的操作。

访问者模式通过定义不同的访问者实现对数据的不同操作,因此在需要给数据添加新的操作时只需为其定义一个新的访问者即可。

访问者模式适用于数据结构稳定但数据操作方式多变的系统中。

比如,有一个项目计划需要上报,项目计划包括项目名称和项目内容,访问者有项目经理,CEO,CTO。

(1)定义接口VIsitor:

public interface Visitor {
    void visit(ProjectElement element);
}

(2)定义VIsitor的实现类CEOVIsitor、CTOVIsitor:

public class CEOVisitor implements Visitor {
    private final static Log logger = LogFactory.getLog(CEOVisitor.class);
    @Override
    public void visit(ProjectElement element) {
        logger.info("CEO Visitor Element");
        element.signature("CEO",new Date());
        logger.info(JSON.toJSON(element));
    }
}

public class CTOVisitor implements Visitor {
    private final static Log logger = LogFactory.getLog(CTOVisitor.class);
    @Override
    public void visit(ProjectElement element) {
        logger.info("CTO Visitor Element");
        element.signature("CTO",new Date());
        logger.info(JSON.toJSON(element));
    }
}

(3)定义抽象元素Element,并定义accept()用于接收访问者对象。

public interface Element {
    void accept(Visitor visitor);
}

(4)定义Element的实现类ProjectElement:

public class ProjectElement implements Element {
    private String projectName;
    private String projectContent;
    private String visitorName;
    private Date visitTime;

    public ProjectElement(String projectName, String projectContent) {
        this.projectName = projectName;
        this.projectContent = projectContent;
    }

    public void signature(String visitorName, Date visitTime) {
        this.visitorName = visitorName;
        this.visitTime = visitTime;
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
  //省略getter、setter  
}

(5)使用访问者模式:

public class Main {
    public static void main(String[] args) {
        Element element = new ProjectElement("ofo","清算计划");
        element.accept(new CEOVisitor());
        element.accept(new CTOVisitor());
    }
}

结果:

十二月 31, 2019 10:30:42 上午 com.jzq.sign.Visitor.CEOVisitor visit
信息: CEO Visitor Element
十二月 31, 2019 10:30:42 上午 com.jzq.sign.Visitor.CEOVisitor visit
信息: {"projectContent":"清算计划","visitTime":1577759442167,"visitorName":"CEO","projectName":"ofo"}
十二月 31, 2019 10:30:42 上午 com.jzq.sign.Visitor.CTOVisitor visit
信息: CTO Visitor Element
十二月 31, 2019 10:30:42 上午 com.jzq.sign.Visitor.CTOVisitor visit
信息: {"projectContent":"清算计划","visitTime":1577759442292,"visitorName":"CTO","projectName":"ofo"}

四、解释器模式

解释器模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。

注:可利用场景比较少,JAVA 中如果碰到可以用 expression4J 代替。

五、策略模式

 策略模式为同一个行为定义不同的策略,并为每种策略都实现了不同的方法。

策略模式的实现是在接口中定义不同的策略,在实现类中完成了对不同的策略下具体行为的实现。

以选择旅游交通工具为例:

(1)定义TravelStrategy:

public interface TravelStrategy {
    void travelMode();
}

(2)定义TravelStrategy接口的实现类TravelByAirStrategy、TravelByCarStrategy:

public class TravelByAirStrategy implements TravelStrategy {
    private final static Log logger = LogFactory.getLog(TravelByAirStrategy.class);
    @Override
    public void travelMode() {
        logger.info("travel by air");
    }
}

public class TravelByCarStrategy implements TravelStrategy {
    private final static Log logger = LogFactory.getLog(TravelByCarStrategy.class);
    @Override
    public void travelMode() {
        logger.info("travel by car");
    }
}

(3)定义Context实现策略模式:

public class Context {
    private TravelStrategy travelStrategy;
    public TravelStrategy getTravelStrategy() {
        return travelStrategy;
    }
    public void setTravelStrategy(TravelStrategy travelStrategy) {
        this.travelStrategy = travelStrategy;
    }
    public void travelMode(){
        this.travelStrategy.travelMode();
    }
}

(4)使用策略模式:

public class Main {
    public static void main(String[] args) {
        Context context = new Context();
        TravelStrategy travelByAirStrategy = new TravelByAirStrategy();
        context.setTravelStrategy(travelByAirStrategy);
        context.travelMode();
        System.out.println("=====出行方式飞机换为汽车=====");
        TravelStrategy travelByCarStrategy = new TravelByCarStrategy();
        context.setTravelStrategy(travelByCarStrategy);
        context.travelMode();
    }
}

结果:

十二月 31, 2019 11:23:13 上午 com.jzq.sign.Strategy.TravelByAirStrategy travelMode
信息: travel by air
十二月 31, 2019 11:23:13 上午 com.jzq.sign.Strategy.TravelByCarStrategy travelMode
信息: travel by car
=====出行方式飞机换为汽车=====

六、模板模式

 模板模式在抽象类中定义了算法的结构并实现了公共部分算法,在子类中实现可变的部分并根据不同的业务需求实现不同的扩展。

以银行办理业务为例:

 (1)定义AbstractTemplate模板类:

public abstract class AbstractTemplate {
    private final static Log logger = LogFactory.getLog(AbstractTemplate.class);
    public void templateMethod(){
        //模板方法,用于核心流程和算法的实现
        checkNumber();
        queueUp();
        handleBusiness();
        serviceEvaluation();
    }
    private void checkNumber() {
        //抽号
        logger.info("checkNumber...");
    }
    private void queueUp() {
        //排队
        logger.info("queue up");
    }
    protected abstract void handleBusiness();
    private void serviceEvaluation() {
        //服务评价
        logger.info("业务完成,请评价服务...");
    }
}

(2)定义SaveMoney、TakeMoney的业务实现:

public class SaveMoney extends AbstractTemplate {
    private final static Log logger = LogFactory.getLog(SaveMoney.class);
    @Override
    protected void handleBusiness() {
        logger.info("存钱");
    }
}

public class TakeMoney extends AbstractTemplate {
    private final static Log logger = LogFactory.getLog(TakeMoney.class);
    @Override
    protected void handleBusiness() {
        logger.info("取钱");
    }
}

(3)使用模板模式:

public class Main {
    public static void main(String[] args) {
        AbstractTemplate template1 = new TakeMoney();
        template1.templateMethod();

        AbstractTemplate template2 = new SaveMoney();
        template2.templateMethod();
    }
}

结果:

十二月 31, 2019 4:55:27 下午 com.jzq.sign.Template.AbstractTemplate checkNumber
信息: checkNumber...
十二月 31, 2019 4:55:27 下午 com.jzq.sign.Template.AbstractTemplate queueUp
信息: queue up
十二月 31, 2019 4:55:27 下午 com.jzq.sign.Template.TakeMoney handleBusiness
信息: 取钱
十二月 31, 2019 4:55:27 下午 com.jzq.sign.Template.AbstractTemplate serviceEvaluation
信息: 业务完成,请评价服务...
十二月
31, 2019 4:55:27 下午 com.jzq.sign.Template.AbstractTemplate checkNumber 信息: checkNumber... 十二月 31, 2019 4:55:27 下午 com.jzq.sign.Template.AbstractTemplate queueUp 信息: queue up 十二月 31, 2019 4:55:27 下午 com.jzq.sign.Template.SaveMoney handleBusiness 信息: 存钱 十二月 31, 2019 4:55:27 下午 com.jzq.sign.Template.AbstractTemplate serviceEvaluation 信息: 业务完成,请评价服务...
原文地址:https://www.cnblogs.com/strong-FE/p/12122060.html