08_装饰者模式

【装饰者模式】

 动态的给一个对象的添加一些额外的职责,就增加功能而言,装饰模式比直接继承的子类会更加灵活。

装饰模式由4部分组成

1.Component抽象构件(ISoldier接口)

2.ConcreteComponent具体构件(Soldier类)

3.Decorator装饰者类(AbstractRMBSoldier抽象类)

4.ConcreteDecorator具体装饰者类 (RMBSoldier类)

【装饰者模式 例子】

package com.Higgin.Decorator;
import java.util.Random;

/**
 * 战士接口
 */
interface ISoldier{
    public void shoot();
}

/**
 * 具体普通战士类
 */
class Soldier implements ISoldier{
    @Override
    public void shoot() {
        System.out.println("战士举枪,射击!!!");
    }
}
/**
 * 人民币玩家的 抽象战士类
 */
abstract class AbstractRMBSoldier implements ISoldier{
    protected ISoldier soldier=null;
    public AbstractRMBSoldier(ISoldier soldier){
        this.soldier=soldier;
    }
    @Override
    public void shoot() {
        this.soldier.shoot();
    }
}
/**
 * 人民币玩家的 具体战士类
 */
class RMBSoldier extends AbstractRMBSoldier{

    public RMBSoldier(ISoldier soldier) {
        super(soldier);
    }
    public void beforeShoot(){
        System.out.println("战士戴上头盔...");
        System.out.println("战士穿上防弹衣...");
        System.out.println("战士给枪装上消音器...");
    }
    public void afterShoot(){
        System.out.println("射击结束,再扔个手雷...");
    }
    @Override
    public void shoot() {
        this.beforeShoot();
        this.soldier.shoot();
        this.afterShoot();
    }
}

/**
 * 装饰器测试
 */
public class TestDecorator {
    public static void main(String[] args) {
        ISoldier soldier=new Soldier();
        ISoldier rmbSoldier=new RMBSoldier(soldier);
        rmbSoldier.shoot();
    }
} 

【运行结果】

【装饰者模式 优点】

* 装饰者和被装饰者可以独立发展,而不会相互耦合。

* 装饰者模式是继承的一个替代方案。

* 装饰者模式也可以动态地扩展一个类的实现类。

【装饰者模式 缺点】

多层装饰较为复杂。

【装饰者模式 使用场景】

* 需要动态扩展一个类的实现类,或者给类添加一个附加功能。

* 需要动态地给一个对象增加功能,这些功能也可以动态地撤销。

* 需要为一批的兄弟类进行改装或加装功能,首选装饰器模式。

【注意:装饰者模式与代理模式的区别】

发现装饰者模式和静态代理模式UML图一模一样!!!为什么还要区分这两个模式呢?

装饰者模式:注重对被装饰者的方法的增强,比如本例中的装饰者(RMBSoldier类)对被装饰者(Soldier类)的shoot方法进行了增强,本质上,被装饰类的shoot方法还是会执行的,只是增强了。

代理模式:注重对被代理类的方法的控制,比如我们代理类(RMBSoldier类)对代理者(Soldier类)的shoot方法,可以 这样改:

/**
 * 人民币玩家的 具体战士类
 */
class RMBSoldier extends AbstractRMBSoldier{

    public RMBSoldier(ISoldier soldier) {
        super(soldier);
    }
    public void beforeShoot(){
        System.out.println("战士戴上头盔...");
        System.out.println("战士穿上防弹衣...");
        System.out.println("战士给枪装上消音器...");
    }
    public void afterShoot(){
        System.out.println("射击结束,再扔个手雷...");
    }
    @Override
    public void shoot() {
        Random r=new Random();
        if(r.nextBoolean()){   //随机生成一个Boolean类型的数据
            this.beforeShoot();
            this.soldier.shoot();//被代理的类的方法,有可能执行,也有可能不执行!!!
            this.afterShoot();     
        }else{
            System.out.println("老子不爽,不射击了!");
        }
    }
}
原文地址:https://www.cnblogs.com/HigginCui/p/6211434.html