设计模式——装饰者模式

设计模式——装饰者模式,第1张

设计模式——装饰者模式

前言

        本文简单介绍了设计模式的一种:装饰者模式

        (上一篇) 设计模式——代理模式_秋雨绵绵-CSDN博客


目录

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

二、装饰模式的结构

三、咖啡点单案例演示

四、总结


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

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

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

        装饰模式的定义:

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

        特点:

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

        缺点

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

二、装饰模式的结构

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

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

        图示

 三、咖啡点单案例演示

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

        看类图

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

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

        代码实例:

        component抽象构件角色:

package com.decoratorPattern.starBucks;


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;
    }

    
    public abstract float cost();
}

        装饰者类:

package com.decoratorPattern.starBucks;


public class Decorator extends Drink {

    private Drink drink;

    
    public Decorator(Drink drink) {
        this.drink = drink;
    }

    
    @Override
    public float cost() {
        return super.getPrice() + drink.cost();
    }

    
    @Override
    public String getDescription() {
        return drink.getDescription() + "n加入的材料:" + super.getDescription()
                + "t材料价格:" + super.getPrice() ;
    }
}

        装饰者类:

package com.decoratorPattern.starBucks;


public class Coffee extends Drink{
    @Override
    public float cost() {
        return super.getPrice();
    }
}

        具体构件类:拿铁

package com.decoratorPattern.starBucks;


public class Latte extends Coffee{
    public Latte() {
        setDescription("拿铁咖啡");
        setPrice(15.0f);
    }
}

        具体构件类:摩卡

package com.decoratorPattern.starBucks;


public class Mocha extends Coffee {
    public Mocha() {
        setDescription("摩卡咖啡");
        setPrice(12.2f);
    }
}

        其他同上,不过多展示

        具体装饰类:牛奶

package com.decoratorPattern.starBucks;


public class Milk extends Decorator{

    
    public Milk(Drink drink) {
        super(drink);
        setDescription("牛奶");
        setPrice(1.0f);
    }
}

        具体装饰:糖

package com.decoratorPattern.starBucks;


public class Sugar extends Decorator{
    
    public Sugar(Drink drink) {
        super(drink);
        setDescription("糖");
        setPrice(0.5f);
    }
}

        订单测试代码:

package com.decoratorPattern.starBucks;


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());
    }
}

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

四、总结

        装饰模式是为已有的功能动态的添加更多功能的一种方式,当系统需要新功能的时候,向旧的类中添加新的代码,这些新加的代码通常装饰了原有类的核心职责或主要行为。

        优点:

        把类中装饰功能从类中移除,这样可以简化原来的类,

        有效的把类的核心职责和装饰功能分开了,而且可以去除相关类中的重复装饰逻辑

        可代替继承。

                                                                  参考:大话设计模式

                                                                             菜鸟教程:装饰器模式 | 菜鸟教程 (runoob.com)  

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5680861.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存