装饰器模式是一种非常有用的结构型模式,它允许我们在不改变类的结果的情况下,为类添加新的功能。
我们来举例说明一下。首先添加一组形状,它们都实现了形状接口。
public interface Shape {
String getShape();
}
class Square implements Shape{
@Override
public String getShape() {
return "正方形";
}
}
class Circle implements Shape{
@Override
public String getShape() {
return "圆";
}
}
然后再来定义装饰器。装饰器同样需要实现Shape接口,而且在装饰器中还需要对Shape进行补充(也就是装饰)。
public abstract class ColorDecorator implements Shape {
protected Shape shape;
public ColorDecorator(Shape shape) {
this.shape = shape;
}
}
class RedDecorator extends ColorDecorator {
public RedDecorator(Shape shape) {
super(shape);
}
@Override
public String getShape() {
return "红色的" + shape.getShape();
}
}
class BlueDecorator extends ColorDecorator {
public BlueDecorator(Shape shape) {
super(shape);
}
@Override
public String getShape() {
return "绿色的" + shape.getShape();
}
}
最后再来验证一下。我们成功在没有修改形状类的前提下,为形状增加了颜色的功能。
public void run() {
Shape square = new Square();
Shape circle = new Circle();
Shape redSquare = new RedDecorator(square);
Shape blueCircle = new BlueDecorator(circle);
System.out.println(redSquare.getShape());
System.out.println(blueCircle.getShape());
}
装饰器模式在很多地方都有使用。在Java里面最经典的使用场景就是Java那一大堆的IO类,例如BufferedInputStream
或者 FileOutputStream
这样的。Java的IO类库通过多个不同IO类的嵌套,可以实现多种功能(例如缓存)的组合。当然其实Java的IO库是一个反面教材,由于装饰器模式的过度使用,导致系统中类太多太复杂,反而不利于我们学习和使用。在实际使用中我们也要注意设计模式的合理使用,不要为了使用而使用。