中介者模式

作者: 架构师的一小步 | 来源:发表于2019-03-24 11:32 被阅读0次

中介者模式(Mediator)->牛逼->MVP架构思想

中介者模式定义
  • 别名:调节者模式、调停者模式
  • 包装了一系列对象相互作用的方式,使得这些对象不必相互明显作用。从而使它们可以降低耦合(松散耦合)。当某些对象之间的作用发生改变时,不会立即影响其他的一些对象之间的作用。保证这些作用可以彼此独立变化。中介者模式将多对多的相互作用转化为一对多的相互作用。中介者模式将对象的行为和协作抽象化,把对象在小尺度的行为上与其他对象的相互作用分开处理。
中介者模式-应用场景
  • 当对象之间的交互操作很多且每个对象的行为操作都依赖彼此时,为防止在修改一个对象的行为时,同时涉及修改很多其他对象的行为,可以采用中介者模式来解决耦合问题。
    \color{red}{核心:解决耦合问题}
中介者模式角色划分

角色一:Mediator(抽象中介者)
角色二:ConcreteMediator(具体中介者)
角色三:Colleague(抽象同事)
角色四:ConcreteColleague(具体同事)

中介者模式-原理案例

角色一:ComputerMediator->电脑(很多种类)->中介者、华为、苹果、三星...

//
//  ComputerMediator.swift
//  ComputerMediator
//
//  Created by Dream on 2018/7/25.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

//中介者->抽象中介者
//特点:持有同事引用
class ComputerMediator: NSObject {

    func changed(colleague:ComputerColleague) {
        
    }
    
}

角色二:SXComputerMediator->具体电脑

//
//  SXComputerMediator.swift
//  ComputerMediator
//
//  Created by Dream on 2018/7/25.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

//中介者调度CPU、DisplayCard、SoundCard、CDCard
//持有CPU、DisplayCard、SoundCard、CDCard的引用和运行方法,中介者来调度这些行为,CPU、DisplayCard、SoundCard、CDCard每一个都有自己特定的行为
//通过中介者解除耦合
class SXComputerMediator: ComputerMediator {

    private var cpu:CPU?
    private var displayCard:DisplayCard?
    private var soundCard:SoundCard?
    private var cdDevice:CDDevice?
    
    func setCPU(cpu:CPU) {
        self.cpu = cpu
    }
    
    func setDisplayCard(displayCard:DisplayCard) {
        self.displayCard = displayCard
    }
    
    func setSoundCard(soundCard:SoundCard) {
        self.soundCard = soundCard
    }
    
    func setCDDevice(cdDevice:CDDevice) {
        self.cdDevice = cdDevice
    }
    
    //架构思维->被案例迷惑了->结构搞明白了
    override func changed(colleague: ComputerColleague) {
        if colleague == cpu {
            self.handleCD(cpu: colleague as! CPU)
        } else if colleague == cdDevice {
            self.handleCD(cd: colleague as! CDDevice)
        }
    }
    
    //CPU读取数据->显示过程
    //解析数据
    private func handleCD(cd:CDDevice) {
        cpu?.decodeData(data: cd.read())
    }
    
    //设备交互
    private func handleCD(cpu:CPU) {
        self.soundCard?.soundPlay(data: cpu.getSoundData())
        self.displayCard?.videoPlay(data: cpu.getVideoData())
    }
    
}

角色三:ComputerColleague->抽象同事

//
//  ComputerColleague.swift
//  ComputerMediator
//
//  Created by Dream on 2018/7/25.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

//抽象同事
class ComputerColleague: NSObject {

    var mediator:ComputerMediator
    
    init(mediator:ComputerMediator) {
        self.mediator = mediator
    }
    
}

零件:主板、cpu、显示器...
角色四:CPU、DisplayCard、Mainboard->具体同事

//
//  CPU.swift
//  ComputerMediator
//
//  Created by Dream on 2018/7/25.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

