• 装饰模式


    子类复子类,子类何其多

    示例:

        假如我们需要为游戏中开发一种坦克,除了各种不同型号的坦克外,我们还希望在不同场合为其添加以下一种或者多种功能:比如红外线夜视,水陆两栖功能,卫星定位功能等

     

    代码:(第一版本)

     

    //抽象坦克类                                                

     public abstract  class  Tank{

           public abstract  shot();//发射

           public  abstract   run();//跑动

    }

     

    //坦克子类

     public   class  TankA extends   Tank{

    }

    public   class  TankB extends   Tank{

    }

    public   class  TankC extends   Tank{

    }

    //功能接口

    public  interface    flyable{

       public   void   fly();

    }

     

    public  interface    swinable{

       public   void   swin();

    }

    //各种不同功能的组合(满足需求的设计)

    public  class  TankAWithFly  extends  TankA  implements  flyable{//能飞的坦克

    }

     

    public  class  TankAWithSwin extends  TankA   implements  swinable{//能下水的坦克

    }

     

    public  class  TankAWithFlyAndSwin  extends  TankA    implements  swinable{//能飞,能下水的坦克

    }

     

     

    问题:

        每一个功能的增加都会产生一个子类

     

     

    解决办法:装饰模式的运用

    何时用:解决主体类在多个方向上的扩展问题

     

    动机:上述描述的问题根源在于我们"过度地使用了类或接口继承来扩展对象的功能",由于继承为类型引入到静态特质(我们要想获取一个功能,我们在编译的时候要建一个类),使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀

     

    如何使"对象功能的扩展"能够根据需要来动态地实现?同时避免扩展功能的增多带来子类的膨胀问题?从而使得任何"功能扩展变化"所导致的影响将为最低?

     

    意图:

    动态地给一个对象增加一些额外的职责,就增加功能而言,修饰者模式比生成子类更为灵活. 

     

     

     

     

     

     

     

     

    package decorator;
    //抽象类
    public abstract class Tank {
        public abstract void shot();
    
        public abstract  void run();
    }
    
    
    
    package decorator;
    /**
     * 坦克A 
     * @author Administrator
     *
     */
    public class TankA extends Tank {
    
        @Override
        public void run() {
            System.out.println("Tank A 开始跑了");
            
        }
    
        @Override
        public void shot() {
            System.out.println("Tank A 开始发射");
        }
    
    }
    
    
    
    
    package decorator;
    
    public abstract class Decorator extends Tank {
    
        private Tank tank;
    
        public Decorator(Tank tank) {
            this.tank = tank;
        }
    
        @Override
        public void run() {
            tank.run();
        }
    
        @Override
        public void shot() {
            tank.shot();
        }
    
        public Tank getTank() {
            return tank;
        }
    
        public void setTank(Tank tank) {
            this.tank = tank;
        }
    
    }
    
    
    
    
    
    package decorator;
    /**
     * 在run方法前进行相关的处理  如  进入书中 等
     * @author Administrator
     *
     */
    public class DecoratorInWater extends Decorator {
    
        public DecoratorInWater(Tank tank) {
            super(tank);
        }
    
        @Override
        public void run() {
            System.out.println("进入水中..");
            super.run();
        }
        
        
        
    }
    
    
    
    package decorator;
    /**
     * 装饰tank类 使其具有 发射具有红外功能
     * @author Administrator
     *
     */
    public class DecoratorShot extends Decorator {
    
        public DecoratorShot(Tank tank) {
            super(tank);
        }
    
        
        @Override
        public void shot() {
            System.out.println("使其具有红外功能的坦克!");
            super.shot();
        }
        
    
    }
    
    
    
    
    
    package decorator;
    
    public class App {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
               Tank  tankA=new TankA();
               Decorator  decTankA=new DecoratorShot(tankA);
               Decorator  decTankB=new DecoratorInWater(decTankA);
               decTankB.shot();
               decTankB.run();
        }
    
    }

     装饰模式 <wbr>结构图

     

     

    通过采用组合、而非继承的手法,Decorator模式实现了在运动时动态的扩展了对象功能的能力,而且可以根据需要扩展多个功能,避免了单独使用继承带来的"灵活性差"和"多子类衍生问题"

     

     

  • 相关阅读:
    Git: untrack a file in local repo only and keep it in the remote repo
    ubuntu 安装 nodejs
    Ffmpeg
    网页布局基础 第三次(浮动布局)
    网页布局基础 第二次(盒子模型)
    网页布局基础 第一次
    Web前端开发基础 第四课(CSS小技巧1)
    Web前端开发基础 第四课(CSS小技巧)
    Web前端开发基础 第四课(颜色值)
    Web前端开发基础 第四课(盒代码模型)
  • 原文地址:https://www.cnblogs.com/coollijie/p/Decorator.html
Copyright © 2020-2023  润新知