Collin Nam


设计模式之-适配器模式

Frank 2019-07-16 1277浏览 1条评论
首页/ 正文
分享到: / / / /

结构型模式概述

     结构型模式是描述如何将类对象结合在一起,形成一个更大的结构,结构模式描述两种不同的东西:类与类的实例。故可以分为类结构模式和对象结构模式。

适配器模式概述

     适配器模式(Adapter Pattern):将一个接口转换成客户希望的另一个接口,使接口不兼容的那 些类可以一起工作,其别名为包装器(Wrapper)。适配器模式既可以作为类结构型模式,也可 以作为对象结构型模式。

 

类结构型模式

     关心类的组合,由多个类组合成一个更大的系统,在类结构型模式中一般只存在继承关系和实现关系

对象结构型模式

     关心类与对象的组合,通过关联关系,在一个类中定义另一个类的实例对象,然后通过该对象调用相应的方法

适配器模式的结构与实现

在对象适配器模式结构图中包含如下几个角色:

● Target(目标抽象类):目标抽象类定义客户所需接口,可以是一个抽象类或接口,也可以 是具体类。

● Adapter(适配器类):适配器可以调用另一个接口,作为一个转换器,对Adaptee和Target进 行适配,适配器类是适配器模式的核心,在对象适配器中,它通过继承Target并关联一个 Adaptee对象使二者产生联系。

● Adaptee(适配者类):适配者即被适配的角色,它定义了一个已经存在的接口,这个接口 需要适配,适配者类一般是一个具体类,包含了客户希望使用的业务方法,在某些情况下可 能没有适配者类的源代码。 根据对象适配器模式结构图,在对象适配器中,客户端需要调用request()方法,而适配者类 Adaptee没有该方法,但是它所提供的specificRequest()方法却是客户端所需要的。

为了使客户 端能够使用适配者类,需要提供一个包装类Adapter,即适配器类。这个包装类包装了一个适 配者的实例,从而将客户端与适配者衔接起来,在适配器的request()方法中调用适配者的 specificRequest()方法。因为适配器类与适配者类是关联关系(也可称之为委派关系),所以 这种适配器模式称为对象适配器模式。典型的对象适配器代码如下所示:

class Adapter extends Target {
private Adaptee adaptee; //维持一个对适配者对象的引用
public Adapter(Adaptee adaptee) {
this.adaptee=adaptee;
}
public void request() {
adaptee.specificRequest(); //转发调用
}
}

 

 

  • 适配器模式的结构 适配器模式包含以下3个角色:
  • Target(目标抽象类)
  • Adapter(适配器类)
  • Adaptee(适配者类)
     

 

适配器模式的实现 典型的类适配器代码:

public class Adapter extends Adaptee implements Target {
    public void request() {
        super.specificRequest();
    }
}

适配器模式的实现 典型的对象适配器代码 

public class Adapter extends Target {
    private Adaptee adaptee; //维持一个对适配者对象的引用
	
    public Adapter(Adaptee adaptee) {
        this.adaptee=adaptee;
    }
	
    public void request() {
        adaptee.specificRequest(); //转发调用
    }
}

 

适配器模式的应用实例

     某公司欲开发一款儿童玩具汽车,为了更好地吸引小朋友的注意力,该玩具汽车在移动过程中伴随着灯光闪烁和声音提示。在该公司以往的产品中已经实现了控制灯光闪烁(例如警灯闪烁)和声音提示(例如警笛音效)的程序,为了重用先前的代码并且使得汽车控制软件具有更好的灵活性和扩展性,现使用适配器模式设计该玩具汽车控制软件。

 

 

实例代码

(1) CarController:汽车控制类,充当目标抽象类

package designpatterns.adapter;

/**
 * 汽车控制类 充当目标抽象类
 *
 * @Author Frank
 * @Description
 * @Date: Create in  2019-07-16 10:52
 */
public abstract class CarController {
    public void move() {
        System.out.println("玩具汽车移动");
    }

