温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java装饰者模式怎么理解

发布时间:2022-01-05 19:45:54 来源:亿速云 阅读:154 作者:iii 栏目:开发技术

本篇内容主要讲解“Java装饰者模式怎么理解”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java装饰者模式怎么理解”吧!

    一、装饰模式的定义和特点

    在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成了一些核心功能。但在不改变其结构的情况下,可以动态地扩展其功能。所有这些都可以釆用装饰器模式来实现。

    就像我们做菜,需要用到调料,菜,刀,火等一系列抽象的组件来最终完成一道菜。

    装饰模式的定义:

    指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。就增加功能来说,装饰模式比生成子类更加灵活。

    特点:

    装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用
    通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果
     装饰器模式完全遵守开闭原则

    缺点

     装饰器模式会增加许多子类,过度使用会增加程序得复杂性。

    二、装饰模式的结构

    装饰模式的结构一般包含以下几个角色

    1. 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
    2. 具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。
    3. 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
    4. 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

    图示

    Java装饰者模式怎么理解

    三、咖啡点单案例演示

    有一个需求,点一杯咖啡需要咖啡,材料等等,这个案例就很适合装饰模式,类似于穿衣,点餐,买包子,等等,我们怎么把他设计成装饰模式呢?

    这个结构就是我已经设计好的一个装饰模式的类图,idea自动生成的,这里的Drink就是我们上面说的抽象构建角色,装饰者是Decorator,他是一个抽象装饰,下面他的子类就是具体的装饰者,那么具体构建中间我们提供了一个中间构建,提供了coffee的一些共性,可以放在这里,用的时候直接继承,他的下面就是相应的具体构件,具体被装饰者角色,装饰者与被装饰者共同继承自component抽象构件,需要用到装饰的就是我们点一杯咖啡,用装饰去包裹即可,层层包裹,案例如下:

    比如我要点一份加糖加奶的拿铁咖啡

    代码实例:

    component抽象构件角色:

    package com.decoratorPattern.starBucks;
     
    /**
     * @author wang
     * @version 1.0
     * @packageName com.decoratorPattern.starBucks
     * @className Drink
     * @date 2021/12/28 10:28
     * @Description 饮料构件类抽象component
     */
    public abstract class Drink {
        private String description;
        private float price = 0.0f;
     
        public String getDescription() {
            return description;
        }
     
        public void setDescription(String description) {
            this.description = description;
        }
     
        public float getPrice() {
            return price;
        }
     
        public void setPrice(float price) {
            this.price = price;
        }
     
        /**
         * @Date  2021/12/28 10:30
         * @Param
         * @Return float
         * @MetodName cost
         * @Author wang
         * @Description 计算花费,订单价格
         */
        public abstract float cost();
    }

    装饰者类:

    package com.decoratorPattern.starBucks;
     
    /**
     * @author wang
     * @version 1.0
     * @packageName com.decoratorPattern.starBucks
     * @className Decorator
     * @date 2021/12/28 10:40
     * @Description 装饰者定义类,配料
     */
    public class Decorator extends Drink {
     
        private Drink drink;
     
        /**
         * @param drink
         * @Date 2021/12/28 10:42
         * @Param
         * @Return null
         * @MetodName Decorator
         * @Author wang
         * @Description 传入一个被装饰者,由装饰者进行装饰
         */
        public Decorator(Drink drink) {
            this.drink = drink;
        }
     
        /**
         * @Date 2021/12/28 10:43
         * @Param
         * @Return float
         * @MetodName cost
         * @Author wang
         * @Description 装饰者的价格加上被装饰者的价格
         */
        @Override
        public float cost() {
            return super.getPrice() + drink.cost();
        }
     
        /**
         * @Date 2021/12/28 10:44
         * @Param
         * @Return String
         * @MetodName getDescription
         * @Author wang
         * @Description 输出订单信息,包含装饰者,装饰者的价格,以及被装饰者的信息
         */
        @Override
        public String getDescription() {
            return drink.getDescription() + "\n加入的材料:" + super.getDescription()
                    + "\t材料价格:" + super.getPrice() ;
        }
    }

    装饰者类:

    package com.decoratorPattern.starBucks;
     
    /**
     * @author wang
     * @version 1.0
     * @packageName com.decoratorPattern.starBucks
     * @className Decorator
     * @date 2021/12/28 10:40
     * @Description 装饰者定义类,配料
     */
    public class Decorator extends Drink {
     
        private Drink drink;
     
        /**
         * @param drink
         * @Date 2021/12/28 10:42
         * @Param
         * @Return null
         * @MetodName Decorator
         * @Author wang
         * @Description 传入一个被装饰者,由装饰者进行装饰
         */
        public Decorator(Drink drink) {
            this.drink = drink;
        }
     
        /**
         * @Date 2021/12/28 10:43
         * @Param
         * @Return float
         * @MetodName cost
         * @Author wang
         * @Description 装饰者的价格加上被装饰者的价格
         */
        @Override
        public float cost() {
            return super.getPrice() + drink.cost();
        }
     
        /**
         * @Date 2021/12/28 10:44
         * @Param
         * @Return String
         * @MetodName getDescription
         * @Author wang
         * @Description 输出订单信息,包含装饰者,装饰者的价格,以及被装饰者的信息
         */
        @Override
        public String getDescription() {
            return drink.getDescription() + "\n加入的材料:" + super.getDescription()
                    + "\t材料价格:" + super.getPrice() ;
        }
    }

    具体构件类:拿铁

    package com.decoratorPattern.starBucks;
     
    /**
     * @author wang
     * @version 1.0
     * @packageName com.decoratorPattern.starBucks
     * @className latte
     * @date 2021/12/28 10:32
     * @Description 拿铁咖啡实类,被装饰者
     */
    public class Latte extends Coffee{
        public Latte() {
            setDescription("拿铁咖啡");
            setPrice(15.0f);
        }
    }

    具体构件类:摩卡

    package com.decoratorPattern.starBucks;
     
    /**
     * @author wang
     * @version 1.0
     * @packageName com.decoratorPattern.starBucks
     * @className Mocha
     * @date 2021/12/28 10:36
     * @Description 摩卡咖啡实类,被装饰者
     */
    public class Mocha extends Coffee {
        public Mocha() {
            setDescription("摩卡咖啡");
            setPrice(12.2f);
        }
    }

    其他同上,不过多展示

     具体装饰类:牛奶

    package com.decoratorPattern.starBucks;
     
    /**
     * @author wang
     * @version 1.0
     * @packageName com.decoratorPattern.starBucks
     * @className Milk
     * @date 2021/12/28 10:47
     * @Description 牛奶调味品,具体装饰者
     */
    public class Milk extends Decorator{
     
        /**
         * @param drink
         * @Date 2021/12/28 10:42
         * @Param
         * @Return null
         * @MetodName Decorator
         * @Author wang
         * @Description 传入一个被装饰者,由装饰者进行装饰
         */
        public Milk(Drink drink) {
            super(drink);
            setDescription("牛奶");
            setPrice(1.0f);
        }
    }

    具体装饰:糖

    package com.decoratorPattern.starBucks;
     
    /**
     * @author wang
     * @version 1.0
     * @packageName com.decoratorPattern.starBucks
     * @className sugar
     * @date 2021/12/28 10:50
     * @Description 糖,装饰者
     */
    public class Sugar extends Decorator{
        /**
         * @param drink
         * @Date 2021/12/28 10:42
         * @Param
         * @Return null
         * @MetodName Decorator
         * @Author wang
         * @Description 传入一个被装饰者,由装饰者进行装饰
         */
        public Sugar(Drink drink) {
            super(drink);
            setDescription("糖");
            setPrice(0.5f);
        }
    }

    订单测试代码:

    package com.decoratorPattern.starBucks;
     
    /**
     * @author wang
     * @version 1.0
     * @packageName com.decoratorPattern.starBucks
     * @className OrderTest
     * @date 2021/12/28 10:51
     * @Description 前台订单类
     */
    public class OrderTest {
        public static void main(String[] args) {
            //点一份加糖加奶的拿铁咖啡
     
            System.out.println("+++++++没加任何东西+++++++");
            Drink latte = new Latte();
            System.out.println("当前总价:" + latte.cost());
            System.out.println("coffee:" +latte.getDescription());
            //加糖
            System.out.println("+++++++加糖后+++++++");
            latte = new Sugar(latte);
            System.out.println("当前总价:" + latte.cost());
            System.out.println("coffee:" + latte.getDescription());
     
            System.out.println("+++++++加奶后+++++++");
            latte = new Milk(latte);
            System.out.println("当前总价:" + latte.cost());
            System.out.println("coffee:" +latte.getDescription());
        }
    }
    /**
     * +++++++没加任何东西+++++++
     * 当前总价:15.0
     * coffee:拿铁咖啡
     * +++++++加糖后+++++++
     * 当前总价:15.5
     * coffee:拿铁咖啡
     * 加入的材料:糖	材料价格:0.5
     * +++++++加奶后+++++++
     * 当前总价:16.5
     * coffee:拿铁咖啡
     * 加入的材料:糖	材料价格:0.5
     * 加入的材料:牛奶	材料价格:1.0
     *
     * Process finished with exit code 0
     */

    综上, 如果我们需要新的咖啡种类或者是新的调料,只需要新增类去继承coffee或者decorator类即可。

    到此,相信大家对“Java装饰者模式怎么理解”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI