闽公网安备 35020302035485号

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