3.装饰器模式完全遵守开闭原则,可以在不修改原有代码的基础上增加新的功能。
3.装饰器模式会影响对象的标识,当使用装饰器对对象进行包装时,对象的类型和行为可能会发生变化。
3.当需要为一批兄弟类进行改装或加装功能时,可以使用装饰器模式。例如,在一个图形界面工具箱中为多个不同的组件提供一些公共的功能时,可以使用装饰器模式来实现。
//抽象组件接口 public interface Shape { void draw(); } // 堆代码 duidaima.com //具体组件类:圆形 public class Circle implements Shape { @Override public void draw() { System.out.println("Drawing a circle"); } } //具体组件类:矩形 public class Rectangle implements Shape { @Override public void draw() { System.out.println("Drawing a rectangle"); } } 定义一个抽象装饰器类 ShapeDecorator 和两个具体装饰器类 RedShapeDecorator 和 GreenShapeDecorator, //抽象装饰器类 public abstract class ShapeDecorator implements Shape { //持有一个抽象组件对象 protected Shape shape; //构造方法 public ShapeDecorator(Shape shape) { this.shape = shape; } //调用被包装对象的方法 @Override public void draw() { shape.draw(); } } //具体装饰器类:红色装饰器 public class RedShapeDecorator extends ShapeDecorator { //构造方法 public RedShapeDecorator(Shape shape) { super(shape); } //重写draw方法,在调用被包装对象的方法之前或之后添加新的功能 @Override public void draw() { //调用被包装对象的方法 super.draw(); //添加新的功能 setRedBorder(); } //定义新的功能方法 private void setRedBorder() { System.out.println("Setting red border"); } } //具体装饰器类:绿色装饰器 public class GreenShapeDecorator extends ShapeDecorator { //构造方法 public GreenShapeDecorator(Shape shape) { super(shape); } //重写draw方法,在调用被包装对象的方法之前或之后添加新的功能 @Override public void draw() { //调用被包装对象的方法 super.draw(); //添加新的功能 setGreenBorder(); } //定义新的功能方法 private void setGreenBorder() { System.out.println("Setting green border"); } }编写装饰器模式测试代码,main 函数中创建了不同的组件和装饰器对象,并调用了它们的方法.
//测试类 public class DecoratorPatternDemo { public static void main(String[] args) { //创建一个圆形对象 Shape circle = new Circle(); //创建一个矩形对象 Shape rectangle = new Rectangle(); //创建一个红色装饰器对象,包装圆形对象 Shape redCircle = new RedShapeDecorator(circle); //创建一个绿色装饰器对象,包装矩形对象 Shape greenRectangle = new GreenShapeDecorator(rectangle); //调用各个对象的方法,展示不同的效果 System.out.println("Normal circle:"); circle.draw(); System.out.println("Normal rectangle:"); rectangle.draw(); System.out.println("Red circle:"); redCircle.draw(); System.out.println("Green rectangle:"); greenRectangle.draw(); } }输出结果如下:
Normal circle: Drawing a circle Normal rectangle: Drawing a rectangle Red circle: Drawing a circle Setting red border Green rectangle: Drawing a rectangle Setting green border
@Component public class Rectangle implements Shape { @Override public void draw() { System.out.println("Drawing a rectangle"); } } @Component public class Rectangle implements Shape { @Override public void draw() { System.out.println("Drawing a rectangle"); } }给具体装饰器类 RedShapeDecorator 和 GreenShapeDecorator 类添加 @Component 注解,
@Component public class GreenShapeDecorator extends ShapeDecorator { // 构造方法 public GreenShapeDecorator(@Qualifier("rectangle") Shape shape) { super(shape); } // 重写draw方法,在调用被包装对象的方法之前或之后添加新的功能 @Override public void draw() { // 调用被包装对象的方法 super.draw(); // 添加新的功能 setGreenBorder(); } // 定义新的功能方法 private void setGreenBorder() { System.out.println("Setting green border"); } } @Component public class RedShapeDecorator extends ShapeDecorator { // 构造方法 public RedShapeDecorator(@Qualifier("circle") Shape shape) { super(shape); } // 重写draw方法,在调用被包装对象的方法之前或之后添加新的功能 @Override public void draw() { // 调用被包装对象的方法 super.draw(); // 添加新的功能 setRedBorder(); } // 定义新的功能方法 private void setRedBorder() { System.out.println("Setting red border"); } }编写 Spring 项目测试代码
@SpringBootTest @RunWith(SpringRunner.class) public class DecoratorTest { // 从Spring容器中获取Context对象 @Autowired private RedShapeDecorator redCircle; @Autowired private GreenShapeDecorator greenRectangle; @Test public void test() { System.out.println("Red circle:"); redCircle.draw(); System.out.println("Green rectangle:"); greenRectangle.draw(); } }输出结果如下:
Red circle: Drawing a circle Setting red border Green rectangle: Drawing a rectangle Setting green border