Skip to content

适配器模式

ZHI-XINHUA edited this page Jan 11, 2019 · 1 revision

适配器模式

适配器模式把一个类的接口交换成客户端期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。

1、类适配器

适配器继承被适配的类

类适配uml如下: image

涉及的角色:

  • 目标角色(Target):所期待得到的接口。特别注意的是,这里是类适配器模式,目标不可以是类。
  • 源角色(Adaptee):被适配的类。
  • 适配器角色(Adapter):适配器模式核心类。把源接口转换成目标接口。(继承被适配的类,实现目标接口。)

具体代码如下:

Target:

/**
 * 目标角色:所期待得到的接口。特别注意的是,这里是类适配器模式,目标不可以是类
 */
public interface Target {

    /**
     * 操作1
     */
    void operation1();

    /**
     * 操作2
     */
    void operation2();
}

Adaptee:

/**
 * 源角色:被适配的类
 */
public class Adaptee {

    /**
     * 操作1
     */
    public void operation1(){
        System.out.println("Adaptee operation1.....");
    }
}

Adapter:

/**
 * 适配器角色:适配器模式的核心。适配器把源接口转换成目标接口。所以,这是一个类,不可能是接口
 *
 * 类适配:继承被适配的类,实现目标接口
 */
public class Adapter extends Adaptee implements Target{
    @Override
    public void operation2() {
        System.out.println("适配的扩展方法:Adapter operation2......");
    }
}

2、对象适配器

与类适配器模式一样,对象的适配器模式把被适配的类的api转换成为目标类的api;与类适配器不同的是,对象适配器模式不是使用继承关系链接到源类(Adaptee),而是使用委派关系(即引用)关联源类(Adaptee)

对象适配的结构uml如下: image

涉及的角色:

  • 目标角色(Target):所期待得到的接口。特别注意的是,这里是类适配器模式,目标不可以是类。
  • 源角色(Adaptee):被适配的类。
  • 适配器角色(Adapter):适配器模式核心类。把源接口转换成目标接口。(引用被适配的类,实现目标接口。)

代码如下:

Target和Adaptee和上面类适配器一样,Adapter由继承Adaptee改为引用Adaptee。

Adapter:

/**
 * 适配器角色:适配器模式的核心。适配器把源接口转换成目标接口。所以,这是一个类,不可能是接口
 *
 * 对象适配:使用委派关系,即引用
 */
public class Adapter implements Target {
    //被适配类
    private Adaptee adaptee;


    public Adapter(Adaptee adaptee) {
        this.adaptee = adaptee;
    }

    @Override
    public void operation1() {
        adaptee.operation1();
    }

    @Override
    public void operation2() {
        System.out.println("适配的扩展方法:Adapter operation2......");
    }
}

3、缺省适配器

实现接口,不关心的方法不写业务逻(空着),实现所关系的接口方法。
缺省适配器模式为一个接口提供缺省实现,子类型可以冲这个缺省实现进行扩展,而不必要从原有接口扩展。

被适配接口(IBaseUserInfo):

/**
 *   源角色:被适配接口
 */
public interface IBaseUserInfo {

    /**
     * 获取用户名
     * @return
     */
    String getUserName();

    /**
     * 获取职位
     * @return
     */
    String  getJobPosition();

    /**
     * 获取手机号码
     * @return
     */
    String getTelNumber();

    /**
     * 获取办公室号码
     * @return
     */
    String getOfficeTelNumber();

    /**
     * 获取家庭号码
     * @return
     */
    String getHourseTelNumber();

    /**
     * 获取住址
     * @return
     */
    String getAddress();
}

缺省适配器(DefaultUserInfo):

/**
 * 缺省适配器角色:实现这个接口的子类,很可能出现很多方法是空着的情况
 * 因为之前接口设计的过大,导致接口中原本不该出现的方法出现了,结果现在子类根本用不上这个方法,
 * 但由于JAVA语言规则的原因,实现一个接口必须实现它的全部方法,所以我们的子类不得不被迫写一堆空方法在那,只为了编译通过。
 *
 * 所以我们只需实现我们关心的方法即可。
 */
public class DefaultUserInfo implements IBaseUserInfo{
    @Override
    public String getUserName() {
        System.out.println("我叫james");
        return "james";
    }

    @Override
    public String getJobPosition() {
        System.out.println("职位是高级总裁");
        return "高级总裁";
    }

    @Override
    public String getTelNumber() {
        return null;
    }

    @Override
    public String getOfficeTelNumber() {
        return null;
    }

    @Override
    public String getHourseTelNumber() {
        return null;
    }

    @Override
    public String getAddress() {
        return null;
    }
}

Clone this wiki locally