适配器模式的主要作用是将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些对象(类)可以一起工作。
UML示意图:
例如,鸭子有fly方法和quack(嘎嘎叫)方法,火鸡也有fly方法和gobble(咯咯叫)方法,如果希望火鸡有quack方法,可以复用鸭子的,但它的叫声应该是咯咯。可以创建一个火鸡适配器来实现,使得火鸡支持quack方法,但是在其内部还是调用gobble:
抽象构造函数:
var Duck = function(){}; Duck.prototype.fly = function(){ throw new Error("The method should be override!"); }; Duck.prototype.quack = function(){ throw new Error("The method should be override!"); }; var Turkey = function(){}; Turkey.prototype.fly = function(){ throw new Error(" The method should be override!"); }; Turkey.prototype.gobble = function(){ throw new Error(" The method should be override!"); };
构造函数:
var MallardDuck = function () { Duck.apply(this); }; MallardDuck.prototype = new Duck(); MallardDuck.prototype.fly = function () { console.log("It can fly a long way!"); }; MallardDuck.prototype.quack = function () { console.log("Quack!"); }; var WildTurkey = function () { Turkey.apply(this); }; WildTurkey.prototype = new Turkey(); WildTurkey.prototype.fly = function () { console.log("It can fly a short way!"); }; WildTurkey.prototype.gobble = function () { console.log("Gobble!"); };
创建一个火鸡适配器:
var TurkeyAdapter = function(oTurkey){ Duck.apply(this); this.oTurkey = oTurkey; }; TurkeyAdapter.prototype = new Duck(); TurkeyAdapter.prototype.quack = function(){ this.oTurkey.gobble(); }; TurkeyAdapter.prototype.fly = function(){ var nFly = 0; var nLenFly = 5; for(; nFly < nLenFly ; nFly++;){ this.oTurkey.fly(); } };
这个构造函数接收一个火鸡的实例,这个适配器的原型是Duck,然后重写了Duck的quack方法,在其内部调用了火鸡实例的gobble,也重写了fly方法,调用一下:
var oMallardDuck = new MallardDuck(); var oWildTurkey = new WildTurkey(); var oTurkeyAdapter = new TurkeyAdapter(oWildTurkey); oMallardDuck.fly(); oMallardDuck.quack(); oWildTurkey.fly(); oWildTurkey.gobble(); oTurkeyAdapter.fly(); oTurkeyAdapter.quack();
适配器模式的使用场景:
1.想要使用一个已经存在的对象,但其方法或属性不符合要求
2.想要创建一个可以复用的对象,可以与其他不相关对象协同工作
3.想使用已经存在的对象,但是不能对每一个都进行原型继承以匹配它的接口。对象适配器可以适配它的父对象接口方法或属性。