聊聊Swift中的设计模式---结构型(桥接模式)

326 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第17天,点击查看活动详情


前言

在面向对象的开发过程中,其实咱们或多或少的都接触过一些设计模式,可能知道或不知道其对应的名称,也不知道其具体使用场景,今天咱们就来说说几种常见的设计模式,帮助你们在开发过程中,更加得心应手。

正文

桥接模式

关于桥接模式的定义,就是将类的抽象部分和它具体的实现部分,进行按需分离,让他们可以进行独立的,有选择的变化,然后通过组合,建立起两个类直接的联系。

这个模式的核心关键就是解耦抽象和实现。

咱们来通过一个例子说明一下:

首先新建一个TV类

protocol TV { 
    func on() 
    func off() 
    func tuneChannel(channel: Int) 
   }

按品牌分,就有Haier、KONKA

/// 海尔电视
class Haier : TV {
    func on() {
        print("Haier on")
    }
    func off() {
        print("Haier off")
    }
    func tuneChannel(channel: Int) {
        print("Haier 切换到 (channel) 频道")
    }
}

/// 康佳电视
class KONKA : TV {
    func on() {
        print("KONKA on")
    }
    func off() {
        print("KONKA off")
    }
    func tuneChannel(channel: Int) {
        print("KONKA 切换到 (channel) 频道")
    }
}

因为Haier、KONKA都是继承自TV类,所以它们就是TV类这个抽象类的实体

假设咱们这是要有个遥控器去控制Haier、KONKA电视,只能通过Haier、KONKA的类去实例化对应的遥控器,让后去实现他们里面对应的方法

let Remote_KONKA = KONKA()
Remote_KONKA.on()
Remote_KONKA.off()
...


let Remote_Haier = Haier()
Remote_Haier.on()
Remote_Haier.off()

这样就会造成实例过多,那咱们来看看桥接模式如何解决这个问题。

然后咱们来实现一个RemoteControl(遥控器)


protocol RemoteControl {
    var tv: TV{get set}
    
    func on()
    func off()
    func setChannel(channel: Int)
}

这里,RemoteControl类中传入了TV的实例

让后咱们再扩展RemoteControl的方法

extension RemoteControl {
    func on() {
        tv.on()
    }
    
    func off() {
        tv.off()
    }
    
    func setChannel(channel: Int) {
        tv.tuneChannel(channel: channel)
    }
}

这个extension中,可以写RemoteControl方法非实现和自定义的方法。

然后咱们再创建个万能遥控器


/// 万能遥控器
class ConcreteRemote : RemoteControl {
    
    var tv: TV
    
    var channel: Int
    
    init(tv: TV, channel: Int = 0) {
        self.tv = tv
        self.channel = channel
    }
        
    func nextChannel() {
        self.channel += 1
        setChannel(channel: channel)
    }
    
    func previousChannel() {
        self.channel -= 1
        setChannel(channel: channel)
    }
}

这个万能遥控器类里面,初始化时,传入了TV的实例,所以,使用时,只要传对应的TV类型就可以控制对应的TV了。


let haierRemote = ConcreteRemote(tv: Haier())
haierRemote.on()
haierRemote.nextChannel()
haierRemote.off()

print("\n")
let konkaRemove = ConcreteRemote(tv: KONKA(), channel: 3)
konkaRemove.on()
konkaRemove.previousChannel()
konkaRemove.off()

结果将输出:

Haier on

Haier 切换到 1 频道

Haier off

KONKA on

KONKA 切换到 2 频道

KONKA off

结语

桥接模式的优点

1,将一个复杂的类分离出抽象部分和实现部分两个维度,完成了代码的解耦,提高了系统的扩展性。 2,扩展时只需要新增类,无需修改源代码,符合开闭原则。 3,通过组合而不是继承来实现耦合,符合合成复用原则。

缺点

1、增加了系统的理解难度和设计难度(这也算是大部分设计模式的共性)
2、需要正确识别系统中各个独立变化的维度


扩展阅读 下面还有其他模式

创建型-工厂模式

创建型-建造者模式

结构型-适配器模式

结构型-组合模式