装饰器模式
1. 介绍
装饰器(Decorator Pattern)模式
属于结构型模式。装饰器模式可以在不修改原有类的情况下扩充新的功能。
简单理解:假如现在有许多塑料制品,它们都是白色的。如果我想要其他颜色的塑料制品,可以使用不同颜色的原料来制作不同颜色的塑料制品,但更简单的方式是将这些塑料制品装饰一下,给它们喷不同颜色的漆。
优点
- 在不影响其他对象的情况下,以动态的、透明的方式给单个对象添加职责。将目标对象传入装饰类,进而生成该对象的装饰对象,装饰对象在原有对象的基础上增加了新的属性和方法。
- 对象增加的职责可以撤销。由于装饰对象是额外生成的,如果装饰对象不符合我们的要求,我们可以直接使用原对象,也就相当于撤销了对对象增加的职责。
- 比静态继承更加灵活。与对象的静态继承相比,Decorator模式提供的更加灵活地向对象添加职责的方法,可以用在装饰类中添加方法或删除方法来达到增加职责和删除职责的作用。而继承则要求为每一种增加或删除职责的清况生成子类,这无疑会产生很多的子类。
缺点
- 接口的一致性。装饰类依赖的接口和被装饰类实现的接口最好是一样的,这样,这个装饰类才对所有的被装饰类对象都有作用。
- 不能认为包装对象和原有对象就是一样的。从某些方面看,包装对象和原有对象是不一样的,不能将两者等同。
2. 例子
有一个Shape接口,实现了这个接口的类有Circle和Rectangle,创建一个装饰类,增加画出有红色的图形的功能。
类图:
Shape接口
package decoratorPattern;
public interface Shape {
public void draw();
}
Circle类
Circle实现了Shape接口,代表的是圆。
package decoratorPattern;
public class Circle implements Shape {
@Override
public void draw() {
System.out.println("画一个圆");
}
}
Rectangle类
实现了Shape接口,代表的是长方形。
package decoratorPattern;
public class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("画了一个长方形");
}
}
ShapeDecorator抽象类
一个抽象类,实现了Shape接口,作为所有的装饰类的基础类,其他装饰类在此基础上增加责任。
package decoratorPattern;
public abstract class ShapeDecorator implements Shape {
Shape decoratorShape;
public ShapeDecorator(Shape decoratorShape) {
this.decoratorShape = decoratorShape;
}
@Override
public void draw() {
decoratorShape.draw();
}
}
RedShapeDecorator类
继承了ShapeDecorator这个抽象类,增加了画红色图形的功能。
package decoratorPattern;
public class RedShapeDecorator extends ShapeDecorator {
public RedShapeDecorator(Shape decoratorShape) {
super(decoratorShape);
}
public void setRedBorder() {
if(decoratorShape.getClass() == Circle.class) {
System.out.println("画了一个红色边框的圆");
}else {
System.out.println("画了一个红色边框的长方形");
}
}
}
测试类
新创建了Circle和Rectangle的实例,获取这两个对象的装饰对象,测试装饰对象新增的画红色图形的功能。
package decoratorPattern;
import org.junit.Test;
public class TestJ {
@Test
public void test1() {
Shape circle = new Circle();
Rectangle rectangle = new Rectangle();
circle.draw();
rectangle.draw();
System.out.println();
RedShapeDecorator redCircleDecorator = new RedShapeDecorator(circle);
RedShapeDecorator redRectangleDecorator = new RedShapeDecorator(rectangle);
redCircleDecorator.draw();
redRectangleDecorator.draw();
System.out.println();
redCircleDecorator.setRedBorder();
redRectangleDecorator.setRedBorder();
}
}
运行结果:
画一个圆
画了一个长方形
画一个圆
画了一个长方形
画了一个红色边框的圆
画了一个红色边框的长方形
3. 总结
装饰器模式:在不更改类的情况下,通过获取目标对象的装饰对象来实现为目标对象动态的增加一些额外的职责。