Java设计模式之装饰者模式

本文详细介绍了装饰者模式,包括其定义、角色划分(抽象构件、具体构件和装饰者),并通过FastFood类和Garnish类的示例展示如何动态添加功能。装饰者模式强调灵活性、可扩展性和松耦合,与静态代理进行比较,突出了其目的和构建方式的不同。

目录

定义

结构

案例

好处

静态代理与装饰着模式区别


定义

指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。

结构

装饰模式中的角色:

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

案例

抽象构建角色

public abstract class FastFood {
    private BigDecimal price; //  价格
    private String desc; //描述

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    public BigDecimal getPrice() {
        return price;
    }

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

    public FastFood(BigDecimal price, String desc) {
        this.price = price;
        this.desc = desc;
    }

    //计算总价
    public abstract BigDecimal cost();
}

具体构建角色 

//食物1
public class Food1 extends FastFood {

    public Food1() {
        super(BigDecimal.valueOf(10),"炒饭");
    }


    @Override
    public BigDecimal cost() {
        return getPrice();
    }
}
//食物2
public class Food2 extends FastFood {
    public Food2() {
        super(BigDecimal.valueOf(12), "炒面");
    }

    @Override
    public BigDecimal cost() {
        return getPrice();
    }
}

 抽象装饰类

public abstract class Garnish extends FastFood{
    private FastFood fastFood;

    public Garnish(BigDecimal price, String desc, FastFood fastFood) {
        super(price, desc);
        this.fastFood = fastFood;
    }

    public FastFood getFastFood() {
        return fastFood;
    }

    public void setFastFood(FastFood fastFood) {
        this.fastFood = fastFood;
    }
}

 具体装饰类

public class Garnish1 extends Garnish {
    public Garnish1(FastFood fastFood) {
        super(BigDecimal.valueOf(1), "配料1", fastFood);
    }

    @Override
    public String getDesc() {
        return super.getDesc()+getFastFood().getDesc();
    }

    @Override
    public BigDecimal cost() {
        //getFastFood().getPrice与getFastFood().cost() 区别很大欸
        return getPrice().add(getFastFood().cost());
    }
}

public class Garnish2 extends Garnish {
    public Garnish2(FastFood fastFood) {
        super(BigDecimal.valueOf(2), "配料2", fastFood);
    }

    @Override
    public String getDesc() {
        return super.getDesc()+getFastFood().getDesc();
    }

    @Override
    public BigDecimal cost() {
        return getPrice().add(getFastFood().cost());
    }
}

测试 

public class Client {
    public static void main(String[] args) {
        FastFood fastFood = new Food1();
        System.out.println(fastFood.getDesc()+":"+fastFood.cost());

        System.out.println("==================");
        fastFood=new Garnish1(fastFood);
        System.out.println(fastFood.getDesc()+":"+fastFood.cost());
        System.out.println("==================");
        fastFood=new Garnish2(fastFood);
        System.out.println(fastFood.getDesc()+":"+fastFood.cost());
    }
}

运行结果为: 

炒饭:10

==================

配料1炒饭:11

==================

配料2配料1炒饭:13

有点像递归的意思,不断地嵌套通过cost方法取得自己与上一级的售价和,直到达到最底层Food1或Food2后开始return

好处

  • 饰者模式可以带来比继承更加灵活性的扩展功能,使用更加方便,可以通过组合不同的装饰者对象来获取具有不同行为状态的多样化的结果。装饰者模式比继承更具良好的扩展性,完美的遵循开闭原则,继承是静态的附加责任,装饰者则是动态的附加责任。
  • 装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

静态代理与装饰着模式区别

  • 相同点:
    • 都要实现与目标类相同的业务接口
    • 在两个类中都要声明目标对象
    • 都可以在不修改目标类的前提下增强目标方法
  • 不同点:
    • 目的不同 装饰者是为了增强目标对象 静态代理是为了保护和隐藏目标对象
    • 获取目标对象构建的地方不同 装饰者是由外界传递进来,可以通过构造方法传递 静态代理是在代理类内部创建,以此来隐藏目标对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zmbwcx2003

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值