美文网首页
(十五)命令模式

(十五)命令模式

作者: guideEmotion | 来源:发表于2019-09-25 21:02 被阅读0次

一 基本介绍

  1. 命令模式(Command Pattern):在软件设计中,我们经常需要向某些对象发送请求,但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个, 我们只需在程序运行时指定具体的请求接收者即可,此时,可以使用命令模式来进行设计
  2. 命令模式使得请求发送者与请求接收者消除彼此之间的耦合,让对象之间的调用关系更加灵活,实现解耦
  3. 在命令模式中,会将一个请求封装为一个对象,以便使用不同参数来表示不同的请求(即命名),同时命令模式 也支持可撤销的操作
  4. 通俗易懂的理解:将军发布命令,士兵去执行。其中有几个角色:将军(命令发布者)、士兵(命令的具体执 行者)、命令(连接将军和士兵)。 Invoker 是调用者(将军),Receiver 是被调用者(士兵),MyCommand 是命令,实现了 Command 接口,持 有接收对象

1.1 举例

命令也可以是复杂的,就像脚本。命令就是这个写好的脚本。我们只需要调用这个脚本就可以完成复杂/可重复的操作

二 uml类图

image.png

对原理类图的说明-即(命名模式的角色及职责)

  1. Invoker 是调用者角色
  2. Command: 是命令角色,需要执行的所有命令都在这里,可以是接口或抽象类
  3. Receiver: 接受者角色,知道如何实施和执行一个请求相关的操作
  4. ConcreteCommand: 将一个接受者对象与一个动作绑定(关联了Receiver对象),调用接受者相应的操作,实现 execute

三 代码实现

3.1 示例说明

image.png

3.2 Command接口

1 package zyr.dp.command;
2 
3 public interface Command {
4     public abstract void execute();
5 }

3.3 DrawCommand类

需要聚合接收者(Drawable)

package zyr.dp.command;

import java.awt.Point;


public class DrawCommand implements Command {

    private Drawable drawable;
    private Point position;
    public  DrawCommand(Drawable drawable,Point position){
        this.drawable=drawable;
        this.position=position;
    }

    public void execute() {
        drawable.draw(position.x, position.y);
    }

}

3.4 MacroCommand 类

命令的集合,包含了撤销

package zyr.dp.command;

import java.util.Iterator;
import java.util.Stack;

public class MacroCommand implements Command {

    Stack commands=new Stack();
    
    public void execute() {
        Iterator it = commands.iterator();
        while(it.hasNext()){
            Command command=(Command)it.next();
            command.execute();
        }
    }
    
    public void append(Command command){
        if(command!=this){
            commands.add(command);
        }
    }
    
    public void clear(){
        commands.clear();
    }
    
    public void undo(){
        if(!commands.isEmpty()){
            commands.pop();    
        }
    }

}

3.5 Drawable接口

接收者的抽象

package zyr.dp.command;

public interface Drawable {

    public abstract void draw(int x,int y);
    
}

3.6 DrawCanvas 实现类

命令接收者

package zyr.dp.command;

import java.awt.*;
import java.util.Random;


public class DrawCanvas extends Canvas implements Drawable {

    private static final long serialVersionUID = 1972130370393242746L;
    
    private MacroCommand history;
    private int radius=8;

    public DrawCanvas(int width,int hieght, MacroCommand history){
        setSize(width,hieght);
        setBackground(Color.white);
        this.history=history;
    }
    
    public void draw(int x, int y) {
        Random random = new Random();
        
        Graphics g = getGraphics();
        g.setColor((random.nextBoolean())? Color.yellow : Color.MAGENTA);
        g.fillOval(x-radius, y-radius, radius*2, radius*2);
    }
    
    @Override
    public void paint(Graphics g) {
        System.out.println("执行一次刷新!"+System.currentTimeMillis());
        history.execute();
    }

}

3.7 测试类

package zyr.dp.command;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;

import javax.swing.*;


public class Main extends JFrame implements ActionListener,MouseMotionListener,WindowListener{

    private MacroCommand history=new MacroCommand() ;
    
    private JButton btnClear=new JButton("清除");
    private JButton btnRePaint=new JButton("重现");
    
    private DrawCanvas canvas=new DrawCanvas(400,400,history);
    
