设计模式 - command

将请求封装为对象,从而可以使用不同的请求对客户进行参数化,该模式的关键在于对不同请求的封装。简单的说,也就是在请求发出者和客户间通过command对象进行解耦,从而使得请求者可以通过实例化不同的command对象实现不同操作。

command模式类似于c++的回调,我们需要在command的实现类中注册回调函数,也就是将命令的具体执行者注册。

在GOF中,使用了Menu,MenuItem以及doucment的例子还阐述command模式。用户点击menu,将操作事件委托给MenuItem,不同的MenuItem拥有不同的concreteCommand,从而实现menuItem与操作执行者的解耦。

另外,command模式可以支持复合操作,也就是执行一批command(接口实现缘故),并且可以通过记录操作前状态实现撤销操作unexecute,从而为事务处理提供了基础。

command模式的效果:

1) command模式将调用操作的对象与知道如何实现该操作的对象解耦

2) command对象可以像其他对象一样被操纵和扩展

3) 多个command可以复合

4) 增加新command很容易,无需改变其他类

给个例子:

还是公司的事情,公司里有一位大boss;他不喜欢见人,可能是长得丑,也可能是其他原因。他的任何命令都是通过写在小纸条上的command来执行的。纸条上会写上需要执行的任务。如boss想要开房,他就下发一道开房command。

另外一个部门负责编写不同的小纸条,并决定由谁去给boss开房,有可能是大泽玛利亚,也有可能是uncle wang,当然这就跟boss没有关系了,反正房开好了就可以。

这样,就实现了boss和秘书之间的解耦。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.inspur.jiyq.designpattern.command;
 
import com.inspur.jiyq.designpattern.command.impl.ReserveCommand;
import com.inspur.jiyq.designpattern.command.impl.SendMessageCommand;
 
public class BossMain {
    public static void main(String[] args)
    {
        //通过使用command模式,实现了boss和秘书的解耦
         
        //boss想发邮件
        Command mailCommand = new SendMessageCommand(new MailMan());
        mailCommand.execute();
         
        //boss想开房
        Command reserveCommand = new ReserveCommand(new Secretary());
        reserveCommand.execute();
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.inspur.jiyq.designpattern.command;
 
public interface Command {
    /**
     * 执行命令
     */
    public void execute();
     
    /**
     * 取消已经执行的命令
     */
    public void unexecute();
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.inspur.jiyq.designpattern.command;
 
public class MailMan {
    /**
     * 发邮件
     */
    public void sendMail()
    {
        System.out.println("MailMan sending mails.");
    }
     
    /**
     * 回收邮件,前提是得保存前一次送件地址
     */
    public void retrieve()
    {
        System.out.println("MailMan retrieve mails");
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
package com.inspur.jiyq.designpattern.command;
 
public class Secretary {
    /**
     * 秘书需要做各种预定
     */
    public void reserve()
    {
        System.out.println("Secretary book a room.");
    }
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.inspur.jiyq.designpattern.command.impl;
 
import com.inspur.jiyq.designpattern.command.Command;
import com.inspur.jiyq.designpattern.command.Secretary;
 
public class ReserveCommand implements Command{
    private Secretary secretary;
     
    public ReserveCommand(Secretary secretary)
    {
        this.secretary = secretary;
    }
 
    @Override
    public void execute() {
        secretary.reserve();
    }
 
    @Override
    public void unexecute() {
        // TODO Auto-generated method stub
    }
 
}

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.inspur.jiyq.designpattern.command.impl;
 
import com.inspur.jiyq.designpattern.command.Command;
import com.inspur.jiyq.designpattern.command.MailMan;
 
public class SendMessageCommand implements Command {
    /**
     * 快递哥
     */
    private MailMan mailMan;
     
    public SendMessageCommand(MailMan mailMan)
    {
        this.mailMan = mailMan;
    }
 
    @Override
    public void execute() {
        mailMan.sendMail();
 
    }
 
    @Override
    public void unexecute() {
        //如果送出去的信写错了,可以要求信差收回来,前提是信差可以这么做
         
    }
 
}

  

 

posted @   纪玉奇  阅读(1485)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示