java 装饰器_装饰器模式(Java)

装饰器模式是一种设计模式,用于在不修改原有对象的基础上,通过包装对象来添加新的功能。它提供了一种比继承更灵活的方式来扩展类的功能。在咖啡馆点咖啡的例子中,通过装饰器模式,我们可以动态地为咖啡添加调料,如巧克力、牛奶等,而不需要为每种组合创建新的咖啡类。这种方式避免了类的膨胀,提高了代码的可维护性。装饰类和被装饰类可以独立发展,降低了耦合。装饰模式适用于需要动态扩展功能或撤销扩展的情况。
摘要由CSDN通过智能技术生成

什么是装饰器模式?

装饰器模式允许你向一个现有的对象添加新的功能,同时又不改变其结构,它是作为现有的类的一个包装。这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

他的目的主要是动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

他主要解决的问题是我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。

那么我们何时使用呢?

在不想增加很多子类的情况下扩展类。

如何解决?

将具体功能职责划分,同时继承装饰者模式。

关键代码:

1、Component 类充当抽象角色,不应具体实现。

2、修饰类(Decorator)引用和继承 Component 类

3、具体扩展类(ConcreteComponent)继承 Component 类,重写父类方法。

示例代码

我们去咖啡馆点咖啡的时候,通常会点具体的咖啡单品,然后再点一些咖啡调料。

咖啡种类(具体类):Espresso、ShortBlack、LongBlack、Decaf

调料(装饰类):Milk、Soy、Chocolate

1、抽象接口

// 饮料public abstract class Drink {

// 描述 private String description = "";

// 价格 private float price = 0f;

public void setDescription(String description) {

this.description = description;

}

public String getDescription() {

return "{描述:"+description + "-" + this.getPrice()+"}";

}

public float getPrice() {

return price;

}

public void setPrice(float price) {

this.price = price;

}

// 花费 public abstract float cost();

}

2、定义具体类

咖啡父类

// 咖啡public class Coffee extends Drink {

@Override

public float cost() {

return super.getPrice();

}

}

低咖

// 低咖public class Decaf extends Coffee {

public Decaf() {

super.setDescription("Decaf");

super.setPrice(3.0f);

}

}

意大利浓咖啡

// 意大利浓咖啡public class Espresso extends Coffee {

public Espresso() {

super.setDescription("Espresso");

super.setPrice(4.0f);

}

}

美式咖啡

// 美式咖啡public class LongBlack extends Coffee {

public LongBlack() {

super.setDescription("LongBlack");

super.setPrice(6.0f);

}

}

黑咖啡

// 黑咖啡public class ShortBlack extends Coffee {

public ShortBlack() {

super.setDescription("ShortBlack");

super.setPrice(5.0f);

}

}

3、定义装饰类

调料父类

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 "[===="+super.getDescription() + "&&" + drink.getDescription()+"====]";

}

}

巧克力

public class Chocolate extends Decorator {

public Chocolate(Drink drink) {

super(drink);

super.setDescription("Chocolate");

super.setPrice(3.0f);

}

}

牛奶

public class Milk extends Decorator {

public Milk(Drink drink) {

super(drink);

super.setDescription("Milk");

super.setPrice(2.0f);

}

}

咖啡豆

public class Soy extends Decorator {

public Soy(Drink drink) {

super(drink);

super.setDescription("Soy");

super.setPrice(1.5f);

}

}

测试

public class CoffeeBar {

public static void main(String[] args) {

Drink order;

order = new Decaf();

System.out.println("order1 price:" + order.cost());

System.out.println("order1 desc:" + order.getDescription());

System.out.println("****************");

order = new LongBlack();

order = new Milk(order);

order = new Chocolate(order);

order = new Chocolate(order);

System.out.println("order2 price:" + order.cost());

System.out.println("order2 desc:" + order.getDescription());

}

}

运行结果:

order1 price:3.0

order1 desc:{描述:Decaf-3.0}

****************

order2 price:14.0

order2 desc:[===={描述:Chocolate-3.0}&&[===={描述:Chocolate-3.0}&&[===={描述:Milk-2.0}&&{描述:LongBlack-6.0}====]====]====]

总结

优点:

装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

缺点:

多层装饰比较复杂。

使用场景:

1、扩展一个类的功能。

2、动态增加功能,动态撤销。

注意事项:

动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性。可代替继承。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值