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)中的情况又包装了几个类), 造成复杂度和开发时间的增加, 所以应__在抽象和速度之间折中__
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容