总目录
前言
1 基础介绍
- 定义:将抽象部分与实现部分分离,使它们都可以独立地变化。
- 桥模式不能只认为是抽象和实现的分离,它其实并不仅限于此。其实两个都是抽象的部分,更确切的理解,应该是将一个事物中多个维度的变化分离。
- 一个维度可以认为是抽象部分,另一个维度可以认为是实现部分,而这两个维度可以独立扩充和维护。
- 桥接模式中的角色:
- 抽象化角色(Abstraction):定义抽象类的接口,一般为抽象类,规范RefinedAbstraction,并保存一个对实现化对象(Implementor)的引用。主要靠这个类进行桥接
- 修正抽象化角色(Refined Abstraction):Abstraction的子类,具体实现Abstraction里规定的方法。
- 实现化角色(Implementor):这个角色给出实现化角色的接口,但不给出具体的实现。必须指出的是,这个接口不一定和抽象化角色的接口定义相同,实际上,这两个接口可以非常不一样。实现化角色应当只给出底层操作,而抽象化角色应当只给出基于底层操作的更高一层的操作。
- 具体实现化角色(Concrete Implementor):Implementor的子类,这个角色给出实现化角色接口的具体实现。
在桥接模式中,两个类Abstraction和Implementor分别定义了抽象与行为类型的接口,通过调用两接口的子类实现抽象与行为的动态组合。
2 使用场景
- 如果一个系统需要在构件的抽象化角色和具体化角色之间添加更多的灵活性,避免在两个层次之间建立静态的联系。
- 设计要求实现化角色的任何改变不应当影响客户端,或者实现化角色的改变对客户端是完全透明的。
- 需要跨越多个平台的图形和窗口系统上。
- 一个类存在两个独立变化的维度,且两个维度都需要进行扩展。
3 实现方式
只看上面的各种介绍可能还是不容易理解,还是通过案例来看看吧!
比如不用软件运行在不同的操作系统上。
现在我们开始分析:不同的软件,代表的是软件维度,不同的操作系统是系统角度,运行 则是 具体要实现的功能。
- 操作系统是一个维度,分为ios、Android、Windows等。
- 软件系统是一个维度,分别为微信、QQ、酷狗音乐等
注意:软件要运行 在操作系统上,因此最终软件 是实现运行的 实现部分,操作系统只是提供运行平台,属于更高维度,因此是抽象部分。
分析出对应角色:
Abstraction —》操作系统抽象类
RefinedAbstraction—》ios、Android、Windows等具体实现
Implementor----》软件接口类
ConcreteImplementor—》微信、QQ、酷狗音乐等具体实现
桥接模式分为两部分 抽象部分 和 实现部分 两部分代码
1 实现部分的代码如下:
// 之所以叫实现部分,是因为这部分的代码才是实际功能的实现, // 抽象部分只是对他进行了一个引用和包装 //1 首先定义一个 软件接口类【Implementor】 public abstract class AbstractSoftware { //定义一个启动软件的方法 public abstract void Start(); } //2 在定义软件接口的实现类【ConcreteImplementor】 public class QQ : AbstractSoftware { public override void Start() { Console.WriteLine("QQ 启动了!"); } } public class WeChat : AbstractSoftware { public override void Start() { Console.WriteLine("WeChat 启动了!"); } }
2 抽象部分的代码如下:
// 定义操作系统抽象类【Abstraction】 // 该类为实际的桥接类,并且还规范了更高一层的方法。 public abstract class AbstractSysPlatform { //定义AbstractSoftware 变量,保持对该对象的引用 //因为需要该变量进行桥接的操作 public AbstractSoftware _AbstractSoftware; public AbstractSysPlatform(AbstractSoftware abstractSoftware) { _AbstractSoftware = abstractSoftware; } //定义一个 系统上运行软件的方法,供子类去实现 //该方法为更高一层的方法 public abstract void Run(); } //定义一个操作系统Windows的实现类 public class Windows : AbstractSysPlatform { public Windows(AbstractSoftware abstractSoftware) : base(abstractSoftware) { } //我们要实现在Windows上运行软件的方法 public override void Run() { Console.WriteLine("当前为Windows系统"); _AbstractSoftware.Start(); } } //定义一个操作系统IOS的实现类 public class IOS : AbstractSysPlatform { public IOS(AbstractSoftware abstractSoftware) : base(abstractSoftware) { } //我们要实现在IOS上运行软件的方法 public override void Run() { Console.WriteLine("当前为IOS系统"); _AbstractSoftware.Start(); } }
3 客户端调用
static void Main(string[] args) { //在WIndows上运行QQ AbstractSoftware qq = new QQ(); AbstractSysPlatform win = new Windows(qq); win.Run(); //在IOS上运行WeChat AbstractSoftware weChat = new WeChat(); AbstractSysPlatform ios = new IOS(weChat); ios.Run(); Console.ReadKey(); }
4 应对需求变化
当我们的新增了一个软件抖音,我们只需要,新增如下代码即可:
public class Tiktok : AbstractSoftware { public override void Start() { Console.WriteLine("Tiktok 启动了!"); } }
就可以在不改动原有代码的情况了,客户端只需调用相关代码就可实现 抖音在Window 和 IOS 上的运行。
如果我们还想增加一个操作系统平台,也只需要新增如下代码:
public class Android : AbstractSysPlatform { public Android(AbstractSoftware abstractSoftware) : base(abstractSoftware) { } public override void Run() { Console.WriteLine("当前为Android系统"); _AbstractSoftware.Start(); } }
同样可以在不修改原有代码的情况下,客户端只需调用相关代码就可实现QQ,WeChat,Tiktok 在Android 平台上的运行。
我们发现,桥接模式可以极好的处理两种维度存在变化,但是两个维度间又有联系的这种情况,并且可以做到少量代码的新增,得到极大的功能扩展。
4 优缺点分析
优点:将抽象部分与它的实现部分分离,使它们都可以独立地变化
缺点:增加了系统的复杂度
结语
希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。