装饰器设计模式是一种结构型设计模式,它允许在不影响同一类中其他对象行为的情况下,动态地向对象添加行为。
假设我们有一个披萨店,提供各种口味的披萨供客户选择,客户可以根据自己的需求添加额外的配料、奶酪或其他调料。现在假设我们选择了一种基本披萨,作为装饰器,我们可以根据需要向其添加额外的配料、奶酪或调料。这就是装饰器设计模式的作用,我们根据客户的需求向基本披萨的行为中添加更多的功能,而不是创建全新的披萨。
为什么需要装饰器设计模式?
为了回答这个问题,让我们考虑一个情况:你正在设计一个披萨店,顾客可以根据自己的需求下订单。现在假设你的店里有两种披萨:玛格丽特披萨和农家披萨。此外,你还提供一些额外的配料供顾客选择。假设有位顾客订购了农家披萨,并要求加入额外的配料。按照传统方式,你需要为农家披萨+额外配料创建一个新的类。
问题解决了吗?我们再看看。
假设另一天有位顾客订购了玛格丽特披萨+额外奶酪+额外调料,这时你又需要为这个组合创建一个新的类。这样会导致大量的类产生。

创建这么多类非常消耗资源,既不节省内存,也不节省时间。为了解决这个问题,我们将使用装饰器设计模式。我们将创建一个装饰器接口,由每个装饰器实现,并根据需要使用它们。

这个装饰器接口将基本披萨和装饰器区分开来。
因此,为了避免大量的子类,让代码变得复杂,我们需要装饰器设计模式。
装饰器设计模式的组件
1.Component(组件):这是定义由具体组件和装饰器实现的方法的接口或抽象类。2.Concrete Component(具体组件):这个类实现了Component接口并定义了基本行为。
1.Decorator(装饰器):这是实现Component接口的抽象类,它保持对Component对象的引用。它充当具体装饰器的基类,并为所有装饰器提供一个公共接口。2.Concrete Decorator(具体装饰器):这些类扩展Decorator类并添加额外的行为或状态。它们可以包装一个Component对象并动态修改其行为。
装饰器模式的流程
1.客户端代码使用Component接口或类创建一个特定的组件对象或装饰器链。2.装饰器可以叠加在一起,每个装饰器包装前一个装饰器或核心组件。3.每个装饰器在调用装饰对象的方法之前或之后添加自己的功能,从而修改了装饰对象的行为。4.客户端代码通过Component接口与装饰对象交互,不知道应用于它的具体装饰器。

装饰器设计模式的实现
为了看到装饰器设计模式的实现,我们将使用我们的披萨店例子。
在这里,披萨充当我们的组件接口,由不同类型的基本披萨和披萨装饰器接口实现。而我们的披萨装饰器接口由不同的基本装饰器实现。
披萨接口:
public interface Pizza {
public String getDescription();
public double getPrice();
}
玛格丽特披萨类:
public class Margherita implements Pizza {
Margherita(){};
@Override
public String getDescription(){
return "This is a Margherita Pizza";
}
@Override
public double getPrice(){
return 400.00;
}
}
农家披萨类:
public class FarmHouse implements Pizza {
FarmHouse(){};
@Override
public String getDescription(){
return "This is a Farm House Pizza";
}
@Override
public double getPrice(){
return 500.00;
}
}
披萨装饰器接口:
public interface PizzaDecorator extends Pizza {
}
这个接口只由装饰器实现,以区分基本披萨和装饰器。
奶酪类:
public class Cheese implements PizzaDecorator {
Pizza pizza;
Cheese(Pizza p){
this.pizza=p;
};
@Override
public String getDescription(){
return pizza.getDescription()+" with extra cheese";
}
@Override
public double getPrice(){
return pizza.getPrice()+10.00;
}
}
配料类:
public
class Toppings implements PizzaDecorator {
Pizza pizza;
Toppings(Pizza p){
this.pizza=p;
};
@Override
public String getDescription(){
return pizza.getDescription()+" with extra toppings";
}
@Override
public double getPrice(){
return pizza.getPrice()+50.00;
}
}
披萨店类:
public class PizzaShop {
public static void main(String[] args) {
Pizza margherita=new Margherita();
margherita=new Cheese(margherita);
margherita=new Toppings(margherita);
System.out.println(margherita.getDescription());
System.out.println(margherita.getPrice());
}
}
这样,我们可以轻松创建我们的披萨对象,并根据需要自定义它,而不改变其行为。
其他例子
为了演示装饰器模式的实际用途,让我们考虑一个电子商务应用程序。我们有一个基本的Product
类,代表一个通用的产品。我们可以应用DiscountDecorator
、ShippingDecorator
和GiftWrapDecorator
等装饰器,为产品添加折扣、运输选项和礼品包装等功能。这样,我们可以混合和匹配不同的装饰器,动态地创建各种功能组合。
装饰器设计模式的好处
装饰器设计模式提供了一些好处,包括灵活性、可扩展性和在运行时添加或修改行为的能力。它通过将关注点分离和最小化类的增加来促进代码的重用。然而,在将多个装饰器应用于一个对象时,需要考虑对性能和复杂性的潜在影响。
原文始发于微信公众号(小技术君):什么是装饰器设计模式?
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/149891.html