设计模式之命令模式学习理解

命令模式

命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

介绍

意图:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化。

主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录、撤销或重做、事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适。

何时使用:在某些场合,比如要对行为进行"记录、撤销/重做、事务"等处理,这种无法抵御变化的紧耦合是不合适的。在这种情况下,如何将"行为请求者"与"行为实现者"解耦?将一组行为抽象为对象,可以实现二者之间的松耦合。

如何解决:通过调用者调用接受者执行命令,顺序:调用者→接受者→命令。

关键代码:定义三个角色:1、received 真正的命令执行对象 2、Command 3、invoker 使用命令对象的入口

应用实例:struts 1 中的 action 核心控制器 ActionServlet 只有一个,相当于 Invoker,而模型层的类会随着不同的应用有不同的模型类,相当于具体的 Command。

优点: 1、降低了系统耦合度。 2、新的命令可以很容易添加到系统中去。

缺点:使用命令模式可能会导致某些系统有过多的具体命令类。

使用场景:认为是命令的地方都可以使用命令模式,比如: 1、GUI 中每一个按钮都是一条命令。 2、模拟 CMD。

注意事项:系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作,也可以考虑使用命令模式,见命令模式的扩展。

假设现在有个创建工单的类,还有个安装工的类负责接收和安装工单。

简单的紧耦合实现

 1 /**
 2  * 新建工单类
 3  * @author ko
 4  *
 5  */
 6 public class NewlyBuildOrder {
 7
 8     public void buildTypeAOrder(){
 9         System.out.println("build type a order...");
10     }
11
12     public void buildTypeBOrder(){
13         System.out.println("build type b order...");
14     }
15
16 }
 1 /**
 2  * 安装工
 3  * 接单并安装
 4  * @author ko
 5  *
 6  */
 7 public class Installer {
 8
 9     public void receiveInstall(NewlyBuildOrder newlyBuildOrder){
10
11         newlyBuildOrder.buildTypeAOrder();
12         newlyBuildOrder.buildTypeBOrder();
13         newlyBuildOrder.buildTypeAOrder();
14         newlyBuildOrder.buildTypeAOrder();
15
16     }
17
18 }
 1 /**
 2  * 测试类
 3  * 新建工单
 4  * 安装工领取并安装工单
 5  * @author ko
 6  *
 7  */
 8 public class Test {
 9
10     public static void main(String[] args) {
11         NewlyBuildOrder newlyBuildOrder = new NewlyBuildOrder();
12         Installer installer = new Installer();
13         installer.receiveInstall(newlyBuildOrder);
14     }
15 }
build type a order...
build type b order...
build type a order...
build type a order...

这其实是行为请求者和行为实现者的紧耦合,这样写有很多弊端,如果安装工多了,那就会很混乱,没有日志记录,另外需要撤销领取的工单重新领取也不行。