    public Main(String title){
        super(title);
        
        this.addWindowListener(this);
        canvas.addMouseMotionListener(this);
        btnClear.addActionListener(this);
        btnRePaint.addActionListener(this);
        
        Box btnBox=new Box(BoxLayout.X_AXIS);
        btnBox.add(btnClear);
        btnBox.add(btnRePaint);
        
        Box mainBox=new Box(BoxLayout.Y_AXIS);
        mainBox.add(btnBox);
        mainBox.add(canvas);
        
        getContentPane().add(mainBox);
        
        pack();
        show();
    }
    
    public static void main(String[] args) {

        new Main("命令模式");
        
    }

    
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource()==btnClear){
            history.clear();
            canvas.repaint();
        }else if(e.getSource()==btnRePaint){
            canvas.repaint();
        }
    }


    @Override
    public void mouseDragged(MouseEvent e) {
        Command cmd=new DrawCommand(canvas,e.getPoint());
        history.append(cmd);
        cmd.execute();
    }

    @Override
    public void windowClosing(WindowEvent e) {
        System.exit(0);
    }

    
    

    @Override
    public void windowOpened(WindowEvent e) {
    }
    
    @Override
    public void windowClosed(WindowEvent e) {
    }
    
    @Override
    public void windowIconified(WindowEvent e) {
    }

    @Override
    public void windowDeiconified(WindowEvent e) {
    }

    @Override
    public void windowActivated(WindowEvent e) {
    }

    @Override
    public void windowDeactivated(WindowEvent e) {
    }

    @Override
    public void mouseMoved(MouseEvent e) {
    }
}

四 注意事项和细节

  1. 目的是解耦,不需要将命令发布者和命令执行者关联到一起
  2. 容易设计一个命令队列。只要把命令对象放到列队,就可以多线程的执行命令
  3. 容易实现对请求的撤销和重做
  4. 命令模式不足:可能导致某些系统有过多的具体命令类,增加了系统的复杂度,这点在在使用的时候要注意
  5. 空命令也是一种设计模式,它为我们省去了判空的操作。在上面的实例中,如果没有用空命令,我们每按下一 个按键都要判空,这给我们编码带来一定的麻烦。
  6. 命令模式经典的应用场景:界面的一个按钮都是一条命令、模拟 CMD(DOS 命令)订单的撤销/恢复、触发- 反馈机制

参考

  1. https://www.cnblogs.com/zyrblog/p/9252664.html

相关文章

  • (十五)命令模式

    一 基本介绍 命令模式(Command Pattern):在软件设计中,我们经常需要向某些对象发送请求,但是并不知...

  • 设计模式-命令模式(十五)

    命令模式又称:行动模式 或 交易模式使用了命令模式,客户端就不在直接与Receiver打交道,而把执行的细节交于I...

  • 设计模式(十五)命令模式

    1、概述 命令模式是一种行为设计模式, 它可将请求转换为一个包含与请求相关的所有信息的独立对象。 该转换让你能根据...

  • iOS 设计模式之十五(命令模式)

    一、概念 1、命令模式的动机 ​ 夏天撸串加冰啤酒简直爽翻天,我们可以通过向服务员点菜烤羊肉、烤鱼、冰啤酒等,然...

  • 12.vim的使用技巧

    命令模式 、命令行模式、编辑模式: INSERT 首次进入文件: 命令模式输入: 表示 命令行模式出现...

  • 五、Linux vim编辑器

    vim编辑器三种模式:命令模式、编辑模式、末行模式 1.命令模式: vim进入文件后就是命令模式 1.1 命令模式...

  • 终端操作文件

    VIM 模式切换从命令模式->编辑模式:i,a,o,I,A,O从编辑模式->命令模式:ESC从命令模式->末行模式...

  • vim 操作 && Mac 配置本地Apache

    一、vim 的基本命令操作 vim 的模式: 编辑模式 ,命令模式 编辑模式: 命令模式:可以通过命令 最重要的命...

  • Vim高效编辑器

    Vim程序员高效编辑器 命令模式,输入模式,底线命令模式 默认进入vim就是命令模式,输入i变为输入模式 命令模式...

  • Command模式

    命令模式(Command) 命令模式属于对象的行为模式。命令模式又称为行动(Action)模式或交易(Tran...

网友评论

      本文标题:(十五)命令模式

      本文链接:https://www.haomeiwen.com/subject/vomwuctx.html