装饰者模式-Decorator笔记
装饰者模式-Decorator
概述
- 在不改变原有对象的基础之上,将功能附加到对象上
- 提供了比继承更有弹性的替代方案(扩展原有对象功能)
应用实例:
1、扩展一个类的功能或给一个类添加附加职责
2、动态的给一个对象添加功能,这些功能可以再动态的撤销
类型:结构型设计模式
角色
-
Component(抽象构件):它是具体构件和抽象装饰类的共同父类,声明了在具体构件中实现的业务方法,它的引入可以使客户端以一致的方式处理未被装饰的对象以及装饰之后的对象,实现客户端的透明操作。
-
ConcreteComponent(具体构件):它是抽象构件类的子类,用于定义具体的构件对象,实现了在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法)。
-
Decorator(抽象装饰类):它也是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现。它维护一个指向抽象构件对象的引用,通过该引用可以调用装饰之前构件对象的方法,并通过其子类扩展该方法,以达到装饰的目的。
-
ConcreteDecorator(具体装饰类):它是抽象装饰类的子类,负责向构件添加新的职责。每一个具体装饰类都定义了一些新的行为,它可以调用在抽象装饰类中定义的方法,并可以增加新的方法用以扩充对象的行为。
由于具体构件类和装饰类都实现了相同的抽象构件接口,因此装饰模式以对客户透明的方式动态地给一个对象附加上更多的责任,换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。
装饰模式的核心在于抽象装饰类的设计。
UML
优点
- 继承的有力补充,比继承灵活,不改变原有对象的情况下给一个对象扩展功能
- 通过使用不同装饰类以及这些装饰类的排列组合,可以实现不同效果
案例:煎饼加蛋加肠
使用继承实现案例:
- coding
煎饼类:价格8元
public class Pancake {
protected String getDesc(){
return "煎饼";
}
// 价格
protected int cost(){
return 8;
}
}
客户1:加1个鸡蛋,价格+1元
public class EggPancake extends Pancake {
@Override
protected String getDesc() {
return super.getDesc() + "加个蛋";
}
@Override
protected int cost() {
return super.cost() + 1;
}
}
客户2:加1个鸡蛋加1个肠 价格+2元
public class SausageEggPancake extends EggPancake {
@Override
protected String getDesc() {
return super.getDesc() + "加1个肠";
}
@Override
protected int cost() {
return super.cost() + 2;
}
}
public static void main(String[] args) {
Pancake battercake = new Pancake();
System.out.println(battercake.getDesc()+" 销售价格:"+battercake.cost());
Pancake battercakeWithEgg = new EggPancake();
System.out.println("客户1:"+battercakeWithEgg.getDesc()+" 销售价格:"+battercakeWithEgg.cost());
Pancake battercakeWithEggSausage = new SausageEggPancake();
System.out.println("客户2:"+battercakeWithEggSausage.getDesc()+" 销售价格:"+battercakeWithEggSausage.cost());
}
若此时客户3需要2个鸡蛋1个肠时,扩展将会越来越麻烦
使用装饰者模式实现
- coding
抽象煎饼
public interface IPancake {
String getDesc() ;
int cost() ;
}
具体煎饼
public class Pancake implements IPancake {
public String getDesc() {
return "煎饼";
}
// 价格
public int cost() {
return 8;
}
}
抽象装饰者
public abstract class PancakeDecorator implements IPancake {
IPancake pancake;
public PancakeDecorator(IPancake pancake) {
this.pancake = pancake;
}
@Override
public String getDesc() {
return this.pancake.getDesc();
}
@Override
public int cost() {
return this.pancake.cost();
}
}
鸡蛋装饰者
public class EggDecorator extends PancakeDecorator{
public EggDecorator(IPancake pancake) {
super(pancake);
}
@Override
public String getDesc() {
return super.getDesc() + "加1个蛋";
}
@Override
public int cost() {
return super.cost() + 1;
}
}
烤肠装饰者
public class SausageDecorator extends PancakeDecorator {
public SausageDecorator(IPancake pancake) {
super(pancake);
}
@Override
public String getDesc() {
return super.getDesc() + "加1个肠";
}
@Override
public int cost() {
return super.cost() + 2;
}
}
测试(客户端):需要2个蛋1个肠
public static void main(String[] args) {
IPancake ipancake = new Pancake();
ipancake = new EggDecorator(ipancake);
ipancake = new EggDecorator(ipancake);
ipancake = new SausageDecorator(ipancake);
System.out.println(ipancake.getDesc()+" 销售价格:"+ipancake.cost());
}
- UML
经典应用
Java IO中的应用
- BufferedReader
- BufferedInputStream
- BufferedOutputStream