该系列文章为博主学习笔记,原文请参考参考链接
本文禁止转载,但是欢迎大家留言区留言交流[微笑]
命令模式特(面)点(试):我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁。该模式将请求的发送者和接收者解耦,发送者与接收者之间引入了新的命令对象,将发送者的请求封装在命令对象中,再通过命令对象来调用接收者的方法。
从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