装饰器模式(Decorator Pattern)就是在不改变原始对象本质的前提下,对现有类进行包装,从而提供出额外的功能。
不改变现有类而提供额外的功能,听起来好像是说类继承,没错,装饰器模式就是继承的另一种代替方案,使用继承方式为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀,所以装饰器模式比起类继承实现更加的灵活。
装饰器模式的核心就是功能扩展。设计模式类型属于结构型模式。就是是作为现有的类的一个包装。
我们用代码实现一下:
目的:
给一个图形附上一些色彩,图形依旧是图形(原始类不变),但是通过装饰类,我们给各个图形附上色彩。
一、原始现有类
1.建一个接口
package com.xing.design.decorator;
public interface Shape {
void draw();
}
2.两个图形实现类
package com.xing.design.decorator;
public class Rectangle implements Shape{
@Override
public void draw() {
System.out.println("Shape的实现类 Rectangle->矩形");
}
}
package com.xing.design.decorator;
public class Circle implements Shape{
@Override
public void draw() {
System.out.println("Shape的实现类Circle->圆形");
}
}
3.现在就是现有类,画出两个图形。
二、建立装饰器
1.搞个抽象装饰类
package com.xing.design.decorator;
public abstract class ShapeDecorator implements Shape {
protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape){
this.decoratedShape = decoratedShape;
}
public void draw(){
decoratedShape.draw();
}
}
2.继承抽象类
package com.xing.design.decorator;
public class RedShapeDecorator extends ShapeDecorator {
public RedShapeDecorator(Shape decoratedShape) {
super(decoratedShape);
}
@Override
public void draw() {
decoratedShape.draw();
setRedBorder(decoratedShape);
}
private void setRedBorder(Shape decoratedShape){
System.out.println("以上图形是红色的: Red");
}
}
3.调用测试一下
package com.xing.design.decorator;
public class DecoratorPattern {
public static void main(String[] args) {
Shape circle = new Circle();
System.out.println("原始类画图:");
circle.draw();
Rectangle rectangle = new Rectangle();
System.out.println("原始类画图:");
rectangle.draw();
ShapeDecorator redCircle = new RedShapeDecorator(new Circle());
ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());
System.out.println("\n装饰类1的画图:");
redCircle.draw();
System.out.println("\n装饰类2的画图:");
redRectangle.draw();
}
}
装饰器模式的实现原理:
让装饰器实现与被装饰类相同的接口,使得装饰器与被扩展类类型一致,并在构造函数中传入该接口对象,然后在实现这个接口的被包装类对象的现有功能上添加新功能。由于装饰器与被包装类属于同一类型(实现自同一接口),且构造函数的参数为其实现接口类,因此装饰器模式具备嵌套扩展功能,这样就能使用装饰器模式一层一层地对底层被包装类进行功能扩展了。
总结:
我们在没有改变图形类的前提下,添加了图形是红色的说明。用装饰类来包装原有的图形类,并在保持类方法签名完整性的前提下,提供了额外的功能。
END