研磨设计模式day12命令模式

目录

定义

几个参数

场景描述

代码示例

参数化设置

命令模式的优点

本质 

何时选用


定义

几个参数

Command:定义命令的接口。

ConcreteCommand:命令接口的实现对象。但不是真正实现,是通过接收者的功能来完成命令要执行的操作

Receiver:接收者。真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能

Invoker:要求命令对象执行请求,通常持有命令对象。

Client:创建具体的命令对象,并且设置命令对象的接收者。

场景描述

电脑开机:

机箱上的按钮就相当于是命令对象

机箱相当于是Invoker:要求机箱上的按钮执行哪些动作

主板相当于接收者对象:真正执行命令的对象

命令对象持有接收者对象就相当于按钮有一条线连接着主板,当按钮被按下就通过连接线把命令发出去。

代码示例

定义主板

package day12命令模式;

/**
 * 主板的接口
 */
public interface ZhuBanApi {
    /**
     * 定义一个功能:开机
     */
    public void open();
}

定义实现,定义两个一个是技嘉主板,一个是微星主板,现在将实现写为一样

不同的主板对同一个命令的操作可以是不同的

技嘉主板

package day12命令模式.Impl;

import day12命令模式.ZhuBanApi;

public class JiJiaZhuBanImpl implements ZhuBanApi {
    @Override
    public void open() {
        System.out.println("技嘉主板正在开机,请等候");
        System.out.println("接通电源......");
        System.out.println("设备检查......");
        System.out.println("装载系统......");
        System.out.println("机器正常运转......");
        System.out.println("机器已经正常打开,请操作");
    }
}

微星主板

package day12命令模式.Impl;

import day12命令模式.ZhuBanApi;

public class WeiXingZhuBanImpl implements ZhuBanApi {
    @Override
    public void open() {
        System.out.println("微星主板正在开机,请等候");
        System.out.println("接通电源......");
        System.out.println("设备检查......");
        System.out.println("装载系统......");
        System.out.println("机器正常运转......");
        System.out.println("机器已经正常打开,请操作");
    }
}

定义命令接口:里面只有一个方法就是执行

package day12命令模式;

/**
 * 命令接口,声明执行的操作
 */
public interface Command {
    /**
     * 执行命令对应的操作
     */
    public void execute();
}

命令实现:我们按下的是按钮,但是按钮本身不知道怎么去启动电脑,只有主板知道,所以我们要持有真正实现命令的接收者--主板对象

package day12命令模式.Impl;

import day12命令模式.Command;
import day12命令模式.ZhuBanApi;

/**
 * 开机命令接口的实现
 */
public class CommandImpl implements Command {
    /**
     * 持有真正实现命令的接收者--主板对象
     */
    private ZhuBanApi zhuBanApi = null;

    /**
     * 构造方法,传入主板对象
     * @param zhuBanApi
     */
    public CommandImpl(ZhuBanApi zhuBanApi){
        this.zhuBanApi = zhuBanApi;
    }

    /**
     * 实现开机
     */
    @Override
    public void execute() {
        this.zhuBanApi.open();
    }
}

提供机箱,按钮是放置在机箱上的。机箱对象,本身有按钮,持有按钮对应的命令对象也就是Command

package day12命令模式;

/**
 * 机箱对象,本身有按钮,持有按钮对应的命令对象
 */
public class Box {
    /**
     * 开机命令对象
     */
    private Command openCommand;

    /**
     * 设置开机命令对象
     * @param openCommand 开机命令对象
     */
    public void setOpenCommand(Command openCommand) {
        this.openCommand = openCommand;
    }
    /**
     * 提供给客户使用,接收并相应用户请求,相当于那妞被按下触发的方法
     */
    public void openButton(){
        openCommand.execute();
    }
}

客户使用按钮,把与主板连接好的按钮对象放置在机箱上。

package day12命令模式;

import day12命令模式.Impl.CommandImpl;
import day12命令模式.Impl.WeiXingZhuBanImpl;

public class Client {
    public static void main(String[] args) {
        // 1.创建接收者
        WeiXingZhuBanImpl zhuban = new WeiXingZhuBanImpl();

        // 2.设置接收者与命令对象的关系  (按钮要进行开机,使用哪个主板)
        CommandImpl command = new CommandImpl(zhuban);

        // 3.创建Invoker,用Invoker来执行命令
        Box box = new Box();
        // 4.将2中绑定好关系的命令对象设置到Invoker中,让Invoker持有
        box.setOpenCommand(command);

        // 5.调用Invoker中的方法,触发要求执行命令
        // Box定义了方法,,用持有命令对象接口里面的方法,接口的实现中持有真正实现命令的接收者ZhuBanApi,
        // ZhuBanApi他去调用真正的开机方法,而这个接口有多个实现类,到底调用哪一个呢?
        // 因为在创建接收者时已经把微星这个接收者与命令对象绑定起来了,所以用的就是微星的实现类
        box.openButton();
    }
}