    //发出声音
    public abstract void phonate();

    //灯光闪烁
    public abstract void twinkle();
}

(2) PoliceSound:警笛类,充当适配者

package designpatterns.adapter;

/**
 *  警笛类  充当适配者
 * @Author Frank
 * @Description
 * @Date: Create in  2019-07-16 10:48
 */
public class PoliceSound {
    public void sound(){
        System.out.println("发出警笛声音");
    }
}

(3) PoliceLamp:警灯类,充当适配者

package designpatterns.adapter;

/**
 * 警灯类  充当适配者
 *
 * @Author Frank
 * @Description
 * @Date: Create in  2019-07-16 10:49
 */
public class PoliceLamp {
    public void twinkle() {
        System.out.println("呈现警灯闪烁");
    }
}

(4) PoliceCarAdapter:警车适配器,充当适配器

package designpatterns.adapter;

/**
 * @Author Frank
 * @Description
 * @Date: Create in  2019-07-16 10:55
 */
public class PoliceCarAdapter extends CarController {

    private PoliceSound policeSound;
    private PoliceLamp policeLamp;

    public PoliceCarAdapter() {
        policeSound = new PoliceSound();
        policeLamp = new PoliceLamp();
    }

    @Override
    public void phonate() {
        policeSound.sound();
    }

    @Override
    public void twinkle() {
        policeLamp.twinkle();
    }
}

(5) Client:客户端测试类

package designpatterns.adapter;

/**
 * @Author Frank
 * @Description
 * @Date: Create in  2019-07-16 11:00
 */
public class PoliceClient {
    public static void main(String[] args) {
        CarController carController=new PoliceCarAdapter();
        carController.move();
        carController.twinkle();
        carController.phonate();
    }
}

 

 

缺省适配器模式定义

     缺省适配器模式(Default Adapter Pattern):当不需要实现一个接口所提供的所有方法时,可先设计一个抽象类实现该接口,并为接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可以选择性地覆盖父类的某些方法来实现需求,它适用于不想使用一个接口中的所有方法的情况,又称为单接口适配器模式

 


 

缺省适配器类的典型代码片段:

public abstract class AbstractServiceClass implements ServiceInterface {
public void serviceMethod1() {  }  //空方法
public void serviceMethod2() {  }  //空方法
public void serviceMethod3() {  }  //空方法
}

 

 

 

双向适配器

public class Adapter implements Target,Adaptee {
    private Target target;
    private Adaptee adaptee;
	
    public Adapter(Target target) {
        this.target = target;
    }
	
    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }
	
    public void request() {
        adaptee.specificRequest();
    }
	
    public void specificRequest() {
        target.request();
    }
}

 

适配器模式的优缺点与适用环境

模式优点

     将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,无须修改原有结构 增加了类的透明性和复用性,提高了适配者的复用性,同一个适配者类可以在多个不同的系统中复用 灵活性和扩展性非常好 类适配器模式:置换一些适配者的方法很方便 对象适配器模式:可以把多个不同的适配者适配到同一个目标,还可以适配一个适配者的子类

 

模式缺点

     类适配器模式:(1) 一次最多只能适配一个适配者类,不能同时适配多个适配者;(2) 适配者类不能为最终类;(3) 目标抽象类只能为接口,不能为类 对象适配器模式:在适配器中置换适配者类的某些方法比较麻烦

 

模式适用环境

     系统需要使用一些现有的类,而这些类的接口不符合系统的需要,甚至没有这些类的源代码 创建一个可以重复使用的类,用于和一些彼此之间没有太大关联的类,包括一些可能在将来引进的类一起工作

最后修改:2019-07-16 10:03:45 © 著作权归作者所有
如果觉得我的文章对你有用,请随意赞赏
扫一扫支付

上一篇

发表评论

说点什么吧~

评论列表

จุ๊บLFrank 2019-07-16 10:17:05
[蛋糕]
回复