AS3笔记(11),适配器模式(Adapter Pattern)

注:本文为frank的学习笔记,转载请注明原文链接
更多笔记请参看:http://www.2solo.cn/log/article.asp?id=87

适配器模式属于Gof(Gang of four)在《设计模式》中提到的23种设计模式之一.

Adapter模式的概念
在大规模的系统开发过程中,我们常常碰到诸如以下这些情况:
我们需要实现某些功能,这些功能可以利用已有的一个或多个还不太成熟的组件或类,如果我们自己重新开发这些功能会花费大量时间;所以很多情况下会选择先暂时使用组件,以后再考虑随时替换。但这样一来,会带来一个问题,随着组件库的替换,可能需要对引用该组件的源代码进行大面积的修改,因此也极可能引入新的问题等等。如何最大限度的降低修改面呢?
Adapter模式就是针对这种类似需求而提出来的。
Adapter模式通过定义一个新的接口(对要实现的功能加以抽象),和一个实现该接口的Adapter(适配器)类来透明地调用外部组件。这样替换外部组件或改写类时,最多只要修改几个Adapter类就可以了,其他源代码都不会受到影响。
Gof在《设计模式》中提到了两种Adapter适配器模式,一种叫对象适配器模式,另一种叫类适配器模式。
*对象适配器模式提倡通过复合(Composition)来实现适配器模式
*类适配器模式提倡通过继承(Inheritance)来实现适配器模式

适配器模式中的有以下的四种角色:
  目标(target):定义客户端使用的与特定领域相关的接口。
  被适配者(adaptee):定义了一个已经存在的接口,这个接口需要匹配。
  适配器(adapter):对Adaptee的接口与target的接口进行适配。
  客户端(Client):与符合target接口的对象协同。
下面,我通过我的一个例子来解说这几个角色。见以下范例,(范例改编自《OReilly.ActionScript.3.0.Design.Patterns》一书)。
Adaptee.as

/*
被适配者类
*/

package {
    public class Adaptee {
        public function requestA():void {
            trace("Adaptee:requestA()");
        }
        public function requestB():void {
            trace("Adaptee:requestB()");
        }
        public function requestC():void {
            trace("Adaptee:requestC()");
        }
    }
}

AdapterA.as
/*
适配器A
*/

package {
    public class AdapterA extends Adaptee implements ITarget {
        public function renamedRequestA():void {
            this.requestA();
        }
        override public function requestB():void {
            trace("AdapterA:requestB()");
        }
        public function requestD():void {
            trace("AdapterA:requestD()");
        }
    }
}

AdapterB.as
/*
适配器B
*/

package {
    public class AdapterB implements ITarget {
        private var adaptee
        public function AdapterB() {
             adaptee=new Adaptee();
        }
        public function renamedRequestA():void {
            adaptee.requestA()
        }
        public function requestA():void {
            trace("AdapterB:requestA()");
        }
        public function requestB():void {
            trace("AdapterB:requestB()");
        }
        public function requestC():void {
            adaptee.requestC();
        }
        public function requestD():void {
            trace("AdapterB:requestD()");
        }
    }
}

ITarget.as
/*
定义接口
*/

package {
    public interface ITarget {
        function renamedRequestA():void;
        function requestA():void;
        function requestB():void;
        function requestC():void;
        function requestD():void;
    }
}

Main.as
/*@
Author:frank
Site:www.2solo.cn
Date:2008.02.11
Info:适配器模式
*/

package {
    import flash.display.MovieClip;
    /**
    *文档类
    */

    public class Main extends MovieClip {
        public function Main() {
            var target:ITarget=new AdapterA();////切换到类适配器模式
            //var target:ITarget=new AdapterB();//切换到对象适配器模式
            target.renamedRequestA();
            target.requestA();
            target.requestB();
            target.requestC();
            target.requestD();
        }
    }
}


UML图例:

如上范例中,ITarget即为接口,Main为文档类即客户端,Adaptee为被适配者,AdapterA和AdapterB为适配器.其中,AdapterA是以类适配器模式实现的,AdapterB是以对象适配器模式实现的。综合在开发中复合多与继承的情况,对象适配器模式比较易用一些,至于使用复合多与继承的的原因,我准备在以后的blog中讨论这个问题。

附上范例源文件:http://www.2solo.cn/upload/adapter1_2soloDOTcn.zip



[本日志由 frank 于 2008-02-18 11:57 PM 编辑]
文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags: 设计模式 AS3笔记 as3.0
评论: 0 | 引用: 0 | 查看次数: 3448
发表评论
昵 称:
密 码: 游客发言不需要密码.
内 容:
验证码: 验证码
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.
字数限制 1000 字 | UBB代码 开启 | [img]标签 关闭