9、DECORATOR(装饰模式)

目的

动态的给一个对象添加一些额外的职责。对于增加功能来说,该模式比生成子类更为灵活。

使用优点

  • 采用装饰模式扩展对象的功能比采用继承方式更加灵活
  • 可以设计出多个不同的具体装饰类,创造出多个不同行为的组合

使用场景

9、DECORATOR(装饰模式)_第1张图片
装饰者模式UML

小明很喜欢吃肉夹馍和手抓饼,手抓饼和肉夹馍都可以添加煎蛋、黄瓜、火腿等配料。但是这些配料是可选的,也就是装饰元素。
在这个例子中,我的类图如下:


9、DECORATOR(装饰模式)_第2张图片
煎饼和手抓饼.png

在本例子中,Pancake是UML中的Compoent,而手抓饼和肉夹馍都是Component的具体构建,Codiment是调料,是抽象装饰,Ham、Meat等是其的具体装饰。
具体代码如下:

/**
 * 煎饼抽象类,对应UML中的Component
 */
public abstract class Pancake {
    String desc;
    public String getDesc(){
        return desc;
    }
    //煎饼的价格
    double price;
    public double getPrice(){
        return price;
    }
}
/**
 * 手抓饼,对应UML中的Concrete Component,
 * 是Pancake的具体实现
 */
public class TornCake extends Pancake{
    public TornCake(){
        desc = "手抓饼";
    }
    @Override
    public double getPrice(){
        return 4;
    }
}

public class Roujiamo extends Pancake {
    public Roujiamo(){
        desc = "肉夹馍";
    }
    @Override
    public double getPrice(){
        return 6;
    }
}
/**
 * 肉夹馍和手抓饼可以加的料,相当于UML中的抽象装饰
 */
public abstract class Condiment extends Pancake{
    public abstract String getDesc();
}
/**
 * 抽象装饰的具体实现,相当于UML中的具体装饰
 * 可以加的料——黄瓜
 */
public class Cucumeber extends Condiment{
    Pancake pancake;
    public Cucumeber(Pancake pancake){
        this.pancake = pancake;
    }
    @Override
    public String getDesc(){
        return pancake.getDesc() + ",黄瓜";
    }
    @Override
    public double getPrice(){
        return pancake.getPrice() + 1;
    }
}

/**
 * 装饰的具体实现
 * 可以加的料——煎蛋
 */
public class Egg extends Condiment{
    private Pancake pancake;
    public Egg(Pancake pancake){
        this.pancake = pancake;
    }
    @Override
    public String getDesc(){
        return pancake.getDesc() + ",煎蛋";
    }
    @Override
    public double getPrice(){
        return pancake.getPrice() + 2;
    }
}

/**
 * 可以加的料——火腿,装饰的具体实现
 */
public class Ham extends Condiment {
    Pancake pancake;
    public Ham(Pancake pancake){
        this.pancake = pancake;
    }
    @Override
    public String getDesc(){
        return pancake.getDesc() + ",火腿";
    }
    @Override
    public double getPrice(){
        return pancake.getPrice() + 4;
    }
}

测试类

public class Client {
    public static void main(String[] args){
        //新建一个手抓饼
        Pancake torCake = new TornCake();
        System.out.printf("%s 的价格是 %f\n",torCake.getDesc(),torCake.getPrice());

        Pancake roujiamo = new Roujiamo();
        roujiamo = new Egg(roujiamo);
        roujiamo = new Ham(roujiamo);
        roujiamo = new Cucumeber(roujiamo);
        System.out.printf("%s 的价格是 %f\n",roujiamo.getDesc(),roujiamo.getPrice());
    }
}

最后函数的输出结果如下;

手抓饼 的价格是 4.000000
肉夹馍,煎蛋,火腿,黄瓜 的价格是 13.000000

你可能感兴趣的:(9、DECORATOR(装饰模式))