装饰者模式,也称为包装模式是指在不改变原有对象的基础之上,将功能附加到对象上,提供了比继承更有弹性的替代方案(扩展原有对象的功能),属于结构型模式。
装饰者模式的核心是功能扩展。使用装饰者模式可以透明且动态地扩展类的功能。
装饰者模式主要用于透明且动态地扩展类的功能。其实现原理为:让装饰器实现被包装类相同的接口,并在构造函数中传入该接口对象,然后就可以在接口需要实现的方法中在被包装对象的现有功能上添加新的功能了。而且由于装饰器与被包装类属于同一类型,且构造器的参数为其实现接口类,因此装饰器模式具备嵌套扩展功能,这样就可以使用装饰器模式一层一层的对最底层被包装类进行功能扩展了。
1、抽象组件(Component):可以是一个接口或者抽象类,其充当被装饰类的原始对象,规定了被装饰对象的行为。
2、具体组件(ConcretrComponent):实现/继承Component的一个具体对象,也即被装饰对象。
3、抽象装饰器(Decorator):通用的装饰ConcretrComponent的装饰器,其内部必然有一个属性指向Component抽象组件;其实现一般是一个抽象类,主要是为了让其子类按照构造形式传入一个Component抽象组件,这是强制的通用行为(如果系统中装饰逻辑单一,并不需要实现许多装饰器,可以直接省略该类,直接实现具体装饰器(ConcreteDecorator)即可)。
4、具体装饰器(ConcreteDecorator):Decorator的具体实现类,理论上,每个ConcreteDecorator都扩展了Component对象的一种功能。
1、用于扩展一个类的功能或给要给类添加附加职责
2、动态的给要给对象添加功能,这些功能可以再动态的撤销
3、需要为一批的兄弟类进行改装或加装功能
本代码示例以购买煎饼此现实事例为例,通过购买不同需求的煎饼的不同,具体的实现也不同。
由于本例未使用装饰者模式,所以购买的煎饼种类为固定的,只可购买已书写的类中的煎饼,不可加量或是其他操作。
煎饼类:Battercake
public class Battercake {
protected String getMsg() {
return "煎饼";
}
public int getPrice() {
return 10;
}
}
鸡蛋煎饼类:BattercakeWithEgg
public class BattercakeWithEgg extends Battercake {
@Override
protected String getMsg() {
return super.getMsg() + "1个鸡蛋";
}
@Override
public int getPrice() {
return super.getPrice() + 1;
}
}
鸡蛋热狗煎饼类:BattercakeWithEggAndSausage
public class BattercakeWithEggAndSausage extends BattercakeWithEgg {
@Override
protected String getMsg() {
return super.getMsg() + "1个火腿";
}
@Override
public int getPrice() {
return super.getPrice() + 2;
}
}
测试类:BattercakeTest
public class BattercakeTest {
public static void main(String[] args) {
Battercake battercake = new Battercake();
System.out.println(battercake.getMsg() + "价格:" + battercake.getPrice());
BattercakeWithEgg battercakeWithEgg = new BattercakeWithEgg();
System.out.println(battercakeWithEgg.getMsg() + "价格:" + battercakeWithEgg.getPrice());
BattercakeWithEggAndSausage battercakeWithEggAndSausage = new BattercakeWithEggAndSausage();
System.out.println(battercakeWithEggAndSausage.getMsg() + "价格:" + battercakeWithEggAndSausage.getPrice());
}
}
该示例仍为购买煎饼,该例中通过使用装饰者模式,使得实现更加简便灵活。并且可实现购买的煎饼种类多样化,可实现配料加量等功能。
煎饼类:Battercake
public abstract class Battercake {
protected abstract String getMsg();
protected abstract int getPrice();
}
基础煎饼类:BaseBattercake
public class BaseBattercake extends Battercake {
@Override
protected String getMsg() {
return "煎饼";
}
@Override
protected int getPrice() {
return 10;
}
}
煎饼的抽象装饰器:BattercakeDecotator
public abstract class BattercakeDecotator extends Battercake {
private Battercake battercake;
public BattercakeDecotator(Battercake battercake) {
this.battercake = battercake;
}
protected abstract void doSomething();
@Override
protected String getMsg() {
return this.battercake.getMsg();
}
@Override
protected int getPrice() {
return this.battercake.getPrice();
}
}
鸡蛋装饰器:EggDecotator
public class EggDecotator extends BattercakeDecotator {
public EggDecotator(Battercake battercake) {
super(battercake);
}
@Override
protected void doSomething() {
}
@Override
protected String getMsg() {
return super.getMsg() + "1个鸡蛋";
}
@Override
protected int getPrice() {
return super.getPrice() + 1;
}
}
热狗装饰器:SausageDecorator
public class SausageDecorator extends BattercakeDecotator {
public SausageDecorator(Battercake battercake) {
super(battercake);
}
@Override
protected void doSomething() {
}
@Override
protected String getMsg() {
return super.getMsg() + "1个热狗";
}
@Override
protected int getPrice() {
return super.getPrice() + 2;
}
}
测试类:BattercakeTest
public class BattercakeTest {
public static void main(String[] args) {
Battercake battercake;
battercake = new BaseBattercake();
battercake = new EggDecotator(battercake);
battercake = new SausageDecorator(battercake);
System.out.println(battercake.getMsg() + "总价" + battercake.getPrice());
}
}
1、装饰器是继承的有力补充,比继承灵活,不改变原有对象的情况下动态地给一个对象扩展功能,即插即用
2、通过使用 不同装饰类以及这些装饰类的排列组合,可以实现不同效果
3、装饰器完全遵循开闭原则
1、会出现更多的代码,更多的类,增加程序复杂性
2、动态装饰时,多层装饰时会更复杂
1、装饰器强调自身功能的扩展,Decorator所做的就是增强ConcretrComponent的功能(也有可能是减弱功能),主体对象为ConcreteComponent,着重类功能的变化。
2、代理模式强调对代理过程的控制,Proxy完全掌握对RealSubject的访问控制,因此Proxy可以决定对RealSubject进行功能扩展,功能所见甚至功能散失(不调用RealSubject方法),主体对象为Proxy。
链接: 七大设计原则的简单解释(包含合成复用原则),简单理解、快速入门,具备案例代码.
链接: 工厂模式详解附有代码案例分析(简单工厂,工厂方法,抽象工厂).
链接: 单例模式详解及代码案例与应用场景(饿汉式单例模式、懒汉式单例模式、注册式单例模式).
链接: 原型模式详解附有代码案例分析(浅克隆和深克隆的相关解析).
链接: 建造者模式详解附有代码案例分析(包含建造者模式与工厂模式的区别分析).
链接: 门面模式详解附有代码案例分析.
链接: 装饰者模式详解附有代码案例分析.
链接: 享元模式详解附有代码案例分析(包含享元模式的源码应用分析——String中的享元模式应用、Integer中的享元模式应用).
链接: 组合模式详解附有代码案例分析(包含透明组合模式、安全组合模式的代码示例).
链接: 桥接模式详解附有代码案例分析.
链接: 适配器模式详解附有代码案例分析(包含类适配器、对象适配器以及接口适配器的代码示例).
链接: 委派模式详解附有代码案例分析(包含委派模式在JDK中的源码示例解析).
链接: 模板方法模式详解附有代码案例分析(包含模板方法模式重构JDBC操作业务代码示例).
链接: 策略模式详解附有代码案例分析(包含策略模式在源码中的应用以及代码示例).
链接: 责任链模式详解附有代码案例分析(包含责任链模式与建造者模式的结合代码案例).
链接: 迭代器模式详解附有代码案例分析(包含迭代器模式的源码应用分析).
链接: 命令模式详解附有代码案例分析(包含命令模式的源码应用分析).
链接: 状态模式详解附有代码案例分析(包含状态模式与其他相关设计模式的对比).
链接: 备忘录模式详解附有代码案例分析.
链接: 中介者模式详解附有代码案例分析.
链接: 解释器模式详解附有代码案例分析.
链接: 观察者模式详解附有代码案例分析(包含观察者模式使用JDK方式实现).
链接: 访问者模式详解附有代码案例分析.