电脑网站建设服务器,oppo软件商城,网站开发多少钱,有含义的公司名一.概念
装饰器模式(Decorator Pattern)#xff0c;动态地给一个对象添加一些额外的职责#xff0c;就增加功能来说#xff0c;装饰器模式比生成子类更灵活。 —-《大话设计模式》
允许向一个现有的对象添加新的功能#xff0c;同时又不改变其结构。这种类型的设计模式属…一.概念
装饰器模式(Decorator Pattern)动态地给一个对象添加一些额外的职责就增加功能来说装饰器模式比生成子类更灵活。 —-《大话设计模式》
允许向一个现有的对象添加新的功能同时又不改变其结构。这种类型的设计模式属于结构型模式它是作为现有的类的一个包装。 这种模式创建了一个装饰类用来包装原有的类并在保持类方法签名完整性的前提下提供了额外的功能。
动态地给一个对象添加一些额外的职责。就增加功能来说装饰器模式相比生成子类更为灵活。 二.角色
Component抽象构件给出一个抽象接口装饰器模式中公共方法的类在装饰器模式结构图的顶层以规范准备接收附加责任的对象。ConcreteComponent具体构件是要动态扩展的对象转换器模式中具体的被装饰的类它继承自Component。Decorator装饰器持有一个构件(Component)对象的实例它是装饰器模式中的核心对象所有具体装饰器对象的父类完成装饰器的部分职能。可以只对被装饰的对象进行一些简单的包裹也可包含对Component中方法的实现。ConcreteDecorator具体装饰完成具体的装饰功能。装饰功能的实现是通过调用被装饰对象对应的方法加上装饰对象自身的方法。这是装饰器模式动机中的添加额外功能的关键。 三.优缺点
1.优点
装饰类和被装饰类可以独立发展不会相互耦合装饰模式是继承的一个替代模式装饰模式可以动态扩展一个实现类的功能。装饰模式与继承关系的目的都是要扩展对象的功能但是装饰模式可以提供比继承更多的灵活性。装饰模式允许系统动态决定“贴上”或者除掉一个“装饰”继承关系是静态的它在系统运行前就决定了通过使用不同的具体装饰类以及这些装饰类的排列组合设计师可以创造出很多不同行为的组合装饰者类可以在被装饰者的行为前面或后面加上自己的行为甚至取代被装饰者的行为达到特定的目的装饰者一般对组件的客户是透明的除非客户程序依赖于组件的具体类型
2.缺点
多层装饰比较复杂。由于使用装饰模式可以比使用继承关系需要较少数目的类。使用较少的类当然使设计比较易于进行。但是在另一方面使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难特别是这些对象看上去都很相像。
四.适用场景
运行时你需要动态地为对象增加额外职责时当你需要一个能够代替子类的类借助它提供额外方法时。在不影响其他对象的情况下以动态、透明的方式给单个对象添加职责处理那些可以撤销的职责当不能采用生成子类的方式进行扩充时。
五.装饰器模式与适配器模式的比较
共同点都拥有一个目标对象。装饰器通过包装一个装饰对象来扩展其功能而又不改变其接口这实际上是基于对象的适配器模式的一种变种。 不同点适配器模式需要实现另外一个接口而装饰器模式必须实现该对象的接口。适配器模式主要是为了接口的转换而装饰者模式关注的是通过组合来动态的为被装饰者注入新的功能或行为(即所谓的责任)。
适配器模式详解传送门JAVA设计模式-适配器模式_Mr Tang的博客-CSDN博客
六.实现
假设我去买咖啡首先服务员给我冲了一杯原味咖啡我希望服务员给我加些牛奶和白糖混合入原味咖啡中。使用装饰器模式就可以解决这个问题。
咖啡接口
定义了获取花费和配料的接口。
/*** 咖啡接口*/
public interface Coffee {/*** 获取价格* return*/public float getPrice();/*** 获取咖啡* return*/public String getCoffee();
}原味咖啡
实现Coffe接口花费1元配料中只有咖啡
/*** 原味咖啡类*/
public class OriginalCoffee implements Coffee {Overridepublic float getPrice() {return 1;}Overridepublic String getCoffee() {return 原味咖啡;}
}装饰器类
咖啡对象的装饰器类同样实现Coffee接口定义一个Coffe对象的引用在构造器中进行初始化。并且将getPrice和getCoffee()方法转发给被装饰对象。
/*** 咖啡的装饰器可以给咖啡添加各种配料* 该类是一个抽象类需要具体子类来实现*/
public class DecoratorAbstractCoffee implements Coffee {/*** 具体咖啡的接口*/protected final Coffee coffee;/*** 构造方法初始化咖啡对象的引用* param coffee*/public DecoratorAbstractCoffee(Coffee coffee) {this.coffee coffee;}/*** 获取价格装饰器父类中直接转发请求至引用对象* return*/Overridepublic float getPrice() {return coffee.getPrice();}/*** 获取咖啡装饰器父类中直接转发请求至引用对象* return*/Overridepublic String getCoffee() {return coffee.getCoffee();}
}具体的装饰器类
具体的装饰器类负责往咖啡中“添加”牛奶注意看getPrice方法和getCoffee()方法可以在转发请求之前或者之后增加功能。如果是代理模式这里的结构就有所不同通常代理模式根据运行时的条件来判断是否转发请求。
/*** 混合牛奶到蜂蜜中*/
public class CreamCoffee extends DecoratorAbstractCoffee {private float price (float) 0.5;/*** 调用父类的构造方法* param coffee*/public CreamCoffee(Coffee coffee) {super(coffee);}/*** 增加配料需要加钱* return*/Overridepublic float getPrice() {return coffee.getPrice()price;}/*** 对咖啡进行加工* return*/Overridepublic String getCoffee() {return coffee.getCoffee()添加牛奶;}
}
添加糖
另一个具体装饰器类用来给咖啡加蜂蜜一样的逻辑。
class HoneyCoffee extends DecoratorAbstractCoffee {private float price (float) 1.4;public HoneyCoffee(Coffee coffee) {super(coffee);}Overridepublic float getPrice() {return coffee.getPrice()price;}Overridepublic String getCoffee() {return coffee.getCoffee()添加蜂蜜;}
}客户端使用
public class DecoratorMain {public static void main(String[] args) {//是不是很像 javaIO中的 stream流Coffee coffee new CreamCoffee(new HoneyCoffee(new OriginalCoffee()));System.out.println(coffee.getCoffee());System.out.println(coffee.getPrice());}
}
七.装饰者模式在Spring Boot中的应用
装饰者模式在Spring Boot中有着广泛的应用主要用于动态地扩展和改变对象的行为和状态。以下是装饰者模式在Spring Boot中的一些常见应用
自定义异常处理Spring Boot允许你通过装饰者模式来为你的控制器添加自定义的异常处理。你可以创建一个异常处理器然后通过装饰者模式将其添加到Spring MVC的异常处理器链中。这样当控制器抛出异常时你的自定义处理器就会被调用。安全性控制Spring Security是Spring Boot中用于安全性控制的一个库。它使用了装饰者模式来动态地为请求添加安全性检查。你可以创建一个自定义的安全性过滤器然后将其添加到Spring Security的过滤器链中以实现自定义的安全性控制。响应式编程Spring WebFlux是Spring Boot中的响应式编程框架。它使用了装饰者模式来动态地为服务器端点添加响应式处理。你可以创建一个自定义的响应式处理器然后将其添加到WebFlux的处理器链中以实现自定义的响应式处理逻辑。拦截器Spring MVC允许你使用拦截器来在控制器处理请求之前或之后执行一些操作。拦截器实际上就是使用了装饰者模式。你可以创建一个自定义的拦截器然后将其添加到Spring MVC的拦截器链中以实现自定义的请求拦截和处理。
这些应用只是装饰者模式在Spring Boot中的一部分。事实上只要你需要动态地扩展和改变对象的行为和状态装饰者模式就可能是一个好的解决方案。
八.总结
装饰器模式是代替增加子类的一种解决方案体现了聚合/合成复用原则的思想尽量使用组合的方式来扩展功能这样就把基本功能和扩展功能解耦了使得代码可复用可维护灵活。关键点在于装饰器模式可以动态地为对象增加扩展功能。