桥接模式(Bridge),将抽象部分与它的实现部分分离,使它们都可以独立地变化。
抽象化和实现部分在一起,桥接模式的目的就是使两者分离,根据面向对象的封装变化的原则,我们可以把实现部分的变化封装到另外一个类中,这样的一个思路也就是桥接模式的实现,大家可以对照桥接模式的实现代码来解决我们的分析思路。
为了帮助大家理清对桥接模式中类之间关系,这里给出桥接模式的类图结构:
我们再来看看桥接模式的使用场景,在以下情况下应当使用桥接模式:
- 如果一个系统需要在构件的抽象化角色和具体化角色之间添加更多的灵活性,避免在两个层次之间建立静态的联系。
- 设计要求实现化角色的任何改变不应当影响客户端,或者实现化角色的改变对客户端是完全透明的。
- 需要跨越多个平台的图形和窗口系统上。
- 一个类存在两个独立变化的维度,且两个维度都需要进行扩展。
C#桥接模式:
namespace 桥接模式 { class Program { static void Main(string[] args) { HandsetBrand ab; ab = new HandsetBrandN(); ab.SetHandsetSoft(new HandsetGame()); ab.Run(); ab.SetHandsetSoft(new HandsetAddressList()); ab.Run(); ab = new HandsetBrandM(); ab.SetHandsetSoft(new HandsetGame()); ab.Run(); ab.SetHandsetSoft(new HandsetAddressList()); ab.Run(); Console.Read(); } } //手机品牌 abstract class HandsetBrand { protected HandsetSoft soft; //设置手机软件 public void SetHandsetSoft(HandsetSoft soft) { this.soft = soft; } //运行 public abstract void Run(); } //手机品牌N class HandsetBrandN : HandsetBrand { public override void Run() { soft.Run(); } } //手机品牌M class HandsetBrandM : HandsetBrand { public override void Run() { soft.Run(); } } //手机品牌S class HandsetBrandS : HandsetBrand { public override void Run() { soft.Run(); } } //手机软件 abstract class HandsetSoft { public abstract void Run(); } //手机游戏 class HandsetGame : HandsetSoft { public override void Run() { Console.WriteLine("运行手机游戏"); } } //手机通讯录 class HandsetAddressList : HandsetSoft { public override void Run() { Console.WriteLine("运行手机通讯录"); } } //手机MP3播放 class HandsetMP3 : HandsetSoft { public override void Run() { Console.WriteLine("运行手机MP3播放"); } } }
js模拟高级语言的桥接模式:
//手机品牌 var HandsetBrand = function(){ this.soft = null; }; //设置手机软件 HandsetBrand.prototype.setHandsetSoft = function(soft){ this.soft = soft; }; //运行 HandsetBrand.prototype.run = function(){ throw new Error('具体实现必须由子类重写'); }; //手机品牌N var HandsetBrandN = function(){}; HandsetBrandN.prototype = new HandsetBrand(); HandsetBrandN.prototype.run = function(){ this.soft.run(); }; //手机品牌M var HandsetBrandM = function(){}; HandsetBrandM.prototype = new HandsetBrand(); HandsetBrandM.prototype.run = function(){ this.soft.run(); }; //手机品牌S var HandsetBrandS = function(){}; HandsetBrandS.prototype = new HandsetBrand(); HandsetBrandS.prototype.run = function(){ this.soft.run(); }; //手机软件 var HandsetSoft = function(){}; HandsetSoft.prototype.run = function(){ throw new Error('具体实现必须由子类重写'); }; //手机游戏 var HandsetGame = function(){}; HandsetGame.prototype = new HandsetSoft(); HandsetGame.prototype.run = function(){ console.log('运行手机游戏'); }; //手机通讯录 var HandsetAddressList = function(){}; HandsetAddressList.prototype = new HandsetSoft(); HandsetAddressList.prototype.run = function(){ console.log('运行手机通讯录'); }; //手机MP3播放 var HandsetMP3 = function(){}; HandsetMP3.prototype = new HandsetSoft(); HandsetMP3.prototype.run = function(){ console.log('运行手机MP3播放'); }; //调用: // var ab = new HandsetBrandN(); ab.setHandsetSoft(new HandsetGame()); ab.run(); ab.setHandsetSoft(new HandsetAddressList()); ab.run(); ab = new HandsetBrandM(); ab.setHandsetSoft(new HandsetGame()); ab.run(); ab.setHandsetSoft(new HandsetAddressList()); ab.run();
js语言特性的桥接模式:
//手机软件 var handsetSoft = {}; //手机品牌 var HandsetBrand = function(type){ this.soft = null; this.type = type; }; HandsetBrand.prototype = { //修正构造函数指向 constructor:HandsetBrand, //设置手机软件 setHandsetSoft:function(soft){ this.soft = soft; }, //运行 run:function(){ this[type] && this[type](); } }; //手机游戏 handsetSoft.game = function(){ console.log('运行手机游戏'); }; //手机通讯录 handsetSoft.addressList = function(){ console.log('运行手机通讯录'); }; //手机MP3播放 handsetSoft.mp3 = function(){ console.log('运行手机MP3播放'); }; //手机品牌N 手机品牌M 手机品牌S ['brandN','brandM','brandS'].forEach(function(prop){ HandsetBrand.prototype[prop] = function(){ this.soft && this.soft(); }; }); //调用: // var hb = new HandsetBrand('brandN'); hb.setHandsetSoft(handsetSoft.game); hb.run(); hb.setHandsetSoft(handsetSoft.addressList); hb.run(); hb = new HandsetBrand('brandM'); hb.setHandsetSoft(handsetSoft.game); hb.run(); hb.setHandsetSoft(handsetSoft.addressList); hb.run();