c#桥接模式详解
基础介绍:
将抽象部分与它的实现部分分离,使它们都可以独立地变化。适用于不希望在抽象和实现部分之间有固定的绑定关系的情况,或者类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充的情况。
将抽象部分与实现部分分离,使它们都可以独立地变化。
其实两个都是抽象的部分,更准确的说,是将一个事物中多个维度的变化分离。
比如不用软件运行在不同的操作系统上。
操作系统是一个维度,分为ios、Android、Windows等。
软件系统是一个维度,分别为微信、QQ、酷狗音乐等。
一个维度可以认为是抽象部分,另一个维度可以认为是实现部分,而这两个维度可以独立扩充和维护。
单独看起来比较复杂和难以理解,可以先大致看下基础结构,然后结合以下实例来解读。
桥接模式的结构:
Abstraction:定义抽象类的接口,一般为抽象类,规范RefinedAbstraction,并创建一个Implementor实例。主要靠这个类来进行桥接。
RefinedAbstraction:Abstraction的子类,具体实现Abstraction里规定的方法。
Implementor:定义实现类的接口,一般情况,Implementor接口仅为提供基本操作,而Abstraction则定义了基于基本操作的较高层次操作。
ConcreteImplementor:Implementor的子类,具体实现Implementor接口 。
在桥接模式中,两个类Abstraction和Implementor分别定义了抽象与行为类型的接口,通过调用子类实现抽象与行为的动态组合。
应用场景:
适用于不希望在抽象和实现部分之间有固定的绑定关系的情况,或者类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充的情况。
创建方式:
桥接模式的实现方式是通过在抽象类中持有一个指向实现类的引用,从而将抽象类与实现类解耦。
通常情况下,抽象类和实现类都需要定义自己的接口,以便彼此之间进行通信。
实例一:不用软件运行在不同的操作系统上。
操作系统是一个维度,分为ios、Android、Windows等。
软件系统是一个维度,分别为微信、QQ、酷狗音乐等。
这两个维度可以独立扩充和维护,一个维度可以认为是抽象部分,另一个维度可以认为是实现部分。
实现部分中的接口(Implementor)只需提供基本操作,抽象部分中的接口(Abstraction)来创建一个实现接口(Implementor)实例,用这个实例将两部分紧密连续在一起。
抽象部分也是基于这个实例才做一些较高层次的操作。
在这里可以把操作系统当做抽象部分,把软件系统当做实现部分。
在抽象部分中创建一个抽象类(Abstraction),该类中创建一个软件系统的实例,即实现类的实例(Implementor),并规定抽象部分具体实现类(RefinedAbstraction)要实现哪些方法。
注:抽象类和接口主要起桥梁作用和规范作用(Abstraction和Implementor),其具体实现都在其子类中(RefinedAbstraction和ConcreteImplementor)。
在实现部分中创建一个接口(Implementor),该接口主要规范实现类(ConcreteImplementor)需要实现的方法。
RefinedAbstraction和ConcreteImplementor分别继承自Abstraction和Implementor,并实现其规定的方法。
即:
Abstraction ---》操作系统抽象类
RefinedAbstraction---》ios、Android、Windows等具体实现
Implementor----》软件接口类
ConcreteImplementor---》微信、QQ、酷狗音乐等具体实现
1、软件接口类
1 /// <summary> 2 /// 软件接口类 3 /// </summary> 4 public interface ISoftWare 5 { 6 /// <summary> 7 /// 定义一个软件启动方法 8 /// </summary> 9 void Start(); 10 }
Implementor-实现类接口,只声明最基本的方法。
2、软件实现类
1 /// <summary> 2 /// 微信 3 /// </summary> 4 public class WeChat : ISoftWare 5 { 6 public void Start() 7 { 8 Console.WriteLine("启动微信"); 9 } 10 } 11 12 /// <summary> 13 /// QQ 14 /// </summary> 15 public class TencentQQ : ISoftWare 16 { 17 public void Start() 18 { 19 Console.WriteLine("启动QQ"); 20 } 21 }
ConcreteImplementor-继承自实现类接口,实现其基本方法。
3、系统抽象类
1 /// <summary> 2 /// 系统抽象类(桥接类) 3 /// </summary> 4 public abstract class SystemPlatform 5 { 6 //创建软件类实例 7 public ISoftWare _softWare; 8 9 //通过构造函数注入具体软件实例 10 public SystemPlatform(ISoftWare softWare) 11 { 12 this._softWare = softWare; 13 } 14 15 //执行软件运行 16 public abstract void Run(); 17 }
Abstraction-操作系统抽象类,创建一个实现类实例,用来访问实现类内的操作。
该类为实际的桥接类,其他还规范了更高一层的方法。
4、系统平台实现类
1 /// <summary> 2 /// ios系统 3 /// </summary> 4 public class IosSys : SystemPlatform 5 { 6 public IosSys(ISoftWare softWare) 7 : base(softWare) 8 { 9 Console.WriteLine("进入IOS系统"); 10 } 11 public override void Run() 12 { 13 _softWare.Start(); 14 } 15 } 16 17 /// <summary> 18 /// Android系统 19 /// </summary> 20 public class AndroidSys : SystemPlatform 21 { 22 public AndroidSys(ISoftWare softWare) 23 : base(softWare) 24 { 25 Console.WriteLine("进入Android系统"); 26 } 27 public override void Run() 28 { 29 _softWare.Start(); 30 } 31 }
RefinedAbstraction-系统抽象具体实现类,实现了各个实际功能。
5、客户端
1 /// <summary> 2 /// 客户端 3 /// </summary> 4 class Client 5 { 6 static void Main(string[] args) 7 { 8 //创建软件对象 9 WeChat weChat = new WeChat(); 10 TencentQQ tencentQQ = new TencentQQ(); 11 12 //创建操作系统并安装软件 13 SystemPlatform systemPlatform = new IosSys(weChat); 14 systemPlatform.Run(); 15 16 systemPlatform = new AndroidSys(tencentQQ); 17 systemPlatform.Run(); 18 19 Console.ReadKey(); 20 } 21 }
这只是一个简单的实例,如果一个系统中预装载多个软件,可以将构造函数改为集合参数或者申明其他公开方法进行预安装。
实例二:不同形状的物体赋予不同颜色。
不同形状的物体是一个维度,分别为长方形、矩形、圆形等。
不同颜色是一个维度,分别为白色、黑色、红色等。
即:
Abstraction ---》形状抽象类
RefinedAbstraction---》方形 圆形等具体实现
Implementor----》颜色接口类
ConcreteImplementor---》白色 黑色等具体实现
1、颜色接口类
1 public interface Color 2 { 3 void Bepaint(); 4 }
规范颜色实现类,并供形状抽象类使用和维护。
2、颜色实现类
1 public class White : Color 2 { 3 public void Bepaint() 4 { 5 Console.WriteLine("白色的"); 6 } 7 } 8 9 public class Gray : Color 10 { 11 public void Bepaint() 12 { 13 Console.WriteLine("灰色的"); 14 } 15 } 16 17 public class Black : Color 18 { 19 public void Bepaint() 20 { 21 Console.WriteLine("黑色的"); 22 } 23 }
3、形状抽象类
1 public abstract class Shape 2 { 3 public Color color; 4 public void SetColor(Color color) 5 { 6 this.color = color; 7 } 8 public abstract void Draw(); 9 }
创建颜色实例供实现类使用,并规范实现类。
这个类主要是将形状和颜色两个维度的东西联系在一起,并制定高一级的操作规范。
4、形状实现类
1 public class Circle : Shape 2 { 3 public override void Draw() 4 { 5 color.Bepaint(); 6 Console.WriteLine("圆形"); 7 } 8 } 9 public class Rectangle : Shape 10 { 11 12 public override void Draw() 13 { 14 color.Bepaint(); 15 Console.WriteLine("长方形"); 16 } 17 } 18 public class Square : Shape 19 { 20 public override void Draw() 21 { 22 color.Bepaint(); 23 Console.WriteLine("正方形"); 24 } 25 }
具体实现类
5、客户端
1 class Client 2 { 3 static void Main(string[] args) 4 { 5 //白色 6 Color white = new White(); 7 //正方形 8 Shape square = new Square(); 9 //白色的正方形 10 square.SetColor(white); 11 square.Draw(); 12 13 //长方形 14 Shape rectange = new Rectangle(); 15 rectange.SetColor(white); 16 rectange.Draw(); 17 18 Console.ReadKey(); 19 } 20 }
其实颜色和形状两个维度的东西,各自维护和发展并不互相影响。
使用的时候也是将一个维度的东西加装的另一个维度上去,搭建一个桥梁供另一个维度去使用。
至于怎么加载就无所谓了,可以在构造函数中指定,也可以在方法参数中传递。
总结:
将抽象部分与它的实现部分分离,使它们都可以独立地变化。
桥接模式的实现方式是通过在抽象类中持有一个指向实现类的引用,从而将抽象类与实现类解耦。
通常情况下,抽象类和实现类都需要定义自己的接口,以便彼此之间进行通信。