耦合:
简单地说,软件工程中对象之间的耦合度就是对象之间的依赖性。指导使用和维护对象的主要问题是对象之间的多重依赖性。对象之间的耦合越高,维护成本越高。因此对象的设计应使类和构件之间的耦合最小。
设计模式作用:
解决特定场合的耦合问题
命令模式作用:
解决命令的请求者与命令的实现者之间的耦合关系,大概可以看成一个抽象协议 + 一个具体协议。然后请求者让执行者去执行具体协议的一个过程。
好处:
把请求封装成对象,将使用不同的请求、日志、队列等来参数化其他对象。命令模式支持撤销操作。
- 更方便对命令进行拓展
- 对多个命令的统一控制(如队列、撤销/恢复、记录日志等)
模式解析:
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设计模式 - 命令模式
设计模式分类
个人理解–代理模式和命令模式区别
代理模式和命令模式的区别