设计模式の装饰者模式

目录

前言:

定义与特点:

结构与实现:


前言:

上班族大多都有睡懒觉的习惯,每天早上上班时间都很紧张,于是很多人为了多睡一会,就会用方便的方式解决早餐问题。有些人早餐可能会吃煎饼,煎饼中可以加鸡蛋,也可以加香肠,但是不管怎么“加码”,都还是一个煎饼。在现实生活中,常常需要对现有产品增加新的功能或美化其外观,如房子装修、相片加相框等,都是装饰器模式。

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

定义与特点:

装饰器(Decorator)模式的定义:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。

特点: 

  • 装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用

  • 通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果

  • 装饰器模式完全遵守开闭原则

其主要缺点是:装饰器模式会增加许多子类,过度使用会增加程序得复杂性。

结构与实现:

模式的结构

装饰器模式主要包含以下角色。

  1. 抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。

  2. 具体构件(ConcreteComponent)角色:实现抽象构件,通过装饰角色为其添加一些职责。

  3. 抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。

  4. 具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。

 举例:

 结构图:

代码实现: 

//抽象构建角色
public abstract class Drink {
    //描述
    public String des;
    //价格
    private float price = 0.0f;//?

    public String getDes() {
        return des;
    }

    public void setDes(String des) {
        this.des = des;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    //计算费用的抽象方法
    public abstract float cost();
}

//抽象装饰角色
public class Decorator extends Drink {
    //被装饰者
    private Drink obj;

    //接收被装饰者
    public Decorator(Drink obj) {
        this.obj = obj;
    }

    @Override
    public float cost() {
        //自己的价格加上被装饰者的价格
        return super.getPrice() + obj.cost();
    }

    @Override
    public String getDes() {
        //自己的描述+自己的价格+"&&"+被装饰者的描述
        return super.getDes() + " " + super.getPrice() + " $$ " + obj.getDes();
    }
}

//具体构建角色
public class LongBlack extends Drink{

    public LongBlack(){
        setDes("澳氏黑咖啡");
        setPrice(5.0f);
    }
    @Override
    public float cost() {
        return super.getPrice();
    }
}

//具体装饰角色
public class Chocolate extends Decorator{
    public Chocolate(Drink obj) {
        super(obj);
        setDes("巧克力");
        setPrice(3.0f);
    }
}

//具体装饰角色
public class Milk extends Decorator{
    public Milk(Drink obj) {
        super(obj);
        setDes("牛奶");
        setPrice(2.0f);
    }
}

测试:

结构图:

//测试类
public class Test {
    public static void main(String[] args) {

        //点一份澳氏黑咖啡
        Drink order = new LongBlack();
        System.out.println("费用= " + order.cost());
        System.out.println("描述= " + order.getDes());

        //加一份牛奶
        order = new Milk(order);
        System.out.println("order加了一份牛奶 费用= " + order.cost());
        System.out.println("order加了一份牛奶 描述= " + order.getDes());

        //加一份巧克力
        order = new Chocolate(order);
        System.out.println("order加了一份巧克力 费用= " + order.cost());
        System.out.println("order加了一份巧克力 描述= " + order.getDes());

        //加一份巧克力
        order = new Chocolate(order);
        System.out.println("order加了一份巧克力 费用= " + order.cost());
        System.out.println("order加了一份巧克力 描述= " + order.getDes());
    }
}

运行结果: 

费用= 5.0
描述= 澳氏黑咖啡
order加了一份牛奶 费用= 7.0
order加了一份牛奶 描述= 牛奶 2.0 $$ 澳氏黑咖啡
order加了一份巧克力 费用= 10.0
order加了一份巧克力 描述= 巧克力 3.0 $$ 牛奶 2.0 $$ 澳氏黑咖啡
order加了一份巧克力 费用= 13.0
order加了一份巧克力 描述= 巧克力 3.0 $$ 巧克力 3.0 $$ 牛奶 2.0 $$ 澳氏黑咖啡

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值