zoukankan      html  css  js  c++  java
  • 结构型模式————装饰器模式(3.1)

    什么是装饰器模式?


    【先吃三颗栗子:】


    1.PC=主机+显示器+键盘+鼠标+鼠标垫

    主机是核心,而其他的组成部分都是装饰。


    2.手抓饼=+鸡蛋+培根+黄瓜

    饼是核心,鸡蛋,培根是可选的,可以理解为装饰。


    3.咖啡=咖啡+牛奶+冰+方糖

    咖啡是核心,牛奶等可选。


    比喻虽然形象生动,但是与实际或多或少会产生偏差。


    抽象的解释:装饰器模式的目的——核心部分和装饰部分可以自由组合。

    装饰器模式的功能

    对于软件开发来说,聚焦于软件的灵活性和可扩展性。

    装饰器模式要求:

    • 装饰可选
    • 装饰可扩展
    • 核心部分可扩展

    手抓饼中的装饰器模式

    实现饼加各种配料的价格计算。

    思路:

    1.定义抽象类手抓饼,其中包含获取种类的抽象方法和获取价格的抽象方法。

    2.然后定义两个分别为大份手抓饼和中份手抓饼来继承这个抽象类,重写两个方法定义种类和价格。

    3.定义具体的配料类继承手抓饼抽象类,先定义构造器传入已经创建的手抓饼种类,然后重写种类和价格方法。


    在网上看的一些博客,是创建出一个抽象的配料类来继承抽象产品类,然后用具体的配料类来实现抽象配料类,实现装饰。

    可是如果直接将抽象产品类的方法全部定义抽象方法,配料类直接继承重写,实现装饰,功能上也是可以实现的,如下所示,Bacon类直接继承HandPancake,然后重写getName和getCost方法,实现装饰。似乎也没有问题:

    但是设计模式毕竟是一种经验总结,如果有已经看出端倪的小伙伴们在下方留言交流一下吧!

    直接继承HandPancake

    abstract class HandPancake
    {
        public abstract String getName();
    
        public abstract int getCost();
    }
    
    class HandPancake_Big extends HandPancake
    {
        @Override
        public String getName() {
            return "大份手抓饼";
        }
    
        @Override
        public int getCost() {
            return 10;
        }
    }
    
    class HandPancake_Mid extends HandPancake
    {
        @Override
        public String getName() {
            return "中份手抓饼";
        }
    
        @Override
        public int getCost() {
            return 8;
        }
    }
    class Bacon extends HandPancake
    {
        private HandPancake handPancake;
    
        Bacon(HandPancake handPancake)
        {
            this.handPancake=handPancake;
        }
    
        @Override
        public String getName() {
            return handPancake.getName()+"加培根";
        }
    
        @Override
        public int getCost() {
            return handPancake.getCost()+1;
        }
    }
    class Cucumber extends HandPancake
    {
        private HandPancake handPancake;
    
        Cucumber(HandPancake handPancake)
        {
            this.handPancake=handPancake;
        }
    
        @Override
        public String getName() {
            return handPancake.getName()+"加黄瓜";
        }
    
        @Override
        public int getCost() {
            return handPancake.getCost()+2;
        }
    }
    class Ham extends HandPancake
    {
        private HandPancake handPancake;
    
        Ham(HandPancake handPancake)
        {
            this.handPancake=handPancake;
        }
    
        @Override
        public String getName() {
            return handPancake.getName()+"加火腿";
        }
    
        @Override
        public int getCost() {
            return handPancake.getCost()+1;
        }
    }
    
    
    public class APPlication
    {
        public static void main(String[] args) {
            HandPancake handPancake_big = new HandPancake_Big();
    
            System.out.println("啥也不加"+handPancake_big.getName()+":"+handPancake_big.getCost());
    
            handPancake_big = new Ham(handPancake_big);
    
            System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
    
            handPancake_big = new Cucumber(handPancake_big);
    
            System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
    
            handPancake_big = new Bacon(handPancake_big);
    
            System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
    
            System.out.println("==============================");
            HandPancake handPancake_mid = new HandPancake_Mid();
            System.out.println("啥也不加"+handPancake_mid.getName()+":"+handPancake_mid.getCost());
    
            handPancake_mid = new Ham(handPancake_mid);
    
            System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
    
            handPancake_mid = new Cucumber(handPancake_mid);
    
            System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
    
            handPancake_mid = new Bacon(handPancake_mid);
    
            System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
    
    
        }
    }
    

    1565696683438

    官方做法:

    abstract class HandPancake
    {
        String name;                      //1
        public  String getName()
        {
            return name;
        }
    
        public abstract int getCost();
    }
    
    class HandPancake_Big extends HandPancake
    {
        HandPancake_Big()         //2.通过构造器赋值
        {
            name="大份手抓饼";
        }
    
    
        @Override
        public int getCost() {
            return 10;
        }
    }
    
    class HandPancake_Mid extends HandPancake
    {
        HandPancake_Mid()         //2.通过构造器赋值
        {
            name="中份手抓饼";
        }
    
    
        @Override
        public int getCost() {
            return 8;
        }
    }
    
    abstract class Condiments  extends HandPancake   //3.定义抽象接口
    {
        public abstract String getName();
    }
    
    class Bacon extends Condiments     //4.继承抽象接口
    {
        private HandPancake handPancake;
    
        Bacon(HandPancake handPancake)
        {
            this.handPancake=handPancake;
        }
    
        @Override
        public String getName() {
            return handPancake.getName()+"加培根";
        }
    
        @Override
        public int getCost() {
            return handPancake.getCost()+1;
        }
    }
    class Cucumber extends Condiments
    {
        private HandPancake handPancake;
    
        Cucumber(HandPancake handPancake)
        {
            this.handPancake=handPancake;
        }
    
        @Override
        public String getName() {
            return handPancake.getName()+"加黄瓜";
        }
    
        @Override
        public int getCost() {
            return handPancake.getCost()+2;
        }
    }
    class Ham extends Condiments
    {
        private HandPancake handPancake;
    
        Ham(HandPancake handPancake)
        {
            this.handPancake=handPancake;
        }
    
        @Override
        public String getName() {
            return handPancake.getName()+"加火腿";
        }
    
        @Override
        public int getCost() {
            return handPancake.getCost()+1;
        }
    }
    
    
    public class APPlication
    {
        public static void main(String[] args) {
            HandPancake handPancake_big = new HandPancake_Big();
    
            System.out.println("啥也不加"+handPancake_big.getName()+":"+handPancake_big.getCost());
    
            handPancake_big = new Ham(handPancake_big);
    
            System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
    
            handPancake_big = new Cucumber(handPancake_big);
    
            System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
    
            handPancake_big = new Bacon(handPancake_big);
    
            System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
    
            System.out.println("==============================");
            HandPancake handPancake_mid = new HandPancake_Mid();
            System.out.println("啥也不加"+handPancake_mid.getName()+":"+handPancake_mid.getCost());
    
            handPancake_mid = new Ham(handPancake_mid);
    
            System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
    
            handPancake_mid = new Cucumber(handPancake_mid);
    
            System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
    
            handPancake_mid = new Bacon(handPancake_mid);
    
            System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
    
    
        }
    }
    

    1565696715504

    手抓饼的扩展性

    • 创建手抓饼的种类
    • 创建配料种类

    官方的扩展:创建一个小份手抓饼继承Hanpancake,然后创建配料继承Condiments。

    贴一下直接继承HandPancake的情况:

    class HandPancake_Smalll extends HandPancake
    class Egg extends HandPancake

    abstract class HandPancake
    {
        public abstract String getName();
    
        public abstract int getCost();
    }
    
    class HandPancake_Big extends HandPancake
    {
        @Override
        public String getName() {
            return "大份手抓饼";
        }
    
        @Override
        public int getCost() {
            return 10;
        }
    }
    
    class HandPancake_Mid extends HandPancake
    {
        @Override
        public String getName() {
            return "中份手抓饼";
        }
    
        @Override
        public int getCost() {
            return 8;
        }
    }
    class Bacon extends HandPancake
    {
        private HandPancake handPancake;
    
        Bacon(HandPancake handPancake)
        {
            this.handPancake=handPancake;
        }
    
        @Override
        public String getName() {
            return handPancake.getName()+"加培根";
        }
    
        @Override
        public int getCost() {
            return handPancake.getCost()+1;
        }
    }
    class Cucumber extends HandPancake
    {
        private HandPancake handPancake;
    
        Cucumber(HandPancake handPancake)
        {
            this.handPancake=handPancake;
        }
    
        @Override
        public String getName() {
            return handPancake.getName()+"加黄瓜";
        }
    
        @Override
        public int getCost() {
            return handPancake.getCost()+2;
        }
    }
    class Ham extends HandPancake
    {
        private HandPancake handPancake;
    
        Ham(HandPancake handPancake)
        {
            this.handPancake=handPancake;
        }
    
        @Override
        public String getName() {
            return handPancake.getName()+"加火腿";
        }
    
        @Override
        public int getCost() {
            return handPancake.getCost()+1;
        }
    }
    //========================
    
    class HandPancake_Smalll extends HandPancake
    {
        @Override
        public String getName() {
            return "小份手抓饼";
        }
    
        @Override
        public int getCost() {
            return 5;
        }
    }
    
    
    class Egg extends HandPancake
    {
        private HandPancake handPancake;
    
        Egg(HandPancake handPancake)
        {
            this.handPancake=handPancake;
        }
    
        @Override
        public String getName() {
            return handPancake.getName()+"加鸡蛋";
        }
    
        @Override
        public int getCost() {
            return handPancake.getCost()+1;
        }
    }
    
    
    public class APPlication
    {
        public static void main(String[] args) {
            HandPancake handPancake_big = new HandPancake_Big();
    
            System.out.println("啥也不加"+handPancake_big.getName()+":"+handPancake_big.getCost());
    
            handPancake_big = new Ham(handPancake_big);
    
            System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
    
            handPancake_big = new Cucumber(handPancake_big);
    
            System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
    
            handPancake_big = new Bacon(handPancake_big);
    
            System.out.println(handPancake_big.getName()+":"+handPancake_big.getCost());
    
            System.out.println("==============================");
            HandPancake handPancake_mid = new HandPancake_Mid();
            System.out.println("啥也不加"+handPancake_mid.getName()+":"+handPancake_mid.getCost());
    
            handPancake_mid = new Ham(handPancake_mid);
    
            System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
    
            handPancake_mid = new Cucumber(handPancake_mid);
    
            System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
    
            handPancake_mid = new Bacon(handPancake_mid);
    
            System.out.println(handPancake_mid.getName()+":"+handPancake_mid.getCost());
    
    
            System.out.println("扩展性测试:");
    
            HandPancake handPancake_small = new HandPancake_Smalll();
            System.out.println("啥也不加"+handPancake_small.getName()+":"+handPancake_small.getCost());
    
            handPancake_small = new Egg(handPancake_small);
    
            System.out.println(handPancake_small.getName()+":"+handPancake_small.getCost());
    
    
    
    
    
    
        }
    }
    

    运行结果:

    1565696654138

  • 相关阅读:
    data:image/png;base64
    需要去了解的知识
    【转】react的高阶组件
    几个css问题
    antd中form中resetFields清空输入框
    react中map循环中key取值问题
    react中父组件调用子组件的方法
    hive 初始化 时间问题 The server time zone value 'EDT' is unrecognized
    centos7安装MySQL8 无法修改密码 无法修改密码策略
    虚拟机 Linux 不能连 xshell 不能上网
  • 原文地址:https://www.cnblogs.com/noneplus/p/11348102.html
Copyright © 2011-2022 走看看