美文网首页
使用协议实现 Swift 中间人模式

使用协议实现 Swift 中间人模式

作者: csqingyang | 来源:发表于2020-07-06 00:12 被阅读0次

    在 OC 中, 一个比较好的组件化方案是使用 Target-Action + Mediator + runtime 实现的, 参考链接: iOS 组件化方案. 由于借助 OC 中的 runtime, 各业务模块之间不必相互持有, 只要通过 Mediator 即可实现业务调用. 简单理解为:

    mediatorwithruntime.png
    在 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 的命名和生命周期管理.

    相关文章

      网友评论

          本文标题:使用协议实现 Swift 中间人模式

          本文链接:https://www.haomeiwen.com/subject/zjciqktx.html