• 为什么要使用Adapter模式?

    很多时候编程会用到现有的类。特别是现有的类已经被上线或者充分测试过了。而且已经用于其它软件当中了。这个时候我们很愿意将其当做一些组件来使用进行重复利用。这个时候如果出现bug,我们可以很清楚的知道这个bug是在代理类里面。更加方便的排查bug。

    • 如果没有现成的代码应该怎么办呢?

    让现有的类适配新的接口(API),使用Adapter模式似乎是理所当然的。不过实际上,我们在让现有的类适配新的接口时,常常会有“只要将这里稍微修改一下就可以了”。一不留神就会修改到现有的代码。而且还需要在上线前对之前测试完毕,非常的恶心。

    • 软件升级与兼容性:

    软件的生命周期总是伴随着版本的升级,而在版本升级的时候经常会出现“与旧版本的兼容性问题”。如果能完全抛弃就版本,那么软件的维护工作会很轻松。但是现实不允许我们这么做。这个时候我们就可以选择Adapter模式来兼容新旧版本。这个时候让新版本来扮演Adaptee,旧版本扮演Target。接着编写另一个扮演Adapter的角色,让它来使用新版本中的类来实现旧版本类中的方法。

    • Adapter中登场角色:
      • Target(对象):该角色负责定义所需的方法。12伏特电源
      • Client(请求者):负责使用Target角色所定义的方法进行具体处理。笔记本电脑
      • Adaptee(被适配):被适配的持有既定方法的角色。120伏特电源
      • Adapter(适配器):将120伏特电压转换到12伏特电压的适配器。Adapter模式的主人公

    适配器魔术 - 图1

    • 相关的设计模式:
      • Bridge模式:Adapter模式用于连接(API)不同的类,而Bridge模式则用于连接类的功能层次结构与实现层次结构。
      • Decorator:Adapter模式用于填补不同接口(API)之间的缝隙。而Decorator模式则是在不改变接口(API)的前提下增加功能。
    • 为什么在Client(请求者)中尽量使用Target来存储对象,而不是使用Adaptee(适配) 呢?

    因为正常来说Adaptee类中的方法可能会比Client中多。通过将对象保存在Client中,可以明确地表明程序的意图。我们需要使用的Client中的方法。

    • 代码实例:

    Adaptee(被适配):

    1. public class Banner {
    2. private String string;
    3. public Banner(String string) {
    4. this.string = string;
    5. }
    6. public void showWithParen() {
    7. System.out.println("<"+string+">");
    8. }
    9. public void showWithAster() {
    10. System.out.println("*"+string+"*");
    11. }
    12. }

    Target(对象):

    1. public interface Print {
    2. public abstract void printWeak();
    3. public abstract void printStrong();
    4. }

    Adapter(适配):

    1. public class PrintBanner extends Banner implements Print{
    2. public PrintBanner(String string) {
    3. super(string);
    4. }
    5. @Override
    6. public void printWeak() {
    7. showWithParen();
    8. }
    9. @Override
    10. public void printStrong() {
    11. showWithAster();
    12. }
    13. }

    Client(请求者):

    1. public class PrintBanner extends Banner implements Print{
    2. public PrintBanner(String string) {
    3. super(string);
    4. }
    5. @Override
    6. public void printWeak() {
    7. showWithParen();
    8. }
    9. @Override
    10. public void printStrong() {
    11. showWithAster();
    12. }
    13. }