松耦合命令模式实现

 1 // 把行为请求者对行为实现者的命令抽象成类
 2 public abstract class Command {
 3
 4     protected NewlyBuildOrder newlyBuildOrder;
 5
 6     public Command(NewlyBuildOrder newlyBuildOrder){
 7         this.newlyBuildOrder = newlyBuildOrder;
 8     }
 9
10     // 执行命令
11     public abstract void excuteCommand();
12
13 }
 1 // A类工单命令
 2 public class TypeAOrderCommand extends Command {
 3
 4     public TypeAOrderCommand(NewlyBuildOrder newlyBuildOrder) {
 5         super(newlyBuildOrder);
 6         // TODO Auto-generated constructor stub
 7     }
 8
 9     @Override
10     public void excuteCommand() {
11         newlyBuildOrder.buildTypeAOrder();
12     }
13
14     @Override
15     public String toString() {
16         return "TypeAOrderCommand";
17     }
18
19 }
 1 // B类工单命令
 2 public class TypeBOrderCommand extends Command {
 3
 4     public TypeBOrderCommand(NewlyBuildOrder newlyBuildOrder) {
 5         super(newlyBuildOrder);
 6         // TODO Auto-generated constructor stub
 7     }
 8
 9     @Override
10     public void excuteCommand() {
11         newlyBuildOrder.buildTypeBOrder();
12     }
13
14     @Override
15     public String toString() {
16         return "TypeBOrderCommand";
17     }
18
19 }
 1 /**
 2  * 工单管理
 3  * 介于行为请求者和行为实现者之间的类
 4  * @author ko
 5  *
 6  */
 7 public class OrderManage {
 8
 9     private List<Command> orders = new ArrayList<>();// 存放具体命令的容器
10
11     // 设置订单
12     // 对于工单管理类,不管安装工想要的是什么类型的工单,反正都是‘命令’,只管记录订单,
13     //
14     public void setOrder(Command command){
15         if (command.toString().equals("TypeAOrderCommand")) {
16             System.out.println("type a order is over, can‘t provide ...");
17         }else{
18             orders.add(command);
19             // 打印日志
20             System.out.println("LOG   add order:"+command.toString()+",time:"+System.currentTimeMillis());
21         }
22     }
23
24     // 撤销订单
25     public void revokeOrder(Command command){
26         orders.remove(command);
27         // 打印日志
28         System.out.println("LOG   revoke order:"+command.toString()+",time:"+System.currentTimeMillis());
29     }
30
31     public void notifyBuilder(){
32         for (Command command : orders) {
33             command.excuteCommand();
34         }
35     }
36
37 }
 1 /**
 2  * 新建工单类
 3  * @author ko
 4  *
 5  */
 6 public class NewlyBuildOrder {
 7
 8     public void buildTypeAOrder(){
 9         System.out.println("build type a order...");
10     }
11
12     public void buildTypeBOrder(){
13         System.out.println("build type b order...");
14     }
15
16 }
 1 /**
 2  * 测试类
 3  * @author ko
 4  *
 5  */
 6 public class Test {
 7
 8     public static void main(String[] args) {
 9         // 初始准备
10         NewlyBuildOrder newlyBuildOrder = new NewlyBuildOrder();
11         Command typeAOrderCommand = new TypeAOrderCommand(newlyBuildOrder);
12         Command typeBOrderCommand = new TypeBOrderCommand(newlyBuildOrder);
13         OrderManage orderManage = new OrderManage();
14
15         // 设置命令
16         orderManage.setOrder(typeAOrderCommand);
17         orderManage.setOrder(typeBOrderCommand);
18
19         // 通知order builder
20         orderManage.notifyBuilder();
21
22     }
23 }
type a order is over, can‘t provide ...
LOG   add order:TypeBOrderCommand,time:1500879972241
build type b order...

  

时间: 2024-08-09 06:34:00

设计模式之命令模式学习理解的相关文章

设计模式之状态模式学习理解

在状态模式(State Pattern)中,类的行为是基于它的状态改变的.这种类型的设计模式属于行为型模式. 在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象. 介绍 意图:允许对象在内部状态发生改变时改变它的行为,对象看起来好像修改了它的类. 主要解决:对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为. 何时使用:当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时. 如何解决:将各种具体的状态类

理解设计模式之----命令模式

零零碎碎的了解过部分设计模式,但没有系统的学习过,最近晚上有点时间,就买了本程杰的<大话设计模式>,最近想系统的学习下.当看到命令模式的时候,感觉并不是太好理解,于是上网搜索了些资料.发现对设计模式的看法多少很多文章都有些不一样,于是想写下自己对命令模式的一些看法,以加深理解.要是文章有不对的地方,希望大家能提出改进建议. 目的: 任何模式的出现,都是为了解决一些特定的场景的耦合问题,以达到对修改封闭,对扩展开放的效果.命令模式也不例外: 命令模式是为了解决命令的请求者和命令的实现者之间的耦合

设计模式——抽象工厂模式学习

