[译文]3 分钟学习 Swift 命令设计模式

46 阅读2分钟

原文链接

什么是命令设计模式(Command Design Pattern)

命令设计模式是将命令或动作封装为对象的行为模式。命令设计模式通常由Invoker(调用者),Comand(命令),Receiver(接收者)三部分组成。

Invoker 是一个负责存储和执行命令的组件

Command 包装动作并将其封装为对象的组件

Receiver 接收器是一个基于命令执行操作的组件

实战

我们将用命令设计模式解决臃肿的 AppDelegate 和 SceneDelegate现实问题。在一个大的应用中,我们通常使用了大量的第三方库,在一些情况下,我们需要在 AppDelegate 中进行一些初始化或设置第三方库,如果处理不当,就会造成大量代码集中在AppDelegate,并且违反了单一职责原则。理解了这个需求,那么我们如何才能通过漂亮而优雅的解决方案来实现它呢?请看下面这个简单的架构图

image-20220331100140004

在AppDelegate类里,我们需要一个对象来存储并且执行所有命令,在这里为AppInvoker类。然后我们需要抽象类型来定义命令,创建具有一个方法的AppCommand接口。定义命令接口后,就可以创建具体命令如FirebaseCommand和OneSignalCommand.

public protocol AppCommand {
  func execute()
}

import Firebase
public class FirebaseCommand: AppCommand {
  public func execute() {
    FirebaseApp.configure()
  }
}

import OneSignal
public class OneSignalCommand: AppCommand {
  private let launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  
  public init(launchOptions: [UIApplicaiton.LaunchOptionsKey: Any]?) {
    self.launchOptions = launchOptions
  }
 	public func execute() {
    OneSignal.initWithLaunchOptions(launchOptions)
    OneSignal.setAppId("App_Id")
  }
}

所以命令已经定义好后,接下来创建 Invoker 对象

public class AppInvoker {
  private let commands: [AppCommand]
  
  public init(commands: [AppCommand]) {
    self.commands = commands
  }
  
  public func execute() {
    commands.forEach {
      $0.execute()
    }
  }
}

很简单吧,最终在AppDelegate实现如下:

public class AppDelegate: UIResponder, UIApplicaitonDelegate {
  public var window: UIWindow?
  
  public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicaiton.LaunchOptionsKey: Any]? = nil) -> Bool {
    let appInvoker = AppInvoker(commands:
                                [
                                  FirebaseCommand(),
                                  OneSignalCommand(launchOptions: launchOptions)
                                ])
    appInvoker.execute()
    return true
  }
}

现在AppDelegate的实现就看起来很简洁优雅了,这是您可以在 Swift 和 iOS 中使用命令设计模式的众多示例之一。