zoukankan      html  css  js  c++  java
  • 装饰模式(Decorator)

      装饰模式(Decorator)最常见的就是JDK中的关于I/O流的处理。

         DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream("test.txt")));

         

         装饰模式的类图如下:

         

         首先是抽象的接口Component

    public interface Component{
        void sampleOperation();
    }

         下面是装饰角色的代码Decorator,继承了Component接口,调用的方法还是父类的方法,但并不是单纯的调用父类方法,而是在功能上有所增强。 

    public class Decorator implements Component{
        private Component component;
    
        public Decorator(Component component){
            this.component = component;
        }
    
        public Decorator() {
        //write code here } public void sampleOperation(){ component.sampleOperation(); } }

           具体装饰角色的源代码如下,

    public class ConcreteDecorator extends Decorator{
        public void sampleOperation(){
            super.sampleOperation();
        }
    }

           一个典型的装饰模式的创建过程如下:     

    new Decorator1(new Decorator2(new Decorator(new ConcreteComponent())))  

      Decorator1持有一个Decorator2对象的引用,后者持有一个Decorator3的引用,Decorator3持有的是ConcreteDecorator的引用。

         

          齐天大圣的例子中,齐天大圣角色是抽象接口Component,ConcreteComponent是大圣本尊,就是本人。大圣化身是Decorator角色,而花,鸟,鱼,虫的角色是ConcreteDecorator。

          齐天大圣的示例代码:  

    public interface MonkeyKing{
        public void laugh();
    } 

          大圣本尊的实例代码:

    public class MonkeySelf implements MonkeyKing{
        public   MonkeySelf (){
    
        }
    
        public void laugh(){
              System.out.println("laugh like a monkey!");
        }
    }  

      大圣化身的实例代码:

    public class MokeyAvactor implements MonkeyKing{
        private MonkeyKing  mk;
        public MokeyAvactor(MonkeyKing mk){
                this.mk = mk;
        }
    
        public void laugh(){
                 mk.laugh();
        }         
    }

        大圣变成的鱼的实例代码:

    public class FishAvator extends MokeyAvactor{
        public  FishAvator(MonkeyKing mk){
              super(mk);
        }
        public void laugh(){
               super.laugh();
        }
        public void swim(){
            System.out.println("FishAvator is swimming!");
        }
    }
    

      大圣变成的鸟的实例代码:

    public class BirdAvator extends MokeyAvactor{
      public  BirdAvator(MonkeyKing mk){
         super(mk);
      }
      public void laugh(){
         super.laugh();
      }
      public void fly(){
          System.out.println("BirdAvator is flying!");
      }
    }
    

      测试各种变身的类的代码:

    public class AvatorTest {
    	public static void main(String [] args){
    		MonkeyKing mk = new MonkeySelf();
    		MonkeyKing fish = new FishAvator(mk);
    		fish.laugh();
    		
    		MonkeyKing bird = new BirdAvator(fish);
    		bird.laugh();
    	}
    }
    

      测试的结果为:      

      laugh like a monkey!

      laugh like a monkey!

          由大圣本尊化身为的鸟和鱼的laugh调用的还是大圣本尊的laugh。

           

         

       MonkeyKing fish = new FishAvator(mk);符合面向接口编程的原则,但是如果需要用Fish的swim方法,这种写法就不行了,只能写成:

         FishAvator fish = new FishAvator(mk);这种被称为半透明的装饰模式,或者称为退化的装饰模式。

         装饰模式提供了比继承更为灵活的功能,通过不同的组合,对象将拥有不同的属性。

     

         回到最开始的I/O流中的代码:

         DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream("test.txt")));

         查看代码,DataInputStream中的read方法都是调用传入的InputStream的read方法,对应上面就是调用的BufferedInputStream的read方法。

          InputStream可以看做抽象接口,BufferedInputStream可以看做ConcreteComponent,DataInputStream可以看做ConcreteDecorator,就可以和上面装饰模式的类图对应上了。

          实际中使用的装饰模式要比刚开始的类图结构简单些,下面是简化了的装饰模式的类图。

          省略Component的情况:

          

            只有一个ConcreteDecorator,则Decorator是可以省略的:

            

          

  • 相关阅读:
    APUE.3源码编译(Ubuntu16.04)
    《UNIX环境高级编程》(第三版)阅读笔记---2018-5-9
    css回归之用户界面
    css回归之文本
    js回归之字符串
    js回归之BOM
    js回归之事件
    百度前端面试总结
    书单
    剑指offer做题收获之一:补码
  • 原文地址:https://www.cnblogs.com/lnlvinso/p/3906058.html
Copyright © 2011-2022 走看看