要想正确的理解设计模式,首先必须明确它是为了解决什么问题而提出来的. 抽象工厂设计模式概念: 针对抽象工厂这个设计模式,我查找了不少资料,感觉只有涉及产品级别和产品族的才是理解了抽象工厂设计模式的精髓,工厂方法模式针对的是一个产品等级结构:而抽象工厂模式针对的是多个产品等级结构.有些观点认为抽象工厂模式是为了解决客户端代码与工厂类的耦合问题,我认为这种观点的解决方案只是简单工厂模式的一个应用,而这种观点认为的抽象工厂模式是: 工厂模式+简单工厂模式=抽象工厂模式,这是不正确. 针对的问题: 针对

C#设计模式(15)——命令模式(Command Pattern)

原文:C#设计模式(15)--命令模式(Command Pattern) 一.前言 之前一直在忙于工作上的事情,关于设计模式系列一直没更新,最近项目中发现,对于设计模式的了解是必不可少的,当然对于设计模式的应用那更是重要,可以说是否懂得应用设计模式在项目中是衡量一个程序员的技术水平,因为对于一个功能的实现,高级工程师和初级工程师一样都会实现,但是区别在于它们实现功能的可扩展和可维护性,也就是代码的是否“优美”.可读.但是,要更好地应用,首先就必须了解各种设计模式和其应用场景,所以我还是希望继续完

设计模式之命令模式

命令模式的核心是把方法调用封装起来,调用的对象不需要关心是如何执行的. 定义:命令模式将"请求"封装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也可以支持撤销操作. 先看一个例子,设计一个家电遥控器的API,可以通过遥控器发出命令来控制不同生产商生产的家电,比如关灯.开灯. 以下是一个简单的代码示例. 1 package cn.sp.test05; 2 /** 3 * 电灯类 4 * @author 2YSP 5 * 6 */ 7 public class Lig

设计模式之命令模式20170719

行为型设计模式之命令模式: 一.含义 将请求(命令)封装成一个对象(内部有接收者对象,以及按照具体命令执行接收者操作的方法),传递给调用者,由调用者执行具体命令. 也就是把一个动作的执行分为执行对象(接收者角色).执行行为(命令角色),让两者相互独立而不相互影响,实现对动作解耦 二.代码说明 1.主要有三个角色 1)接收者角色 该角色就是干活的角色,被命令角色调用,其操作按具体命令的要求执行 2)命令角色 需要执行的所有命令都在这里声明,同时接收者所有的对象都在这里(接收者封装在这里,防止高层模

跟我学设计模式视频教程——命令模式vs策略模式,唠嗑

课程视频 命令模式vs策略模式 唠嗑 课程笔记 课程笔记 课程代码 课程代码 新课程火热报名中 课程介绍 跟我学设计模式视频教程--命令模式vs策略模式,唠嗑,布布扣,bubuko.com

用Java 8 Lambda表达式实现设计模式:命令模式

链接:http://www.importnew.com/16789.html 在这篇博客里,我将说明如何在使用Java 8 Lambda表达式的函数式编程方式时实现命令设计模式.命令模式的目标是将请求封装成一个对象,从对客户端的不同类型请求,例如队列或日志请求参数化,并提供相应的操作.命令模式是一种通用编程方式,该方式基于运行时决策顺序来执行方法.模式的参与者如下: 命令 :声明用于执行操作的接口. 实体命令 :定义接收者对象和动作的绑定. 客户端 :创建实体命令实例并设置它的接收者. 调用者:

设计模式 ( 十三 ) 命令模式Command(对象行为型)

设计模式 ( 十三 ) 命令模式Command(对象行为型) 1.概述 在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计,使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活. 例子1:电视机遥控器 : 遥控器是请求的发送者,电视机是请求的接收者,遥控器上有一些按钮如开,关,换频道等按钮就是具体命令,不同的按钮对应电视机的不同操作. 2.问题