适配器和外观模式.

一、适配器模式

1、概念

  • 定义:将一个类的接口,转换成客户期望的另一个类的接口,适配器让原本接口不兼容的类可以合作无间。
  • 安卓转Type-C头,就是一个典型的适配器模式。在安卓头和 Type-C 之间引入适配器,安卓头是被适配者。
  • 解析:
      1、 客户(Client)通过目标接口(Target Interface)调用适配器(Adapter)的方法对适配器发出请求。
      2、 适配器使用被适配器接口(Adaptee Interface)把请求转换成被适配者的一个或多个调用接口。
      3、 客户接收到调用的结果,但并未察觉这一切是适配器在起转换作用。
  • 结构:适配器有两种,分别是类适配器和对象适配器。类适配器采用多重继承实现,在 Java 中不适用;对象适配器采用继承和组合实现。以下是两种结构的类图:

avatar

2、Demo 实现

 在 JDK1.0 时我们用的集合还是 Vector(后来推荐使用 ArrayList),我们用的迭代器还是 Enumeration(后来推荐使用 Iterator)。现在我们想写一个适配器,让 Vector 也能使用 Iterator 迭代器,即在 Enumeration 和 Iterator 之间做适配。

/**
 * 1、Iterator 是目标(Target)接口角色。
 * 2、Enumeration 是被适配者(Apaptee)角色。
 * 3、EnumerationAdapter 是适配者(Adapter)角色。
 */
public class EnumerationAdapter implements Iterator {

    private Enumeration enumeration;

    public EnumerationAdapter(Enumeration enumeration) {
        this.enumeration = enumeration;
    }

    @Override
    public boolean hasNext() {
        return enumeration.hasMoreElements();
    }

    @Override
    public Object next() {
        return enumeration.nextElement();
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("remove");
    }
}
    public static void main(String[] args) {
        Vector vector = new Vector();
        vector.add("java");
        vector.add("python");
        vector.add("javaScript");
        Enumeration enumeration = vector.elements();
        Iterator iterator = new EnumerationAdapter(enumeration);
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }

3、总结

  • 应用场景:系统需要使用一些现有的类,而这些类的接口不符合系统的需要,甚至没有这些类的源代码。
  • 优点:
      1、将接口转化成客户真正能接受的接口,为不用的接口之间做适配。
      2、客户和被适配者之间是解耦的。倘若一段时间之后,我们想要改变接口,适配器可以将改变的部分封装起来,而客户不用做任何的改变。另外,被适配者的任何子类,都可以搭配着适配器使用。
  • 缺点:
      1、一次最多只能适配一个适配者类,不能同时适配多个适配者。
      2、目标抽象类只能为接口,不能为类,其使用有一定的局限性。

二、外观模式

  • 外观(Facade)模式:提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。
  • 外观模式说是设计模式中最简单的模式也不为过,因为它没有那么多复杂的角色,它的工作只有一个 —— 简化接口。它可能持有一个或者数个类对象的组合,然后将它们复杂的一切(实现、执行顺序等)隐藏在身后,只露出一个干净美好的外观。
  • 外观模式不只是简化了接口,也将客户从组件的子系统中解耦。
  • 外观模式提供简化接口的同时,依然将系统完整的功能暴露出来,以供需要的人使用。

avatar

三、“最少知识”原则

@Data
public class Subject {
    private String name;
}
@Data
public class Teacher {
    private Subject subject;
}
public static void main(String[] args) {
    Teacher teacher = new Teacher();
    String name = teacher.getSubject().getName();
    System.out.println(name);
}

如上,我们常常这样写代码 —— teacher.getSubject().getName(),但是“最少知识”原则指导我们,应该减少对象间的间接交互:

@Data
public class Teacher {
    private Subject subject;

    public String getSubjectName() {
        return getSubject().getName();
    }
}
public static void main(String[] args) {
    Teacher teacher = new Teacher();
    String name = teacher.getSubjectName();
    System.out.println(name);
}

额,感觉略鸡肋的用法,但是“最少知识”原则可以减少我们所依赖的类的数目。还是那句话吧,原则只是指导,具体情况具体分析。

  • “最少知识”原则:减少对象之间的交互,只留下几个“密友”。这个原则提供了一些方针:就任何对象而言,在该对象的方法内,我们只应该调用属于以下范围的方法:
      1、该对象本身。
      2、被当做方法的参数而传递进来的对象。
      3、此方法所创建或实例化的任何对象。
      4、对象的任何组件。
  • 采用“最少知识”原则会导致更多的“包装”类被制造出来,以处理和其他组件的沟通,这可能会导致复杂度和开发时间的增加,并降低运行时的性能。
  • 所有的原则都应该在有帮助的时候才遵守。所有的设计都不免需要折衷(在抽象和速度之间取舍,在空间和时间之间平衡......)。
posted @ 2018-12-17 19:54  JMCui  阅读(549)  评论(0编辑  收藏  举报