结构型模式之一——适配器模式

模式定义

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

模式结构

如下图为对象适配器模式结构图:
结构型模式之一——适配器模式_第1张图片

如下图为类适配器模式结构图:
结构型模式之一——适配器模式_第2张图片

1.Target
目标抽象类定义客户需要的特定领域的接口,可以是个抽象类或接口,也可以是具体类;在类适配器中,由于Java语句不支持多重继承,所以只能是接口

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

3.Adaptee
适配者即被适配的角色,它定义了一个已经存在的接口,这个接口需要适配,适配者类一般是一个具体类,包含了客户希望使用的业务方法,在某些情况下甚至没有适配者的源代码

实例——类适配器

现需要设计一个可以模拟各种动物行为的机器人,在机器人中定义了一系列方法,如机器人叫喊方法cry(),机器人移动方法move()等。如果希望在不修改已有代码的基础上使得机器人能够像狗一样叫,像狗一样跑。
现在使用类适配器模式实现该系统设计,类图如下所示:
结构型模式之一——适配器模式_第3张图片

public interface Robot {
    public void cry();
    public void move();
}

public class Dog {
    public void wang() {
        System.out.println("狗汪汪叫");
    }

    public void run() {
        System.out.println("狗快快跑");
    }
}

public class DogAdapter extends Dog implements Robot {
    public void cry() {
        System.out.println("机器人模仿:");
        super.wang();
    }

    public void move() {
        System.out.println("机器人模仿:");
        super.run();
    }
}

public class Client {
    public static void main() {
        Robot robot = new DogAdapter();

        robot.cry();
        robot.move();
    }
}

实例——对象适配器

某系统需要提供一个加密模块,将用户信息加密之后再存储在数据库中,系统已经定义好了数据库操作类。为了提高效率,现需要重用已有的加密算法,这些加密算法封装在一些由第三方提供的类中,有些甚至没有源代码。要求不修改现有类的基础上重用第三方加密算法。现使用对象适配器模式完成该系统设计。
类图如下所示:
结构型模式之一——适配器模式_第4张图片

public abstract class DataOperator {
    private String passWord;

    public void setPassword(String psd) {
        passWord = psd;
    }

    public String getPassword() {
        return passWord;
    }

    public abstract String doEncrypt(int key, String psd);
}

// Caesar类是一个由第三方提供的数据加密类,该类定义为final类,无法继承,因此本实例只能用对象适配器模
// 式完成。相传此加密算法由古罗马大地凯撒发明
public final class Caesar {
    public String doEncrypt(int key String psd) {
        String es = "";

        for (int i=0; ichar c = psd.charAt(i);
            if (c >= 'a' && c <= 'z') {
                c += key % 26;
                if (c > 'z') c -= 26;
                if (c < 'a') c += 26;
            }

            if (c >= 'A' && c <= 'Z') {
                c += key % 26;
                if (c > 'Z') c -= 26;
                if (c < 'A') c += 26;
            }

            es += c;
        }

        return es;
    }
}

public class CipherAdapter {
    private Caesar cipher;

    public CipherAdapter() {
        cipher = new Caesar();
    }

    public String doEncrypt(int key, String psd) {
        return cipher.doEncrypt(key, psd);
    }
}

public class Client {
    public static void main(String[] args) {
        DataOperator dao = new CipherAdapter();

        dao.setPassword("helloworld");
        String psd = dao.getPassword();
        String es = dao.doEncrypt(6, psd);
        System.out.println("明文为:" + psd);
        System.out.println("密文为:" + es);
    }
}

// 后面若有另一种加密方法NewCipher,可以在设计一个适配器来完成

扩展

  1. 默认适配器模式
    默认适配器模式是适配器模式的一种变形。
    默认适配器模式(Default Adapter Pattern):当不需要全部实现接口提供的方法时,可先设计一个抽象类实现该接口,并为接口中每个方法提供一个默认实现,那么该抽象类的子类可有选择地覆盖父类的某些方法实现需求,它适用于一个接口不想使用其所有的方法的情况。在默认适配器模式中,包含三个角色:适配者接口、默认适配器类和具体业务类。类图如下所示:
    结构型模式之一——适配器模式_第5张图片
    在JDK类库中的事件处理包java.awt.event中就广泛使用了默认适配器模式,如WindowAdapter、KeyAdapter、MouseAdapter等。
  2. 双向适配器
    在对象适配器的使用过程中,如果在适配器中同时含有对目标类和适配者类的引用,适配者可以通过它调用目标类中的方法,目标类也可以通过它调用适配者类中的方法,那么该适配器就是一个双向适配器,其结构示意如图:
    结构型模式之一——适配器模式_第6张图片

你可能感兴趣的:(DesignPatterns)