Java23种设计模式——命令模式

来源:互联网 发布:dota直播软件 编辑:程序博客网 时间:2024/05/27 19:27

该系列文章为博主学习笔记,原文请参考参考链接
本文禁止转载,但是欢迎大家留言区留言交流[微笑]

命令模式特(面)点(试):我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁。该模式将请求的发送者和接收者解耦,发送者与接收者之间引入了新的命令对象,将发送者的请求封装在命令对象中,再通过命令对象来调用接收者的方法。

这里写图片描述

从UML图中可以看到请求者为Invoker和接受者Receiver没有存在直接的引用,而是针对于抽象命令类Command通过注入的方式,在程序运行过程中确定具体命令类ConcreteCommand,然后调用execute方法。

具体例子:
这里写图片描述

代码:

public abstract class AbstractCommand {    public abstract void execute();}
//接收者类public class BoardScreen {    public  void open() {        System.out.println("打开");    }    public void create() {        System.out.println("创建");    }    public void edit() {        System.out.println("编辑");    }}
//具体命令类-新建命令//具体命令类中关联了接收者类public class CreateCommand extends AbstractCommand{    private BoardScreen boardScreen;    public CreateCommand() {        boardScreen=new BoardScreen();    }    @Override    public void execute() {        boardScreen.create();    }}
//具体命令类-打开命令public class OpenCommand extends AbstractCommand{    private BoardScreen boardScreen;    public OpenCommand() {        boardScreen=new BoardScreen();    }    @Override    public void execute() {        boardScreen.open();    }}
//具体命令类-编辑命令public class EditCommand extends AbstractCommand {    private BoardScreen boardScreen;    public EditCommand() {        boardScreen = new BoardScreen();    }    @Override    public void execute() {        boardScreen.edit();    }}
//主菜单类public class Menu {    //用于存储主菜单的Item    private List<MenuItem> list = new ArrayList<MenuItem>();    //设置主菜单的标题    private String title;    public Menu(String title) {        this.title = title;    }    public String getTitle() {        return title;    }    //添加子菜单    public void addMenuItem(MenuItem menuItem) {        list.add(menuItem);    }    //移除子菜单    public void removeMenuItem(MenuItem menuItem) {        list.remove(menuItem);    }    //显示主菜单中的所有子菜单    public void disp(){        System.out.println("主菜单名称为:" + this.title);        System.out.println("显示功能键:");        for (MenuItem menuItem : list){            System.out.println(menuItem.getName());        }        System.out.println("------------------------------");    }}
//菜单类里面的Item项//相当于UML流程图中的Invoker调用者类,请求发送者,在该类中关联了抽象//命令类,在程序运行中set一个具体的命令类,在调用具体命令类中的//execute()方法public class MenuItem {    private AbstractCommand abstractCommand;    public void setAbstractCommand(AbstractCommand abstractCommand) {        this.abstractCommand = abstractCommand;    }    private String name;    public MenuItem(String name) {        this.name=name;    }    public String getName() {        return name;    }    public void onClick() {        abstractCommand.execute();    }}
public class myClass {    public static void main(String[] args) {        Menu menu = new Menu("学生管理系统");        //创建功能键        MenuItem menuItem1 = new MenuItem("课程管理");        MenuItem menuItem2 = new MenuItem("成绩查询");        //添加功能键        menu.addMenuItem(menuItem1);        menu.addMenuItem(menuItem2);        //显示所有的功能键        menu.disp();        //设置发送者和所对应的接受者        menuItem1.setAbstractCommand(new CreateCommand());        menuItem2.setAbstractCommand(new OpenCommand());        //模拟用户点击Item事件        menuItem1.onClick();        menuItem2.onClick();    }}
主菜单名称为:学生管理系统显示功能键:课程管理成绩查询------------------------------创建打开

在这里如果需要对某一个Item进行更改,比如增加一个“查询教师”的Item,只需要创建一个具体的命令类(SearchCommand),在BoardScreen类中增加一个查询的方法search(),最后在客户端进行setAbstractCommand(new SearchCommand)注入即可,原有代码无须修改,符合“开闭原则”。

微信公众号:
这里写图片描述

QQ群:365473065

原创粉丝点击