装饰模式(Decorator)又被称为包装模式,是继承的一种替代方案,继承对类的扩展是编译时就确定的,装饰模式可以对客户端透明的方式扩展对象功能,扩展是动态的比继承更具灵活性。
举个例子就拿程序员平时爱喝的咖啡作为例子吧,很多人爱喝咖啡,有人喜欢加糖的,有人喜欢加奶的,有人喜欢加菊花的,也有人喜欢加芥末的。现在有个咖啡店如果利用继承来实现需要有个咖啡基类,然后继承后生成加糖的子类,加奶的子类,加菊花的子类等等,看着没有任何问题。
某一天来了一个人,他要一杯加糖加奶的咖啡,怎么办只要再生成一个加糖加奶的咖啡,然后又来一个人他想要一杯加糖加芥末的咖啡,。。。。如果再次扩大咖啡添加的种类,组合起来将是一个庞大的数目,这时装饰模式就派上了用场,利用装饰类就可以简单的生成添加了各种作料的咖啡。
装饰模式类图:
解释:
Component:抽象组件角色,一个接口。
ConcreteComponent:具体组件角色,具体的类,实现了方法。类似咖啡
Decorator:抽象装饰类,持有Component,具有和Component相同的接口方法
ConcreateDecorator:具体的装饰类,实现具体方法的扩展。
示例代码:
public interface ICoffee {
public void operation();
}
public class Coffee implements ICoffee{
@Override
public void operation() {
System.out.println("原始的咖啡制作工艺");
}
}
public class CDecorator implements ICoffee {
private ICoffee coffee;
public CDecorator(ICoffee coffee) {
this.coffee = coffee;
}
@Override
public void operation() {
coffee.operation();
}
}
public class MilkCDecorator extends CDecorator {
public MilkCDecorator(ICoffee coffee) {
super(coffee);
}
@Override
public void operation() {
super.operation();
System.out.println("add milk");
System.out.println("add milk hunhe");
}
}
public class SugarCDecorator extends CDecorator {
public SugarCDecorator(ICoffee coffee) {
super(coffee);
}
@Override
public void operation() {
super.operation();
System.out.println("add sugar");
System.out.println("add sugar hunhe");
}
}
public class Test {
public static void main(String[] args) {
Coffee coffee = new Coffee();
MilkCDecorator md = new MilkCDecorator(coffee);
SugarCDecorator sd = new SugarCDecorator(md);
sd.operation();
}
}
result:
原始的咖啡制作工艺
add milk
add milk hunhe
add sugar
add sugar hunhe
java源码中IO操作用到的流中使用了大量的装饰模式。