Adapter模式-适配器模式

作者: ldsea 分类: 程序生活 发布时间: 2008-06-17 21:09

转自:[url=http://hi.baidu.com/erik168/blog/item/cf50cfa1271e208f47106400.html]http://hi.baidu.com/erik168/blog/item/cf50cfa1271e208f47106400.html[/url]
本来想闲几天,又担心懈怠而放下,所以,还是接着写吧。
第一个结构型模式,就写简单点的,Adapter模式好了
顾名思义,Adapter就是适配器的意思。
如果你在中国买了个笔记本电脑,然后你现在要去美国,美国那边电源插口和中国肯定是不一样的,你要买个转接头把三角的插头转成前面圆形后面两个扁型的那种美式插头,这就是适配器。

[color=#0000FF]Adapter模式的用处是[/color]:将一个类的接口转换成客户希望的另外一个接口。
Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

[color=#0000FF]Adapter分为2种[/color]:类适配器和对象适配器。Adapter和Adaptee之间是is-a关系的时候,属于类适配器,Adapter和Adaptee之间是has-a关系的时候,属于对象适配器。
下面这句话是我在网上看到的,可以作为设计适配器时候的指导:
基于“当涉及到依存性时,应当始终优先选择组合/成员关系而不是继承”的设计原则(),并且由于多继承在使用上的复杂性,及在部分情况下不可行等原因,Object Adapter的运用显得更加广泛。

下面分别是类适配器和对象适配器的[color=#0000FF]类图[/color]:
[img][attach]72[/attach][/img]
[img][attach]73[/attach][/img]

[color=#0000FF]那我们应该什么时候使用Adapter模式呢?[/color]

关于Adapter模式应用场景的描述,我觉得下面这几句话讲的比较通俗易懂
Adapter模式可应用于如下的情况:
1、系统需要使用现有的类,而此类的接口不符合系统的需要。
2、想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作,这些源类不一定有与一致的接口。这种情况从不同的角度考虑,可能被划入Facade模式的范畴,但从与现有设计适配的角度考虑该问题,则将其划归Adapter模式也是可以理解的。
3、通过接口转换,将一个类插入另一个类系中。有人举过这样一个例子:虎与飞禽是没有直接关联的两类动物,但是现在出来了个“飞虎”,它同时具有虎肉食动物跟飞禽会飞的特质,要在飞禽这个类系中添加一个成员类“飞虎”,除了直接实现“飞虎”类,还有一种简单的办法是实现一个Adapter类,在其中包容一个虎的对象,同时实现飞禽的接口即可。当然,对于这个问题,多继承或者实现多接口可能是一个更直观的作法,在实际应用中,可视具体需要确定采用何种作法。

[color=#0000FF]代码范例:[/color]

[code]
//注:代码实现了对象适配器和类适配器,两种适配器代码都已经注释掉,需要删除其中一个适配器的注释,才能运行
//本例中,我们可以把NumMessage类的接口改成我们需要的,但这不是我们的目的。
//当我们遇到没有办法修改类接口的时候(也许不是我们开发的代码,我们不敢随意改动;也许使用的地方太多,会牵扯到整个系统的变动,当前我们无法更改),我们就需要适配器.

function NumMessage(msg) {
    this.msg = msg;
}
NumMessage.prototype.getMessageString = function () {
    return '<font color="blue">' + this.msg + '</font>';
}

function TextMessage(msg) {
    this.msg = msg;
}
TextMessage.prototype.getHTML = function () {
    return '<font color="red">' + this.msg + '</font>';
}

var MessageList = {
    container: [],
    add: function (msg) {
        this.container.push(msg);
    },
    render: function () {
        for (var i = 0, l = this.container.length; i < l; i++) {
            document.write(this.container[i].getHTML() + '<br>');
        }
    }
}

/* 这一部分注释掉的代码是对象适配器的代码
function NumMessageAdapter(msg){
    this.msg = new NumMessage(msg);
}
NumMessageAdapter.prototype.getHTML = function () {
    return this.msg.getMessageString();
}
*/

/* 这一部分注释掉的代码是类适配器的代码
function NumMessageAdapter(msg){
    this.base = NumMessage;
    this.base(msg);
}
NumMessageAdapter.prototype = new NumMessage();
NumMessageAdapter.prototype.getHTML = function () {
    return this.getMessageString();
}
*/

MessageList.add(new TextMessage('This is a text message'));
MessageList.add(new NumMessageAdapter('1234567message'));
MessageList.render();[/code]

发表回复

您的电子邮箱地址不会被公开。