• 每日学一个设计模式22——命令模式


    命令模式(命令也是类)

    用处

    请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

    角色

    • Command(命令)
      该角色负责定义命令的接口(API)
    • ConcreteCommand(具体的命令)
      该角色负责实现Command角色中定义的接口(API)。
    • Recevier(接收者)
      该角色是Command角色执行命令时的对象,也可以称其为命令接收者。
    • Client(请求者)
      该角色负责生成ConcreteCommand并分配Receiver角色。
    • Invoker(发动者)
      该角色是开始执行命令的角色,它会调用在Command角色中定义的接口(API)。

    类图

    在这里插入图片描述
    由类图可知

    • Invoker通过Command接口聚合了ConcreteCommand,在ConcreteCommand中又聚合Receiver
    • Invoker调用ConcreteCommand中的execute方法发出命令,ConcreteCommand再调用Receiver的action方法接受命

    举例

    //Invoker和Client角色
    public class Main extends JFrame implements ActionListener, MouseMotionListener,WindowListener {
        private MacroCommand history = new MacroCommand();
        private DrawCanvas canvas = new DrawCanvas(400,400,history);
        private JButton clearButton = new JButton("clear");
        public Main(String title){
            super(title);
            this.addWindowListener(this);
            canvas.addMouseMotionListener(this);
            clearButton.addActionListener(this);
            Box buttonBox = new Box(BoxLayout.X_AXIS);
            buttonBox.add(clearButton);
            Box mainBox = new Box(BoxLayout.Y_AXIS);
            mainBox.add(buttonBox);
            mainBox.add(canvas);
            getContentPane().add(mainBox);
            pack();
            show();
        }
        public void actionPerformed(ActionEvent e){
            if(e.getSource() == clearButton){
                history.clear();
                canvas.repaint();
            }
        }
    
        public void mouseMoved(MouseEvent e){
        }
        public void mouseDragged(MouseEvent e){
            Command cmd = new DrawCommand(canvas,e.getPoint());
            history.append(cmd);
            cmd.execute();
        }
        public void windowClosing(WindowEvent e){
            System.exit(0);
        }
        public void windowActivated(WindowEvent e){}
        public void windowClosed(WindowEvent e){}
        public void windowDeactivated(WindowEvent e){}
        public void windowDeiconified(WindowEvent e){}
        public void windowIconified(WindowEvent e){}
        public void windowOpened(WindowEvent e){}
    
        public static void main(String[] args){
            new Main("Command Pattern Sample");
        }
    }
    //Command
    interface Command{
        void execute();
    };
    
    //ConcreteCommand
    class MacroCommand implements Command{
        //命令的集合
        private Stack commands = new Stack();
        public void execute(){
            Iterator it = commands.iterator();
            while(it.hasNext()){
                ((Command)it.next()).execute();
            }
        }
        //添加命令
        public void append(Command cmd){
            if(cmd != this){
                commands.push(cmd);
            }
        }
    
        //删除最后一条命令
        public void clear(){
            commands.clear();
        }
    }
    
    //ConcreteCommand角色
    class DrawCommand implements Command{
        //绘制对象
        protected Drawable drawable;
        //绘制位置
        protected Point position;
    
        public DrawCommand(Drawable drawable,Point position){
            this.drawable = drawable;
            this.position = position;
        }
    
        public void execute(){
            drawable.draw(position.x,position.y);
        }
    }
    
    interface Drawable{
        void draw(int x,int y);
    }
    
    //Receiver角色
    class DrawCanvas extends Canvas implements Drawable{
        private Color color = Color.red;
        private int radius = 6;
        private MacroCommand history;
        public DrawCanvas(int width,int height,MacroCommand history){
            setSize(width,height);
            setBackground(Color.white);
            this.history = history;
        }
        public void paint(Graphics g){
            history.execute();
        }
        public void draw(int x,int y){
            Graphics g = getGraphics();
            g.setColor(color);
            g.fillOval(x-radius,y-radius,radius*2,radius*2);
        }
    }
    

    在这里插入图片描述

    总结

    • 符合开闭原则
    • 实现行为请求者-行为实现者之间的解耦
  • 相关阅读:
    [Android]Logcat调试
    Rust(16):结构体方法
    Python-类
    Hadoop (十五) --------- Hadoop 数据压缩
    【图像分割】基于回溯搜索优化算法实现图像聚类分割附matlab代码
    bat脚本-不关闭窗口
    使用vSphere Update Manager 升级 ESXi 主机
    android的三种动画
    从目录文件inode角度,理解软连接的由来
    一文读懂身份证ocr识别
  • 原文地址:https://blog.csdn.net/qq_53008257/article/details/127031442