什么是装饰器设计模式?

装饰器设计模式是一种结构型设计模式,它允许在不影响同一类中其他对象行为的情况下,动态地向对象添加行为。

假设我们有一个披萨店,提供各种口味的披萨供客户选择,客户可以根据自己的需求添加额外的配料、奶酪或其他调料。现在假设我们选择了一种基本披萨,作为装饰器,我们可以根据需要向其添加额外的配料、奶酪或调料。这就是装饰器设计模式的作用,我们根据客户的需求向基本披萨的行为中添加更多的功能,而不是创建全新的披萨。

为什么需要装饰器设计模式?

为了回答这个问题,让我们考虑一个情况:你正在设计一个披萨店,顾客可以根据自己的需求下订单。现在假设你的店里有两种披萨:玛格丽特披萨和农家披萨。此外,你还提供一些额外的配料供顾客选择。假设有位顾客订购了农家披萨,并要求加入额外的配料。按照传统方式,你需要为农家披萨+额外配料创建一个新的类。

问题解决了吗?我们再看看。

假设另一天有位顾客订购了玛格丽特披萨+额外奶酪+额外调料,这时你又需要为这个组合创建一个新的类。这样会导致大量的类产生。

什么是装饰器设计模式?

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

什么是装饰器设计模式?

这个装饰器接口将基本披萨和装饰器区分开来。

因此,为了避免大量的子类,让代码变得复杂,我们需要装饰器设计模式。

装饰器设计模式的组件

1.Component(组件):这是定义由具体组件和装饰器实现的方法的接口或抽象类。2.Concrete Component(具体组件):这个类实现了Component接口并定义了基本行为。

1.Decorator(装饰器):这是实现Component接口的抽象类,它保持对Component对象的引用。它充当具体装饰器的基类,并为所有装饰器提供一个公共接口。2.Concrete Decorator(具体装饰器):这些类扩展Decorator类并添加额外的行为或状态。它们可以包装一个Component对象并动态修改其行为。

装饰器模式的流程

1.客户端代码使用Component接口或类创建一个特定的组件对象或装饰器链。2.装饰器可以叠加在一起,每个装饰器包装前一个装饰器或核心组件。3.每个装饰器在调用装饰对象的方法之前或之后添加自己的功能,从而修改了装饰对象的行为。4.客户端代码通过Component接口与装饰对象交互,不知道应用于它的具体装饰器。

什么是装饰器设计模式?
1*gwmpO3omYAtXvuQi0-l3EA.png

装饰器设计模式的实现

为了看到装饰器设计模式的实现,我们将使用我们的披萨店例子。

在这里,披萨充当我们的组件接口,由不同类型的基本披萨和披萨装饰器接口实现。而我们的披萨装饰器接口由不同的基本装饰器实现。

披萨接口:

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类,代表一个通用的产品。我们可以应用DiscountDecoratorShippingDecoratorGiftWrapDecorator等装饰器,为产品添加折扣、运输选项和礼品包装等功能。这样,我们可以混合和匹配不同的装饰器,动态地创建各种功能组合。

装饰器设计模式的好处

装饰器设计模式提供了一些好处,包括灵活性、可扩展性和在运行时添加或修改行为的能力。它通过将关注点分离和最小化类的增加来促进代码的重用。然而,在将多个装饰器应用于一个对象时,需要考虑对性能和复杂性的潜在影响。


原文始发于微信公众号(小技术君):什么是装饰器设计模式?

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/149891.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!