项目开发过程中,我们会经常性的封装一个父类,里面提供一些基本操作,然后用子类进一步扩展父类的功能。假设我们要实现一个手机软件类,这个软件可能是游戏,可能是基础应用(如电话、设置、文件管理等);可能有些面向对象思维比较好的朋友会设计一个软件基础类,用来提供所有软件共同的操作(如打开软件,关闭软件),然后根据不同的APP来封装对应的APP类,在APP类中扩展其特有的功能。当我们的APP类足够多时,有些APP的功能可能相似甚至相同,这时候我们在把相同的功能提到父类中,久而久之父类的代码越来越臃肿,维护成本越来越高。
这是我们不愿看到的,因为如果APP在某个手机品牌中有不同的表现形式或者新的功能的话,实现这扩展功能会带来更大的难度。
那么我们怎么去避免这种情况的发生呢?别急,我们先来了解一个原则:合成/聚合复用原则:聚合是一种弱的“拥有”关系,表现为A对象包含B对象,但是B对象不是A对象的一部分;合成则是一种强的“拥有”关系,体现了严格的整体和部分的关系,整体和部分的生命周期一样。比如一个手机软件由代码、UI组成,我们在使用中是将其加载到内存中才能正常运行,如果我们把它从进程中关闭的话,那么其代码、UI都要从内存中释放掉。这就是合成;手机中不同的软件按应用类型划分为某个软件栏中(如某宝、某东等组成购物栏),我们可以安装/卸载此类软件。这就是聚合,因为我们可以使某个软件放在购物一栏,也可以放在日常使用一栏。
说了这么多,这跟桥接模式有什么关系呢?首先什么是桥接模式?将抽象部分和实现部分分离出来,使得这两部分可以独立的变化。这就是桥接模式的核心,它将抽象部分和实现部分分离出来,进而达到降低耦合的作用,使得我们上方的APP的父类不会因为某些APP的特性变得臃肿。我们以一个简单的例子来说明一下该如何设计桥接模式。
Talk is cheap. Show me the code!!!!
abstract class PhoneSoftware
{
public abstract void Operation();
}
class AddressList : PhoneSoftware
{
public override void Operation()
{
Console.WriteLine("打开通讯录");
}
}
class Game : PhoneSoftware
{
public override void Operation()
{
Console.WriteLine("打开游戏");
}
}
abstract class MobilePhone
{
public PhoneSoftware ps;
public void SetAddSoftware(PhoneSoftware ps)
{
this.ps = ps;
}
public abstract void OpenSoftware();
}
class XiaoMi : MobilePhone
{
public override void OpenSoftware()
{
Console.WriteLine("小米手机操作:");
ps.Operation();
}
}
class HuaWei : MobilePhone
{
public override void OpenSoftware()
{
Console.WriteLine("华为手机操作:");
ps.Operation();
}
}
首先我们设计了软件PhoneSoftware抽象类,里面封装了软件的使用抽象方法;其次我们封装了通讯录类AddressList及游戏类Game,并使其分别继承软件类及实现使用方法;接着我们封装了手机MobilePhone抽象类,里面提供了安装软件的方法及使用软件的抽象类;最后我们封装出来两个熟悉的手机品牌小米XiaoMi类及华为HuaWei类,使其继承手机类并实现使用软件的方法。将软件类和手机类分开实现并且使其各自实现各自的不同的对象以达到合成/聚合的原则。
接下来我们来看如何安装并使用软件。
class Program
{
static void Main(string[] args)
{
MobilePhone huawei = new HuaWei();
huawei.SetAddSoftware(new Game());
huawei.OpenSoftware();
MobilePhone xiaomi = new XiaoMi();
xiaomi.SetAddSoftware(new Game());
xiaomi.OpenSoftware();
Console.ReadKey();
}
}
可以看到我们分别定义了huawei及xiaomi类并设置其内部软件为游戏类,并且调用操作软件方法,此时两款手机就会分别执行Game类中的Operation方法;如果想要某个APP在某个手机品牌中有不同的表现效果,只需在对应的软件类中修改代码即可;不会使得父类变得臃肿。
以上就是桥接模式的示例,通俗的来说,桥接模式的核心思想就是把实现类给独立出来,让它们各自改变,这就使得每种实现的变化都不会影响其他的实现,从而达到应对变化的目的。
最后,thanks for reading!!!!
注:本人的设计模式系列是根据大话设计模式一书中的内容,加以自身总结说明,一方面想多锻炼自身的表达能力,另一方面希望能够提升自身的编程能力及代码架构水平。若是能让更多的人通过我的文章来明白该设计模式的作用、应用场景及独立设计出来,当然也是对我个人表达能力的提升及掌握程度的认可。最后再次说明,本文内容来自大话设计模式一书,我只是写出来并加以总结希望达到熟练掌握的程度。如果你通过本文搞懂了,那么50%归功于此书,49%归功于你自己,1%为本人(脸都不要了)。