//同事
class CPU: ComputerColleague {
    
    //视频数据
    private var videoData:String?
    //音频数据
    private var soundData:String?

    override init(mediator: ComputerMediator) {
        super.init(mediator: mediator)
    }
    
    func getVideoData() -> String {
        return self.videoData!
    }
    
    func getSoundData() -> String {
        return self.soundData!
    }
    
    func decodeData(data:String) {
        let array = data.split(separator: ",").map(String.init)//map确定字符串分割之后的元素类型
        self.videoData = array[0]
        self.soundData = array[1]
        mediator.changed(colleague: self)
    }
    
    
}

//
//  DisplayCard.swift
//  ComputerMediator
//
//  Created by Dream on 2018/7/25.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

//同事
class DisplayCard: ComputerColleague {
    
    override init(mediator: ComputerMediator) {
        super.init(mediator: mediator)
    }

    //播放视频数据
    func videoPlay(data:String) {
        print("播放视频...")
    }
    
}

//
//  Mainboard.swift
//  ComputerMediator
//
//  Created by Dream on 2018/7/25.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

//同事
class SoundCard: ComputerColleague {

    override init(mediator: ComputerMediator) {
        super.init(mediator: mediator)
    }
    
    //播放视频数据
    func soundPlay(data:String) {
        print("播放音频...")
    }
    
}

//
//  CDCard.swift
//  ComputerMediator
//
//  Created by Dream on 2018/7/25.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

//同事
//CD设备->负责读取光盘数据传递给电脑主板
class CDDevice: ComputerColleague {

    private var data:String?
    
    override init(mediator: ComputerMediator) {
        super.init(mediator: mediator)
    }
    
    func read() -> String {
        return self.data!
    }
    
    func load() {
        //数据格式
        self.data = "视频数据,音频数据"
        mediator.changed(colleague: self)
    }
    
}

调用

    //测试
        //核心->中介者
        let mediator = SXComputerMediator()
        //零件->同事
        let cpu = CPU(mediator: mediator)
        let displayCard = DisplayCard(mediator: mediator)
        let cdDevice = CDDevice(mediator: mediator)
        let soundCard = SoundCard(mediator: mediator)

        mediator.setCPU(cpu: cpu)
        mediator.setSoundCard(soundCard: soundCard)
        mediator.setDisplayCard(displayCard: displayCard)
        mediator.setCDDevice(cdDevice: cdDevice)

        //开始播放->开始放影片
        cdDevice.load()

结构(解释)
看一看
注意了?
在我们传统开发中:所有功能都将写在哪里?
播放视频和音频
播放CD->我自己播放不了->但是没有关系->中介者帮助我进行协调
中介者是串联

如果不通过中介者这些功能之间会出现耦合

中介者模式-开发案例?->MVP架构设计

实际开发案例->MVP架构设计
MVP分层
按照传统开发:数据和UI
M层:数据层->数据库、网络、文件…
V层:UI层(UIView + UIViewController->创建UI、更新UI)
P层:中介->Presenter(将M层和V层进行关联)

与中介者模式有什么关系?
角色一:抽象中介者->P层->MvpPresenterProtocol->协议

//
//  MvpPresenterProtocol.swift
//  ComputerMediator
//
//  Created by Dream on 2018/7/25.
//  Copyright © 2018年 Tz. All rights reserved.
//

import Foundation

//角色一:抽象中介者->P层->MvpPresenterProtocol->协议
//两个标准
//持有同事引用
protocol MvpPresenterProtocol {
    
    //标准一:绑定V层(绑定引用)
    func attachView(view:MvpViewProtocol)
    
    //标准二:解绑V层(释放引用)
    func detachView()
    
}

    角色二:具体中介者->P层->LoginPresenter->具体实现类

//
// LoginPresenter.swift
// ComputerMediator
//
// Created by Dream on 2018/7/25.
// Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

