在 OC 中, 一个比较好的组件化方案是使用 Target-Action + Mediator + runtime 实现的, 参考链接: iOS 组件化方案. 由于借助 OC 中的 runtime, 各业务模块之间不必相互持有, 只要通过 Mediator 即可实现业务调用. 简单理解为:
在 Swift 中因为没有 runtime 的加持, 能做到的是:
mediatorwithoutruntime.png
下面用一个实际例子来实现 Swift 中的 Mediator 模式.
例: 在一个团队里,有产品经理,开发工程师,质量工程师。当开发完成了某些功能,将代码提交到仓库。相关环节人员,像质量工程师和产品经理需要被通知。
protocol Collogue {
var id: String { get }
func send(message: String)
func receive(message: String)
}
class Developer: Collogue {
var id: String
var qe: QE
var pm: PM
init(qe: QE, pm: PM) {
self.id = "Developer"
self.qe = qe
self.pm = pm
}
func send(message: String) {
qe.receive(message: message)
pm.receive(message: message)
}
func receive(message: String) {
print(message)
}
}
class QE: Collogue {
var id: String
var developer: Developer
var pm: PM
init(developer: Developer, pm: PM) {
self.id = "QE"
self.developer = developer
self.pm = pm
}
func send(message: String) {
developer.receive(message: message)
pm.receive(message: message)
}
func receive(message: String) {
print(message)
}
}
class PM: Collogue {
var id: String
var developer: Developer
var qe: QE
init(developer: Developer, qe: QE) {
self.id = "PM"
self.developer = developer
self.qe = qe
}
func send(message: String) {
developer.receive(message: message)
qe.receive(message: message)
}
func receive(message: String) {
print(message)
}
}
改造方法:
1 找到一个中间人取名: TeamMediator. 他能感知各位同事, 因此需要持有一个 collogues 数组, 他的主要功能是在同事间能执行发送消息的操作;
2 各同事需要持有一个中间人, 要发送消息, 就通过这个中间人去做.
protocol Mediator {
func send(message: String, sender: Colleague)
}
class TeamMediator: Mediator {
var colleagues: [Colleague] = []
func register(colleague: Colleague) {
colleagues.append(colleague)
}
func send(message: String, sender: Colleague) {
for colleague in colleagues {
if colleague.id != sender.id {
colleague.receive(message: message)
}
}
}
}
protocol Colleague {
var id: String { get }
var mediator: Mediator { get }
func send(message: String)
func receive(message: String)
}
class Developer: Colleague {
var id: String
var mediator: Mediator
init(mediator: Mediator) {
self.id = "Developer"
self.mediator = mediator
}
func send(message: String) {
mediator.send(message: message, sender: self)
}
func receive(message: String) {
print("Developer received: " + message)
}
}
class QE: Colleague {
var id: String
var mediator: Mediator
init(mediator: Mediator) {
self.id = "QE"
self.mediator = mediator
}
func send(message: String) {
mediator.send(message: message, sender: self)
}
func receive(message: String) {
print("QE received: " + message)
}
}
class PM: Colleague {
var id: String
var mediator: Mediator
init(mediator: Mediator) {
self.id = "PM"
self.mediator = mediator
}
func send(message: String) {
mediator.send(message: message, sender: self)
}
func receive(message: String) {
print("PM received: " + message)
}
}
问题: 这里的引用耦合并没有得到实际解决, 以前是 A 引用 B, B 引用 A, 现在换成了 A 引用 Mediator, Mediator 引用 B. 这是语言特性造成的差异. 在开发中需要有一定的取舍.
这里还有一种做法: 使用 Notification 来实现, 但是需要注意 1 Notification 在哪个线程中 post, 就会在哪个线程 handle; 2 需要规范好 Notification 的命名和生命周期管理.
网友评论