• 设计模式第17篇:命令模式


    一.命令模式介绍

      命令模式是一种对象行为型模式,其别名为动作(Action)模式或事务(Transaction)模式。命令模式的本质是对请求进行封装,一个请求对应于一个命令,每一个命令都是一个操作:请求的一方发出请求要求执行一个操作;接收的一方收到请求,并执行相应的操作。命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求如何被接收、操作是否被执行、何时被执行,以及是怎么被执行的。

           命令模式的关键在于引入了抽象命令类,请求发送者针对抽象命令类编程,只有实现了抽象命令类的具体命令才与请求接收者相关联。在最简单的抽象命令类中只包含了一个抽象的execute()方法,每个具体命令类将一个Receiver类型的对象作为一个实例变量进行存储,从而具体指定一个请求的接收者,不同的具体命令类提供了execute()方法的不同实现,并调用不同接收者的请求处理方法。

    二.命令模式代码用例

      现在开发一个文件系统工具,该系统可以对一个文件进行打开、关闭、写入操作,此外该文件系统还有支持Windows和Linux操作系统。

      1.文件系统接收者接口(Receiver)

    interface FileSystemReceiver {
    
        void openFile();
        void writeFile();
        void closeFile();
    }

      2.具体的文件系统接受者

    class WindowsFileSystemReceiver implements FileSystemReceiver {
    
        @Override
        public void openFile() {
            System.out.println("Opening file in Windows OS");
            
        }
    
        @Override
        public void writeFile() {
            System.out.println("Writing file in Windows OS");
        }
    
        @Override
        public void closeFile() {
            System.out.println("Closing file in Windows OS");
        }
    
    }
    
    class LinuxFileSystemReceiver implements FileSystemReceiver {
    
        @Override
        public void openFile() {
            System.out.println("Opening file in unix OS");
        }
    
        @Override
        public void writeFile() {
            System.out.println("Writing file in unix OS");
        }
    
        @Override
        public void closeFile() {
            System.out.println("Closing file in unix OS");
        }
    
    }

      3.命令接口及其实现类(Command)

    interface Command {
    
        void execute();
    }
    
    class OpenFileCommand implements Command {
    
        private FileSystemReceiver fileSystem;
        
        public OpenFileCommand(FileSystemReceiver fs){
            this.fileSystem=fs;
        }
        @Override
        public void execute() {
            //open command is forwarding request to openFile method
            this.fileSystem.openFile();
        }
    
    }
    
    class CloseFileCommand implements Command {
    
        private FileSystemReceiver fileSystem;
        
        public CloseFileCommand(FileSystemReceiver fs){
            this.fileSystem=fs;
        }
        @Override
        public void execute() {
            this.fileSystem.closeFile();
        }
    
    }
    
    class WriteFileCommand implements Command {
    
        private FileSystemReceiver fileSystem;
        
        public WriteFileCommand(FileSystemReceiver fs){
            this.fileSystem=fs;
        }
        @Override
        public void execute() {
            this.fileSystem.writeFile();
        }
    
    }

      4.调用者(Invoker)

    class FileInvoker {
    
        public Command command;
        
        public FileInvoker(Command c){
            this.command=c;
        }
        
        public void execute(){
            this.command.execute();
        }
    }

      5.文件系统工具类(此处用到工厂模式)

    class FileSystemReceiverUtil {
        
        public static FileSystemReceiver getUnderlyingFileSystem(){
             String osName = System.getProperty("os.name");
             System.out.println("Underlying OS is:"+osName);
             if(osName.contains("Windows")){
                 return new WindowsFileSystemReceiver();
             }else{
                 return new LinuxFileSystemReceiver();
             }
        }
        
    }

      6.测试

    public class FileSystemClient {
    
        public static void main(String[] args) {
            //Creating the receiver object
            FileSystemReceiver fs = FileSystemReceiverUtil.getUnderlyingFileSystem();
            
            //creating command and associating with receiver
            OpenFileCommand openFileCommand = new OpenFileCommand(fs);
            
            //Creating invoker and associating with Command
            FileInvoker file = new FileInvoker(openFileCommand);
            
            //perform action on invoker object
            file.execute();
            
            WriteFileCommand writeFileCommand = new WriteFileCommand(fs);
            file = new FileInvoker(writeFileCommand);
            file.execute();
            
            CloseFileCommand closeFileCommand = new CloseFileCommand(fs);
            file = new FileInvoker(closeFileCommand);
            file.execute();
        }
    
    }

    三.命令模式中的一些要点

      1.命令对象时命令模式的核心

      2.接收者的实现与命令者实现相互独立

      3.接收者中的每一个方法都可以作为一个命令者的实现,比如上面的例子中,接收者中的open,close,write方法对应的三个命令类实现。

      4.当接收者中的方法非常多时,命令模式会非常复杂,要慎用。

  • 相关阅读:
    Maven学习笔记
    [学习笔记] 网络流
    [Contest on 2021.11.3] 女子口阿
    [杂题合集] 25 岁小伙突然没了心跳,他的习惯很多年轻人都有!
    CSP 2021 提高组游记
    [题目小结] 可持久化数据结构
    [学习笔记] 无向图和有向图的连通分量
    [Contest on 2021.10.17] HustOJ 就是个 **
    [Contest on 2021.10.15] 细思极恐
    妖怪寺外,灯火通明
  • 原文地址:https://www.cnblogs.com/quxiangxiangtiange/p/10290234.html
Copyright © 2020-2023  润新知