装饰模式

子类复子类,子类何其多

示例:

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

 

代码:(第一版本)

 

//抽象坦克类                                                

 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模式实现了在运动时动态的扩展了对象功能的能力,而且可以根据需要扩展多个功能,避免了单独使用继承带来的"灵活性差"和"多子类衍生问题"

 

 

转载于:https://www.cnblogs.com/coollijie/archive/2012/07/03/Decorator.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值