研磨设计模式day12命令模式_第1张图片

解析:先new一个主板,主板要跟按钮连接成为一个具体的开机命令,我又new一个机箱,把这个升级过的按钮(带有功能)装到这个机箱上,机箱最后调用这个按钮。

1.会发现命令模式的关键之处就是把请求封装成了对象,也就是命令对象,并定义了统一的执行操作的接口。

2.在命令模式中会有一个组装者,他来维护虚实现与真实实现之间的关系

参数化设置

可以用不同的命令对象,去参数化配置客户的请求

研磨设计模式day12命令模式_第2张图片

定义主板接口,现在增加一个重启的按钮,因此主板加一个方法来实现重启功能

package day12命令模式;

/**
 * 主板的接口
 */
public interface ZhuBanApi {
    /**
     * 定义一个功能:开机
     */
    public void open();
    /**
     * 定义重启功能
     */
    public void reset();
}

 实现类也要改一下

技嘉的

package day12命令模式.Impl;

import day12命令模式.ZhuBanApi;

/**
 * 主板的实现
 */
public class JiJiaZhuBanImpl implements ZhuBanApi {
    @Override
    public void open() {
        System.out.println("技嘉主板正在开机,请等候");
        System.out.println("接通电源......");
        System.out.println("设备检查......");
        System.out.println("装载系统......");
        System.out.println("机器正常运转......");
        System.out.println("机器已经正常打开,请操作");
    }

    @Override
    public void reset() {
        System.out.println("技嘉主板现在正在重新启动机器,请等候");
        System.out.println("机器已经正常打开,请操作");
    }
}

微星的

package day12命令模式.Impl;

import day12命令模式.ZhuBanApi;

/**
 * 主板的实现
 */
public class WeiXingZhuBanImpl implements ZhuBanApi {
    @Override
    public void open() {
        System.out.println("微星主板正在开机,请等候");
        System.out.println("接通电源......");
        System.out.println("设备检查......");
        System.out.println("装载系统......");
        System.out.println("机器正常运转......");
        System.out.println("机器已经正常打开,请操作");
    }

    @Override
    public void reset() {
        System.out.println("微星主板现在正在重新启动机器,请等候");
        System.out.println("机器已经正常打开,请操作");
    }
}

接下来定义命令和按钮,接口不变,添加一个重启命令的实现resetCommandImpl

package day12命令模式.Impl;

import day12命令模式.Command;
import day12命令模式.ZhuBanApi;

public class ResetCommandImpl implements Command {
    /**
     * 持有主板,也就是接收者对象
     */
    private ZhuBanApi zhuBanApi;

    /**
     * 构造函数传入
     * @param zhuBanApi
     */
    public ResetCommandImpl(ZhuBanApi zhuBanApi){
        this.zhuBanApi = zhuBanApi;
    }
    @Override
    public void execute() {
        this.zhuBanApi.reset();
    }
}

Box改造一下,这里增加一个重启命令对象

package day12命令模式;

/**
 * 机箱对象,本身有按钮,持有按钮对应的命令对象
 */
public class Box {
    /**
     * 开机命令对象
     */
    private Command openCommand;

    /**
     * 重启命令对象
     */
    private Command resetCommand;

    public void setResetCommand(Command resetCommand) {
        this.resetCommand = resetCommand;
    }

    /**
     * 设置开机命令对象
     * @param openCommand 开机命令对象
     */
    public void setOpenCommand(Command openCommand) {
        this.openCommand = openCommand;
    }

    /**
     * 提供给客户使用,接收并相应用户请求,相当于按钮被按下触发的方法
     */
    public void openButton(){
        openCommand.execute();
    }

    /**
     * 重启按钮
     */
    public void resetButton(){
        resetCommand.execute();
    }
}

Client

package day12命令模式;

import day12命令模式.Impl.OpenCommandImpl;
import day12命令模式.Impl.ResetCommandImpl;
import day12命令模式.Impl.WeiXingZhuBanImpl;

public class Client {
    public static void main(String[] args) {

        WeiXingZhuBanImpl zhuban = new WeiXingZhuBanImpl();


        OpenCommandImpl openCommand = new OpenCommandImpl(zhuban);
        ResetCommandImpl resetCommand = new ResetCommandImpl(zhuban);


        Box box = new Box();
        box.setOpenCommand(openCommand);
        box.setResetCommand(resetCommand);

        System.out.println("正确配置");
        System.out.println(">>>按下开机按钮:>>>");
        box.openButton();
        System.out.println(">>>按下重启按钮:>>>");
        box.resetButton();
    }
}

研磨设计模式day12命令模式_第3张图片

命令模式的优点

研磨设计模式day12命令模式_第4张图片

本质 

命令模式的本质:封装请求

何时选用

研磨设计模式day12命令模式_第5张图片

 

 

你可能感兴趣的:(设计模式,命令模式)