耦合:
簡單地說,軟件工程中對象之間的耦合度就是對象之間的依賴性。指導使用和維護對象的主要問題是對象之間的多重依賴性。對象之間的耦合越高,維護成本越高。因此對象的設計應使類和構件之間的耦合最小。
設計模式作用:
解決特定場合的耦合問題
命令模式作用:
解決命令的請求者與命令的實現者之間的耦合關係,大概可以看成一個抽象協議 + 一個具體協議。然後請求者讓執行者去執行具體協議的一個過程。
好處:
把請求封裝成對象,將使用不同的請求、日誌、隊列等來參數化其他對象。命令模式支持撤銷操作。
- 更方便對命令進行拓展
- 對多個命令的統一控制(如隊列、撤銷/恢復、記錄日誌等)
模式解析:
Command:(協議)定義命令的統一接口
ConreteCommand:Command接口的實現者,用來執行具體命令
Receiver:命令的實際執行者
Invoker:命令的請求者
適用場景:
- 命令的發送者和命令執行者有不同的生命週期,命令發送了並不是立即執行
- 命令需要各種管理邏輯
- 需要支持撤銷/重做操作
結論:
- 命令模式是通過命令發送者和命令執行者的解耦來完成對命令的具體控制
- 命令模式是對功能方法的抽象,並不是對對象的抽象
- 命令模式是將功能提升到對象來操作,以便對多個功能進行一些列的處理以及封裝
關於委託代理模式和命令模式的比較:
一開始在對比委託和代理模式的時候,感覺還是比較相似的。它們不同於一個只有三個角色,一個有四個角色。對於命令模式,可以大概將其看成 command+concretecommand =protocol,然後執行者和請求者看成委託和代理,委託代理模式,就是一個抽象協議,然後代理裏面實現了具體方法。 委託通過代理去執行實際的方法。命令模式就是把委託代理模式的代理方法再抽成具體的協議方法。MVVM實現的設計模式就是這麼實現的命令模式
至於將委託代理模式解耦成命令模式的原理,就是面向協議編程,目標就是降低邏輯耦合,增加數據內聚。
其他實踐:
網絡請求就是命令模式,反轉控制也可以用到命令模式。
例子 - Swift
Command
//
// Command.swift
// 命令模式SwiftDemo
//
// Created by hhg on 2019/2/21.
// Copyright © 2019年 hhg. All rights reserved.
//
import Foundation
protocol Command {
func execute()
}
ConcreteCommand
//
// ConcreteCommand.swift
// 命令模式SwiftDemo
//
// Created by hhg on 2019/2/21.
// Copyright © 2019年 hhg. All rights reserved.
//
import UIKit
class ConcreteCommand: NSObject,Command {
var _receiver : Receiver!
func execute() {
_receiver.action();
}
init(_ receiver:Receiver) {
_receiver = receiver
}
}
Receiver
//
// Receiver.swift
// 命令模式SwiftDemo
//
// Created by hhg on 2019/2/21.
// Copyright © 2019年 hhg. All rights reserved.
//
import UIKit
class Receiver: NSObject {
func action() {
print("to do something")
}
}
Invoker
//
// Invoker.swift
// 命令模式SwiftDemo
//
// Created by hhg on 2019/2/21.
// Copyright © 2019年 hhg. All rights reserved.
//
import UIKit
class Invoker: NSObject {
var command : Command!
func executeCommand() {
command.execute()
}
}
ViewController
//
// ViewController.swift
// 命令模式SwiftDemo
//
// Created by hhg on 2019/2/21.
// Copyright © 2019年 hhg. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
/// 執行實際操作的對象
let receiver = Receiver();
/// 具體的命令對象
let conrete = ConcreteCommand.init(receiver)
/// 命令調用者
let invoker = Invoker()
invoker.command = conrete
invoker.executeCommand()
}
}
本文部分內容根據技術羣員談論出來,以下爲人員名單:
- 成都_默默
- ♂廣州_般若
有興趣的人也可以進羣討論技術,技術討論問題請加 羣Q號:201708926
引用借鑑來源:
百度百科–耦合
理解設計模式之----命令模式
iOS設計模式 - 命令模式
設計模式分類
個人理解–代理模式和命令模式區別
代理模式和命令模式的區別