美文网首页
chapter07_随遇而安——适配器模式和外观模式

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

作者: 米都都 | 来源:发表于2019-01-07 18:52 被阅读0次
    • (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)中的情况又包装了几个类), 造成复杂度和开发时间的增加, 所以应__在抽象和速度之间折中__

    相关文章

      网友评论

          本文标题:chapter07_随遇而安——适配器模式和外观模式

          本文链接:https://www.haomeiwen.com/subject/zrrprqtx.html