2011年12月23日金曜日

[设计模式] 适配器模式 (Adapter)

1. 场景
需要要复用以前的 "现存对象", 但是这些对象所提供的接口并不一定能适应我们的新环境, 就要对其转换成我们需要的接口, 来供我们调用

2. 角色
Target: 客户端希望得到的接口 (接口, 具体类, 抽象类)
Adaptee: 现存并希望重复使用的需要适配的类 (接口, 具体类, 抽象类)
Adapter: 把源接口转换成目标接口 (类)

3. 分类
Adapter 实现了客户需要的 Target 接口, 因此他可以满足 Client 的需要, 同时它又重用的原有系统的 Adaptee 类
Java 中有两种方式可以达到重用的目的, 继承和包含
在适配器模式中也可以通过这两种方式达到重用 Adaptee类 的目的, 根据重用使用方式的不同一般将适配器模式分为两类

3-1. 类适配器 (Class Adapter)
适配器类实现 Target 接口
适配器类通过继承来实现对 Adaptee 类的重用 (高耦合不推荐使用)
采用“多继承”的实现方式,带来了不良的高耦合,所以一般不推荐使用。对象适配器采用“”的方式,更符合松耦合精神

3-2. 对象适配器 (Object Adapter)
适配器类实现 Target 接口
适配器类通过组合来实现对 Adaptee类 的重用 (对象组合低耦合推荐使用)

4. 实例
Client: CellPhone
Target: CellPhonePoweProvidable
Adaptee: CurrentPower
Adapter: CellPhoneAdapter1, CellPhoneAdapter2

/**
 * Adapee
 */
public class CurrentPower {
    public String getPower() {
        System.out.println("get current power 220V");
        return "220V";
    }
}

/**
 * Target
 */
public interface CellPhonePoweProvidable {
    String getCellPhonePower();
}

/**
 * Class Adapter
 */
public class CellPhoneAdapter1 extends CurrentPower implements CellPhonePoweProvidable {
    @Override
    public String getCellPhonePower() {
        String currentPower = super.getPower();
        System.out.println("change power from 220V to 5V");
        String cellPhonePower = currentPower.replaceAll("220", "5");
        return cellPhonePower;
    }
}

/**
 * Object Adapter
 */
public class CellPhoneAdapter2 implements CellPhonePoweProvidable {
    private CurrentPower currentPower = null;
    public CellPhoneAdapter2(CurrentPower currentPower) {
        this.currentPower = currentPower;
    }

    @Override
    public String getCellPhonePower() {
        String currentPower = this.currentPower.getPower();
        System.out.println("change power from 220V to 5V");
        String cellPhonePower = currentPower.replaceAll("220", "5");
        return cellPhonePower;
    }
}

/**
 * Client
 */
public class CellPhone {

    public static void main(String[] args) {
        CellPhone cellPhone = new CellPhone();

        //
        CellPhoneAdapter1 adpter1 = new CellPhoneAdapter1();
        cellPhone.charge(adpter1);

        System.out.println("------------------------------------------");

        //
        CellPhoneAdapter2 adpter2 = new CellPhoneAdapter2(new CurrentPower());
        cellPhone.charge(adpter2);
    }

    private void charge(CellPhonePoweProvidable adpter) {
        String power = adpter.getCellPhonePower();
        System.out.println("cellphone is charging to use " + power);
    }
}

0 件のコメント:

コメントを投稿