chapter07_随遇而安——适配器模式和外观模式

  • (1) 适配器的__作用__

    将一个接口转换成另一个接口

    (2) 使用适配器的过程

    1° 客户通过目标接口调用适配器的方法

    2° 适配器使用 被适配者 的接口, 将请求转换成被适配器的一个或多个调用接口

    实现了调用者和被适配者的解耦

    (3) 示例

    Duck.java

      public interface Duck {
    
          void quack();
    
          void fly();
      }
    

    Turkey.java

      public interface Turkey {
    
          void gobble();
    
          void fly();
      }
    

    TurkeyAdapter.java

      public class TurkeyAdapter implements Duck {
    
          private Turkey turkey;
    
          public TurkeyAdapter(Turkey turkey) {
    
              this.turkey = turkey;
          }
    
          public void quack() {
    
              turkey.gobble();
          }
    
          public void fly() {
    
              for (int i = 0; i < 5; i++) {
                  turkey.fly();
              }
          }
      }
    

    Turkey和Duck是两个不同的接口, TurkeyAdapter构造器注入一个turkey对象, 将Duck的行为映射成内部turkey对象的行为

  • 适配器模式

    将一个类的接口, 转换成客户期望的另一个接口, 适配器让原本接口不兼容的类可以合作无间

  • 适配器的实际应用例子

    以前的Enumeration接口转换为现在的Iterator接口

      public class EnumerationIterator implements Iterator<Object> {
    
          private Enumeration<?> enumeration;
    
          public EnumerationIterator(Enumeration<?> enumeration) {
    
              this.enumeration = enumeration;
          }
    
          public boolean hasNext() {
    
              return enumeration.hasMoreElements();
          }
    
          public Object next() {
      
              return enumeration.nextElement();
          }
    
          public void remove() {
      
              throw new UnsupportedOperationException();
          }
      }
    

    EnumerationIterator内部包含一个Enumeration对象, 将hasNext和next方法委托之;

    由于Enumeration是一个只读接口, 所以调用remove()时抛出UnsupportedOperationException异常

  • 装饰器模式和适配器模式的对比

    装饰器模式不会改变接口, 它的目标是将新的行为添加到类中;

    适配器模式的作用是改变接口类型

  • (1) 外观模式

    实现一个提供更合理的接口的外观类, 从而将一个复杂的子系统变得容易使用

    (2) 外观模式可以理解为

    一个适配器包装多个被适配者

    (3) 示例

    HomeTheaterFacade.java

      public class HomeTheaterFacade {
    
          private Amplifier amp;
          private Tuner tuner;
          private DvdPlayer dvd;
          private CdPlayer cd;
          private Projector projector;
          private TheaterLights lights;
          private Screen screen;
          private PopcornPopper popper;
    
          public HomeTheaterFacade(
              Amplifier amp, Tuner tuner,
              DvdPlayer dvd, CdPlayer cd,
              Projector projector, Screen screen,
              TheaterLights lights, PopcornPopper popper) {
    
              this.amp = amp;
              this.tuner = tuner;
              this.dvd = dvd;
              this.cd = cd;
              this.projector = projector;
              this.screen = screen;
              this.lights = lights;
              this.popper = popper;
          }
    
          public void watchMovie(String movie) {
    
              System.out.println("Get ready to watch a movie...");
    
              popper.on();
              popper.pop();
              lights.dim(10);
              screen.down();
              projector.on();
              projector.wideScreenMode();
              amp.on();
              amp.setDvd(dvd);
              amp.setSurroundSound();
              amp.setVolume(5);
              dvd.on();
              dvd.play(movie);
          }
    
          ...
      }
    

    Amplifier, Tuner, DvdPlayer等都是内部的被适配者, watchMovie有着复杂的流程, 需要各个子系统协同操作;

    HomeTheaterFacade提供了统一的接口方法watchMovie(), 使得函数调用更加友好

    (4) 外观模式使得客户实现从任何子系统中解耦

  • 外观模式和适配器模式的区别

    意图不同!!!

    适配器模式的意图是__改变接口以迎合客户的需求__;

    外观模式的意图是__简化接口__

  • 外观模式

    提供了一个统一的接口, 用来访问子系统中的一群接口。外观模式定义了一组__高层接口__, 让子系统更容易使用

  • (1) 设计原则: 最少知识原则

    减少对象之间的交互, 只留下几个"密友"对象, 不要让太多的类耦合在一起

    (2) 具体操作方针

    在某个对象的方法内, 我们只应该调用属于以下范围的方法:

    1° 对象本身的方法

    2° 被当作输入参数传进来的对象的方法

    3° 方法内部创建的对象的方法

    4° 对象的内部组件的方法

    也就是说, 尽量不要在某个方法中出现

      this.inner.getA().getX()
    

    这种链式调用

    (3) 完全遵循"最少知识原则"很可能会导致过度封装(为了防止出现(2)中的情况又包装了几个类), 造成复杂度和开发时间的增加, 所以应__在抽象和速度之间折中__

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值