桥接模式的概念
定义:将抽象部分与实现部分分离,使它们都可以独立的变化。
理解:为啦解决一个对象变化而影响多个对象跟着变化,需要把具体实现对象抽象化,使降低对象和变化因素的耦合度,提高系统的可维护性和扩展性。
举例:
手机系统的生态圈问题:
啰嗦点:众所周知wp的生态圈相对与有些系统较差,各位需努力,诺基亚走下神坛,wp要走上神坛,顶一下哈。
wp/ios系统类:运行软件,可承载本运行环境下的任何软件,如果新增一个系统,软件就要多做一个系统的版本
weixin/kuwo软件类:开始运行软件,如果新加一块软件,就要做众多系统版本的。
实现:在iso和wp系统中运行,各种不同的软件。
类图:
下面我们来根据具体的代码了解桥接模式。
软件代码:
//软件 public interface ISoftWare { void start(); } //Kuwo public class Kuwo : ISoftWare { public void start() { Console.WriteLine("听音乐,用酷我!"); } } //WeiXin public class WeiXin : ISoftWare { public void start() { Console.WriteLine("让你我的距离更近!"); } }
操作系统代码
//操作系统,跑软件 public abstract class System { public abstract void Run(ISoftWare software); } //Wp public class WinPhone : System { public override void Run(ISoftWare software) { Console.WriteLine("Winphone系统,给你想要的;"); software.start(); } } //Ios public class Ios : System { public override void Run(ISoftWare software) { Console.WriteLine("Ios系统,给你想不到的;"); software.start(); } }
客户端代码
public static void Main() { ISoftWare weixin = new WeiXin(); ISoftWare kuwo = new Kuwo(); //Wp系统 System WpSys = new WinPhone(); WpSys.Run(weixin); WpSys.Run(kuwo); //IOS系统 System IosSys = new Ios(); IosSys.Run(weixin); IosSys.Run(kuwo); Console.Read(); }
桥接模式的优缺点
介绍完桥接模式,让我们看看桥接模式具体哪些优缺点。
优点:
- 把抽象接口与其实现解耦。
- 抽象和实现可以独立扩展,不会影响到对方。
- 实现细节对客户透明,对用于隐藏了具体实现细节。
缺点: 增加了系统的复杂度
使用场景
我们再来看看桥接模式的使用场景,在以下情况下应当使用桥接模式:
如果一个系统需要在构件的抽象化角色和具体化角色之间添加更多的灵活性,避免在两个层次之间建立静态的联系。
设计要求实现化角色的任何改变不应当影响客户端,或者实现化角色的改变对客户端是完全透明的。
需要跨越多个平台的图形和窗口系统上。
一个类存在两个独立变化的维度,且两个维度都需要进行扩展。
一个实际应用桥接模式的例子
桥接模式也经常用于具体的系统开发中,对于三层架构中就应用了桥接模式,三层架构中的业务逻辑层BLL中通过桥接模式与数据操作层解耦(DAL),其实现方式就是在BLL层中引用了DAL层中一个引用。这样数据操作的实现可以在不改变客户端代码的情况下动态进行更换,下面看一个简单的示例代码:
// 客户端调用 // 类似Web应用程序 class Client { static void Main(string[] args) { BusinessObject customers = new CustomersBusinessObject("ShangHai"); customers.Dataacces = new CustomersDataAccess(); customers.Add("小六"); Console.WriteLine("增加了一位成员的结果:"); customers.ShowAll(); customers.Delete("王五"); Console.WriteLine("删除了一位成员的结果:"); customers.ShowAll(); Console.WriteLine("更新了一位成员的结果:"); customers.Update("Learning_Hard"); customers.ShowAll(); Console.Read(); } } // BLL 层 public class BusinessObject { // 字段 private DataAccess dataacess; private string city; public BusinessObject(string city) { this.city = city; } // 属性 public DataAccess Dataacces { get { return dataacess; } set { dataacess = value; } } // 方法 public virtual void Add(string name) { Dataacces.AddRecord(name); } public virtual void Delete(string name) { Dataacces.DeleteRecord(name); } public virtual void Update(string name) { Dataacces.UpdateRecord(name); } public virtual string Get(int index) { return Dataacces.GetRecord(index); } public virtual void ShowAll() { Console.WriteLine(); Console.WriteLine("{0}的顾客有:", city); Dataacces.ShowAllRecords(); } } public class CustomersBusinessObject : BusinessObject { public CustomersBusinessObject(string city) : base(city) { } // 重写方法 public override void ShowAll() { Console.WriteLine("------------------------"); base.ShowAll(); Console.WriteLine("------------------------"); } } /// <summary> /// 相当于三层架构中数据访问层(DAL) /// </summary> public abstract class DataAccess { // 对记录的增删改查操作 public abstract void AddRecord(string name); public abstract void DeleteRecord(string name); public abstract void UpdateRecord(string name); public abstract string GetRecord(int index); public abstract void ShowAllRecords(); } public class CustomersDataAccess:DataAccess { // 字段 private List<string> customers =new List<string>(); public CustomersDataAccess() { // 实际业务中从数据库中读取数据再填充列表 customers.Add("Learning Hard"); customers.Add("张三"); customers.Add("李四"); customers.Add("王五"); } // 重写方法 public override void AddRecord(string name) { customers.Add(name); } public override void DeleteRecord(string name) { customers.Remove(name); } public override void UpdateRecord(string updatename) { customers[0] = updatename; } public override string GetRecord(int index) { return customers[index]; } public override void ShowAllRecords() { foreach (string name in customers) { Console.WriteLine(" " + name); } } }