• 命令模式


    一 : 应用场景

    当需要将方法调用包装成一个对象,以延时方法调用,或者让其他组件在对其内部实现细节不了解的情况下进行调用的时候可以使用命令模式

      场景一:应用程序支持撤销和恢复

      场景二:记录请求日志,当系统故障这些命令可以重新被执行

      场景三:想用对象参数化一个动作以执行操作,并且用不同命令对象来替换回调函数

    二: 角色划分  

    命令模式规范

    1、角色一:接收者->Reciever

    2、角色二:命令接口->CommandProtocol(协议)

    3、角色三:具体命令->ConcrateCommand

    4、角色四:请求者->Invoker

    三: 具体命令分类

          1:动态命令:

          如果存在较多命令对象,会造成代码冗余,因此可以创建动态命令解决;

       2: 泛型命令:

          将接收者的类型设置为泛型,根据具体的接收者类型,动态的创建详情的接收者对象;

          3: 复合命令:

          同时执行多个命令;

        4: 并发处理: 

         多线程情况下,会导致多个命令并发,报异常; 队列,同步代码块

      5: 闭包命令:

         block代码块代替协议

     四: 具体代码

    import Foundation
    
    /**********************************  协议  *********************************/
    protocol CommandProtocol {
        func execute()
    }
    
    /**********************************  接收者  *********************************/
    import Foundation
    
    class Receiver {
        
        init() {}
        
        func debugFunc() {
            print("debug方法执行...")
        }
        
        func releaseFunc() {
            print("release方法执行...")
        }
        
    }
    
    /**********************************  动态命令  *********************************/
    
    import Foundation
    
    class DynamicCommand: CommandProtocol {
        
        private var receiver: Receiver
        private var commandBlock: (Receiver) -> ()
        
        init(paramReceiver: Receiver, paramBlock: @escaping (Receiver) -> ()) {
            
            self.commandBlock = paramBlock
            self.receiver = paramReceiver
        }
        
        func execute() {
            
            self.commandBlock(self.receiver)
        }
        
        class func sharedCommand(paramReciever: Receiver, paramBlock: @escaping (Receiver) -> ()) -> CommandProtocol {
            
            return DynamicCommand(paramReceiver: paramReciever, paramBlock: paramBlock)
        }
    }
    
    
    
    /**********************************  请求者  *********************************/
    
    
    import Foundation
    
    class InvokeManager {
        
        private var receiver: Receiver
        private var commands = [CommandProtocol]()
        
        
        init(paramReceiver: Receiver) {
            self.receiver = paramReceiver
        }
        
        
        func debugPrint() {
            /** 方法是一种特殊的闭包, 将方法作为闭包传递,不是类方法调用*/
            addMethodCommands(method: Receiver.debugFunc)
            self.receiver.debugFunc()
        }
        
        
        func releasePrint() {
            addMethodCommands(method: Receiver.releaseFunc)
            self.receiver.releaseFunc()
        }
        
        func addMethodCommands(method: @escaping (Receiver) -> ()->() ) {
            
            self.commands.append(DynamicCommand(paramReceiver: self.receiver, paramBlock: { (returnReceiver) in
                method(returnReceiver)()
            }))
            
        }
        
        
        //撤销上一步
        func undo() {
            print("撤销一步")
            
            if self.commands.count > 0 {
                self.commands.removeLast().execute()
            }
        }
        
        //撤销所有
        func undoAll() {
            print("撤销所有")
            
            for item in self.commands {
                item.execute()
            }
            
            self.commands.removeAll()
        }
        
    }
    View Code

      复合命令

    import Foundation
    
    /**********************************  复合命令  *********************************/
    
    class WrapperCommands: CommandProtocol {
        private var commands: [CommandProtocol]
        init(commands: [CommandProtocol]) {
            
            self.commands = commands
        }
        
        func execute() {
            
            for commands in self.commands {
                commands.execute()
            }
        }
    }
    
    /**********************************  复合命令请求者  *********************************/
    
    import Foundation
    
    class WrapperInvokeManager {
        
        private var receiver: Receiver
        private var commands = [CommandProtocol]()
        init(paramReceiver: Receiver) {
            self.receiver = paramReceiver
        }
        
        func debugPrint() {
            addMethodCommands(method: Receiver.debugFunc)
            self.receiver.debugFunc()
        }
        
        func releasePrint() {
            addMethodCommands(method: Receiver.releaseFunc)
            self.receiver.releaseFunc()
        }
        
        func addMethodCommands(method: @escaping (Receiver) -> ()->() ){
            
            self.commands.append(DynamicCommand(paramReceiver: self.receiver, paramBlock: { (returnReceiver) in
                
                method(returnReceiver)()
            }))
        }
        
        func undo() {
            print("撤销一步")
            
            if self.commands.count > 0 {
                self.commands.removeLast().execute()
            }
        }
        
        
        func undoAll() {
            print("撤销所有")
            let wrapCommands = WrapperCommands(commands: self.commands)
            wrapCommands.execute()
            self.commands.removeAll()
        }
        
    }
    View Code

      泛型命令

    /**********************************  泛型命令  *********************************/
    
    import Foundation
    
    class GenericsCommands<T>: CommandProtocol {
        
        private var receiver: T
        private var commandsBlock: (T) -> ()
        
        init(paramReceiver: T, paramBlock: @escaping (T) -> ()) {
            self.receiver = paramReceiver
            self.commandsBlock = paramBlock
        }
        
        func execute() {
            self.commandsBlock(self.receiver)
        }
        
    }
    
    /**********************************  泛型命令请求者  *********************************/
    
    import Foundation
    
    class GenericsInvokeManager {
        
        private var receiver: Receiver
        private var commands = [CommandProtocol]()
        
        init(paramReceiver: Receiver) {
            self.receiver = paramReceiver
        }
        
        
        func debugPrint() {
            addMethodCommands(method: Receiver.debugFunc)
            self.receiver.debugFunc()
        }
        
        func releasePrint() {
            addMethodCommands(method: Receiver.releaseFunc)
            self.receiver.releaseFunc()
        }
        
        func addMethodCommands(method: @escaping (Receiver) -> ()->()) {
            
            self.commands.append(GenericsCommands<Receiver>(paramReceiver: self.receiver, paramBlock: { (returnReceiver) in
                method(returnReceiver)()
            }))
            
        }
        
        
        func undo() {
            print("撤销一步")
            if self.commands.count > 0 {
                self.commands.removeLast().execute()
            }
        }
        
        
        func undoAll() {
            
            print("撤销所有")
            let wrapCommands = WrapperCommands(commands: self.commands)
            wrapCommands.execute()
            self.commands.removeAll()
            
        }
        
    }
    View Code

    闭包命令  

    import Foundation
    
    class BlockInvokeManager {
        typealias CommandBlock = (Receiver) -> ()
        private var receiver: Receiver
        private var commands = [CommandBlock]()
        
        init(paramReceiver: Receiver) {
            self.receiver = paramReceiver
        }
        
        func debugPrint() {
            addMethodCommands(method: Receiver.debugFunc)
            self.receiver.debugFunc()
        }
        
        func releasePrint() {
            addMethodCommands(method: Receiver.releaseFunc)
            self.receiver.releaseFunc()
        }
        
        func addMethodCommands(method: @escaping (Receiver) -> ()->()) {
    
            self.commands.append { (returnReceiver) in
                method(returnReceiver)()
            }
            
            
        }
        
        
        func undo() {
            print("撤销一步")
            if self.commands.count > 0 {
    //            self.commands.removeLast().execute()
                
                let command = self.commands.removeLast()
                command(self.receiver)
            }
        }
        
        
        func undoAll() {
            print("撤销所有")
    
            for command in self.commands {
                command(self.receiver)
            }
            
            self.commands.removeAll()
            
        }
    
    }
    View Code

    demo地址(包含OC和swift版本): https://github.com/hongsejuxiong/designMode

     

          

     

  • 相关阅读:
    angular-ui-bootstrap的弹出框定义成一个服务的实践(二)
    分享百度文件上传组件webUploader的使用demo
    display的flex属性使用详解
    数组去重(初识ES6)
    在ng中的select的使用方法的讲解
    安装xamp之后,appach、mysql等问题的总结
    python中string.casefold和string.lower区别
    python3数据类型
    MySQL bin-log 日志清理方式
    python终端颜色设置
  • 原文地址:https://www.cnblogs.com/jiefangzhe/p/9550760.html
Copyright © 2020-2023  润新知