[Swift设计模式] 命令

848 阅读2分钟
更多内容,欢迎关注公众号:Swift花园
喜欢文章?不如来点赞关注吧

当你需要为支持即时调用的不同的动作提供一个通用接口时,命令模式可以派上用场。通常来说,命令是一个封装了执行动作需要用到的所有数据和方法的单一对象。

命令常被用来处理人机接口的动作,实现撤销管理器,或者管理事务。让我们来看一下 Swift 中如何实现一个命令模式。 💾

#!/usr/bin/env swift

import Foundation

protocol Command {
    func execute()
}

class HelpCommand: Command {

    func execute() {
        Help().info()
    }
}

class Help {

    func info() {
        print("""

             🤖 Commander 🤖
                  v1.0

        Available commands:

            👉 help      This command
            👉 ls        List documents

        Bye! 👋

        """)
    }
}

class ListCommand: Command {

    func execute() {
        List().homeDirectoryContents()
    }
}

class List {

    func homeDirectoryContents() {
        let fileManager = FileManager.default
        guard let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first else {
            print("Could not open documents directory")
            exit(-1)
        }
        do {
            let fileURLs = try fileManager.contentsOfDirectory(at: documentsURL, includingPropertiesForKeys: nil)
            print("\n\t📁 Listing documents directory:\n")
            print(fileURLs.map { "\t\t💾 " + $0.lastPathComponent }.joined(separator: "\n\n") + "\n" )
        }
        catch {
            print(error.localizedDescription)
            exit(-1)
        }

    }
}

class App {

    var commands: [String:Command] = [:]

    init() {
        self.commands["help"] = HelpCommand()
        self.commands["ls"] = ListCommand()
    }

    func run() {
        let arguments = CommandLine.arguments[1...]

        guard let key = arguments.first, self.commands[key] != nil else {
            print("Usage: ./command.swift [\(self.commands.keys.joined(separator: "|"))]")
            exit(-1)
        }

        self.commands[key]!.execute()
    }
}

App().run()

保存下这个文件,然后在终端中输入./file-name.swift运行它。Swift 编译器会替你完成剩下的工作。⚒

现实世界中命令模式的用例

  • 各种按钮的动作
  • 集合 / 表 视图的选择动作
  • 在控制器间导航
  • 历史管理 / 撤销管理器
  • 事务行为
  • 进度管理

如你所见,这个模式可以应用于很多范围。Apple 甚至还为它实现了一个专门的类叫 NSInvocation,不过由于这个类的动作行为,在 Swift 中并不可用。不过没关系,你可以自行实现自己的协议和实现,多数情况下,你只需要额外实现一个封装底层逻辑的类。😛

 

我的公众号
这里有Swift及计算机编程的相关文章,以及优秀国外文章翻译,欢迎关注~