适配器模式 💣

2019-11-12  本文已影响0人  FredWhite

定义

把一个类的接口变换成客户端所期望的另一个接口,从而使因接口不匹配而无法在一起工作的两个类能够一起工作。

分类

使用场景

角色

将 Adaptee 的实现 包装成 Target 的实现 供 Client 调用

实现方式

此处不给示例代码。请参照 ListView 和 RecyclerView 的源码设计
类适配器模式

Adaptee

public class Banner {
    private String content;
    public Banner(String content) {
        this.content = content;
    }
    public void showWithParen() {
        System.out.println("(" + content + ")");
    }
    public void showWithAsterisk() {
        System.out.println("*" + content + "*");
    }
}

Target

public interface Print {
    public abstract void printWeak();    // 弱化()
    public abstract void printStrong();    // 强化 **
}

Adapter

public class PrintBanner extends Banner implements Print {
    public PrintBanner(String content) {
        super(content);
    }
    public void printWeak() {
        showWithParen();
    }

    public void printStrong() {
        showWithAsterisk();
    }
}

测试

public class AdapterTest {
    public static void main(String[] args) {
        Print p = new PrintBanner("hello");
        p.printWeak();
        p.printStrong();
    }
}

对象适配器模式
以上 Banner(Adaptee) 和 AdapterTest 的代码无需更改

Target

// 由于 Java 类不能多继承,只能单继承,所以 PrintBanner 无法同时继承 Print 和 Banner。
// 故只继承 Print(Target) 类,而【委托】Banner 来实现具体逻辑。
public abstract class Print {
    public abstract void printWeak();
    public abstract void printStrong();
}

Adapter

public class PrintBanner extends Print {
    private Banner banner;
    public PrintBanner(String content) {
        banner = new Banner(content);
    }

    @Override
    public void printWeak() {
        // Target 的 printWeak() 方法【委托】banner 的 showWithParen() 实现
        banner.showWithParen();
    }

    public void printStrong() {  
        // Target 的 printStrong() 方法【委托】banner 的 showWithAsterisk() 实现
        banner.showWithAsterisk();
    }
}

优缺点

优点

缺点

注意

版本升级与兼容性

可以通过 Adapter 模式使新旧版本兼容,帮助我们同时维护新版本和旧版本。

让新版本扮演 Adaptee(源) 角色,让旧版本扮演 Target(目标) 角色。再让新版本去实现旧版本的方法(Adaptee 通过 Adapter 来适配 Target),以此来达到新版本兼容旧版本的目的。

功能完全不同的类

当Adaptee 角色与 Target 角色的功能完全不同时,Adapter 模式是无法使用的。(就如同无法用 100V 交流电让自来水管出水一样)

建议

反复研读 ListView 和 RecyclerView 相关源码。

RecyclerView 与 ListView 的最大区别之一就是 将布局工作设置给了 LayoutManger,从而增强了系统的灵活性,降低了耦合度。可以灵活设置布局方式。

上一篇下一篇

猜你喜欢

热点阅读