//角色二:具体中介者->P层->LoginPresenter->具体实现类
//关联->持有引用
class LoginPresenter: MvpPresenterProtocol, Callback {

private var model:LoginModel
private var view:LoginView?

init() {
    self.model = LoginModel()
}

//随便举个例子(抽象)
func attachView(view: MvpViewProtocol) {
    self.view = view as? LoginView
}

func detachView() {
    self.view = nil
}

func login(name:String, password:String) {
    //业务逻辑
    self.model.login(name: name, password: password, callback: self)
}

func onResult(result: Any?) {
    self.view?.onLoginResult(result: result)
}

}

    角色三:抽象同事->M层+V层
        ModelProtocol、MvpViewProtocol
//
//  ModelProtocol.swift
//  ComputerMediator
//
//  Created by Dream on 2018/7/25.
//  Copyright © 2018年 Tz. All rights reserved.
//

import Foundation


//角色三:抽象同事->M层
protocol ModelProtocol {
    //看需求
}

//
//  MvpViewProtocol.swift
//  ComputerMediator
//
//  Created by Dream on 2018/7/25.
//  Copyright © 2018年 Tz. All rights reserved.
//

import Foundation

//角色三:抽象同事->V层(最高层次协议,没有任何定义,只是一个规范)
protocol MvpViewProtocol {
    
}

    角色四:具体同事->LoginModel、LoginView
//
//  LoginModel.swift
//  ComputerMediator
//
//  Created by Dream on 2018/7/25.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit



protocol Callback {
    func onResult(result:Any?)
}

//角色四:具体同事->LoginModel
class LoginModel: ModelProtocol {

    func login(name:String, password:String, callback:Callback) {
        //发起请求->回调UI
        //调用登录逻辑(数据库、网络、文件)
        //...忽略100行代码
    }
    
}

//
//  LoginView.swift
//  ComputerMediator
//
//  Created by Dream on 2018/7/25.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

//角色四:具体同事->LoginView
protocol LoginView: MvpViewProtocol {
    func onLoginResult(result:Any?)
}

调用

      self.presenter = LoginPresenter()
        //绑定
        self.presenter?.attachView(view: self)
        self.presenter?.login(name: "", password: "")

    
    //回调
    func onLoginResult(result: Any?) {
        
    }

优化

//
//  BaseMvpPresenter.swift
//  ComputerMediator
//
//  Created by Dream on 2018/7/25.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

class BaseMvpPresenter<T: MvpViewProtocol>: MvpPresenterProtocol {
    func attachView(view: MvpViewProtocol) {
        
    }
    

    var view:T?
    
    func getView() -> T? {
        return self.view
    }
    
    func attachView(view: T) {
        self.view = view
    }
    
    func detachView() {
        self.view = nil
    }
    
}

//
//  LoignPresenter1.swift
//  ComputerMediator
//
//  Created by Dream on 2018/7/25.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

//Swift泛型类型不能是协议(中间做一个class)

class LoignPresenter1: BaseMvpPresenter<LoginView1>, Callback {

    private var model:LoginModel
    
    override init() {
        self.model = LoginModel()
        super.init()
    }
    
    func login(name:String, password:String) {
        //业务逻辑
        self.model.login(name: name, password: password, callback: self)
    }
    
    func onResult(result: Any?) {
        //强制类型转换->真他妈啃爹(泛型设计来了)
        getView()?.onLoginResult(result: result)
    }
    
}

//
//  LoginView1.swift
//  ComputerMediator
//
//  Created by Dream on 2018/7/25.
//  Copyright © 2018年 Tz. All rights reserved.
//

import UIKit

class LoginView1: MvpViewProtocol {

    func onLoginResult(result:Any?){
        
    }
    
}

登录、注册、详情页…
MVP写的高级,将所有的系统层面重写一次
例如:MvpViewController、MvpUIView、MvpUIButton、MvpUILayout…

中介者模式UML

相关文章

网友评论

    本文标题:中介者模式

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