美文网首页
9、DECORATOR(装饰模式)

9、DECORATOR(装饰模式)

作者: 我要扭开奥利奥 | 来源:发表于2019-05-24 16:53 被阅读0次

    目的

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

    使用优点

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

    使用场景

    装饰者模式UML

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


    煎饼和手抓饼.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(装饰模式)

          本文链接:https://www.haomeiwen.com/subject/fjhnzqtx.html