装饰器模式(Decorator)
对客户透明的方式动态地给一个对象附加上更多的责任,同时又不改变其结构。装饰模式可以在不使用创造更多子类的情况下,将对象的功能加以扩展。
类图:
- 1.抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
- 2.具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类。
- 3.装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
- 4.具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。
继续学习
Java IO中就是典型的装饰器
1. //InputStream提供的基本方法(Component)
2. publicabstractclassInputStreamimplementsCloseable{
3.
4. }
1. //默认目标实现类(ConcreteComponent)
2. publicclassFileInputStreamextendsInputStream{
3.
4. }
1. /*装饰实现类(FilterInputStream)一定是继承或实现原始接口(InputStream)的,内部有包含一个原始接口的超类(其实就是某个默认目标实现类)*/
2. //Decorator
3. publicclassFilterInputStreamextendsInputStream{
4. /**
5. * The input stream to be filtered.
6. */
7. protectedvolatileInputStreamin;
8.
9. protectedFilterInputStream(InputStreamin){
10. this.in=in;
11. }
12. }
1. //具体装饰类(ConcreteDecorator)
2. publicclassBufferedInputStreamextendsFilterInputStream{
3.
4. publicBufferedInputStream(InputStreamin){
5. this(in, DEFAULT_BUFFER_SIZE);
6. }
7. }
1. //具体装饰类(ConcreteDecorator)
2. publicclassDataInputStreamextendsFilterInputStreamimplementsDataInput{
3.
4. publicDataInputStream(InputStreamin){
5. super(in);
6. }
7. }
装饰器模式优点:
- 1.装饰类和被装饰类可以独立发展,不会相互耦合。
- 2.装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。就增加功能来说,装饰器模式相比生成子类更为灵活。
适用场景:
- 1.扩展一个类的功能。2.动态增加功能,动态撤销。
由于你长时间工作,经常需要喝咖啡来提神,咖啡本身很苦,可加牛奶,也可加糖,或者都加。试试装饰器来装饰你的咖啡。
interface ICoffee {
void showCoffee();
float showPrice();
}
//原始咖啡
class Coffee implements ICoffee {
private String name;
private float price;
public Coffee(String name, float price) {
this.name = name;
this.price = price;
}
@Override
public void showCoffee() {
System.out.println(name + " coffee");
}
@Override
public float showPrice() {
return price;
}
}
//抽象装饰器
abstract class Decorator implements ICoffee {
private ICoffee coffee;
public void setCoffee(ICoffee coffee) {
this.coffee = coffee;
}
@Override
public void showCoffee() {
coffee.showCoffee();
}
@Override
public float showPrice() {
return coffee.showPrice();
}
}
//加糖咖啡
class Sugar extends Decorator {
@Override
public void showCoffee() {
System.out.println("加糖");
super.showCoffee();
}
@Override
public float showPrice() {
return super.showPrice() + 5;
}
}
//补全,加牛奶的咖啡
class Milk extends Decorator{
@Override
public void showCoffee() {
System.out.println("加牛奶");
super.showCoffee();
}
@Override
public float showPrice() {
return super.showPrice() + 10;
}
}
class SugarMilk extends Decorator {
@Override
public void showCoffee() {
System.out.println("加糖和牛奶");
super.showCoffee();
}
@Override
public float showPrice() {
return super.showPrice() + 15;
}
}
public class Main {
public static void main(String[] args) {
Coffee coffee = new Coffee("拿铁", 20);
//加糖
Decorator sugar = new Sugar();
sugar.setCoffee(coffee);
System.out.println(sugar.showPrice());
//补全,加糖,加牛奶的咖啡
Decorator sugarmilk = new SugarMilk();
sugarmilk.setCoffee(coffee);
sugarmilk.showCoffee();
System.out.println(sugarmilk.showPrice());
}
}