文章目录
1、桥接模式介绍
2、桥接模式类图
3、桥接模式Demo实现(移动互联网时代的手机设计)
4、桥接模式总结
桥接模式介绍:
桥接模式将变化封装,使用组合的方式将变化的抽象放到类中,属于结构形设计模式。
类图:
一个简单的Demo(移动互联网时代的手机设计):
现在,我们有一个手机的抽象基类BasePhone,它有获取它的操作系统(abstract string System()),获取它的版本号(abstract string Version())和打电话(abstract void Call())三个功能。接下来,我们有三部手机,分别是Iphone,xiaomi,winphone。分别是IOS 9.0操作系统,Android 6.0操作系统,Windows 10.0操作系统。用代码来实现下。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 手机抽象类 3 /// </summary> 4 public abstract class BasePhone 5 { 6 /// <summary> 7 /// 操作系统 8 /// </summary> 9 /// <returns></returns> 10 public abstract string System(); 11 /// <summary> 12 /// 版本 13 /// </summary> 14 /// <returns></returns> 15 public abstract string Version(); 16 /// <summary> 17 /// 打电话 18 /// </summary> 19 public abstract void Call(); 20 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 微软手机 3 /// </summary> 4 public class WinPhone : BasePhone 5 { 6 public override void Call() 7 { 8 Console.WriteLine($"{this.GetType().Name}手机是{this.System()}的操作系统,版本为{this.Version()}"); 9 } 10 11 public override string System() 12 { 13 return "Windows"; 14 } 15 16 public override string Version() 17 { 18 return "10.0"; 19 } 20 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 小米手机 3 /// </summary> 4 public class XiaomiPhone:BasePhone 5 { 6 7 public override string System() 8 { 9 return "Android"; 10 } 11 12 public override string Version() 13 { 14 return "6.2"; 15 } 16 public override void Call() 17 { 18 Console.WriteLine($"{this.GetType().Name}手机是{this.System()}的操作系统,版本为{this.Version()}"); 19 } 20 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// IPhone手机 3 /// </summary> 4 public class IPhone : BasePhone 5 { 6 public override string System() 7 { 8 return "IOS"; 9 } 10 11 public override string Version() 12 { 13 return "9.0"; 14 } 15 16 public override void Call() 17 { 18 Console.WriteLine($"{this.GetType().Name}手机是{this.System()}的操作系统,版本为{this.Version()}"); 19 } 20 }
接下来分别调用一下它们打电话的方法,这里打电话输出一下手机类型,操作系统和版本号。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //用一台小米打电话 2 BasePhone xiaomi = new XiaomiPhone(); 3 xiaomi.Call(); 4 //用一台Winphone打电话 5 BasePhone winphone = new WinPhone(); 6 winphone.Call(); 7 //用一台iphone打电话 8 BasePhone iphone = new IPhone(); 9 iphone.Call();
我们知道,手机是可以刷机的,例如我们可以给我们的Winphone手机刷一个IOS操作系统。这样我们就需要实现这样一个手机类WinPhoneIOSsystem。内部方法System返回操作系统为IOS,Version返回版本好为9.0,如下所示。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 微软手机 3 /// </summary> 4 public class WinPhoneIOSsystem : BasePhone 5 { 6 public override void Call() 7 { 8 Console.WriteLine($"{this.GetType().Name}手机是{this.System()}的操作系统,版本为{this.Version()}"); 9 } 10 11 public override string System() 12 { 13 return "IOS"; 14 } 15 16 public override string Version() 17 { 18 return "9.0"; 19 } 20 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 BasePhone winphoneWithIOS = new WinPhoneIOSsystem(); 2 winphoneWithIOS.Call();
以这样的方式来实现,那我们可以三种手机分别刷三种系统,就需要3*3个子类。这样显然是不合适。这时候我们就可以使用桥接模式来解决这个问题。因为我们的操作系统和版本号是可以改变的,那么我们可以把它单独封装
起来,这里使用一个接口ISystem来实现,这个接口有两个方法分别是操作系统版本和操作系统版本号。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 操作系统 3 /// </summary> 4 public interface ISystem 5 { 6 string System(); 7 string Version(); 8 }
同样,分别把三个操作系统实现。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 安卓操作系统 3 /// </summary> 4 public class Android : ISystem 5 { 6 public string System() 7 { 8 return "Android"; 9 } 10 11 public string Version() 12 { 13 return "6.3"; 14 } 15
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
这时我们修改下我们的手机基类,将操作系统和版本放到变量system中去。这个变量由子类实现时候给它初始化。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 手机抽象类 3 /// </summary> 4 public abstract class BasePhone 5 { 6 /// <summary> 7 /// 操作系统和版本号封装到Isystem接口 8 /// </summary> 9 public ISystem system; 10 11 12 ///// <summary> 13 ///// 操作系统 14 ///// </summary> 15 ///// <returns></returns> 16 //public abstract string System(); 17 ///// <summary> 18 ///// 版本 19 ///// </summary> 20 ///// <returns></returns> 21 //public abstract string Version(); 22 23 24 /// <summary> 25 /// 打电话 26 /// </summary> 27 public abstract void Call(); 28 }
修改后的手机子类如下所示。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 小米手机 3 /// </summary> 4 public class XiaomiPhone:BasePhone 5 { 6 public override void Call() 7 { 8 9 if (this.system == null) 10 throw new Exception("请初始化操作系统"); 11 Console.WriteLine($"{this.GetType().Name}手机是{this.system.System()}的操作系统,版本为{this.system.Version()}"); 12 } 13 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// 微软手机 3 /// </summary> 4 public class WinPhone : BasePhone 5 { 6 public override void Call() 7 { 8 9 if (this.system == null) 10 throw new Exception("请初始化操作系统"); 11 Console.WriteLine($"{this.GetType().Name}手机是{this.system.System()}的操作系统,版本为{this.system.Version()}"); 12 } 13 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /// <summary> 2 /// IPhone手机 3 /// </summary> 4 public class IPhone : BasePhone 5 { 6 public override void Call() 7 { 8 if (this.system == null) 9 throw new Exception("请初始化操作系统"); 10 Console.WriteLine($"{this.GetType().Name}手机是{this.system.System()}的操作系统,版本为{this.system.Version()}"); 11 } 12 }
这时候我们给一台小米手机使用IOS操作系统就能如下所示。
此时,我们不同的“手机(实现类)”刷不同的"系统(抽象)",所需要的实现类个数为 M + N 就可以完成了。(M手机类型,N系统类型)相比之前的方式实现个数为M*N,减少了大量实现类。
桥接模式总结:
- 桥接模式将实现予以解耦,将变化的部分独立封装起来。
- 抽象部分和实现部分可以独立扩展,不会影响到对方。
- 桥接模式使上端(客户端)知道了更多的细节,增加了代码的复杂度。