@装饰模式 属于结构型模式
定义:装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
要记住两点:可以动态的添加新的功能,同时又不改变原有结构(开闭原则)。要先添加新的功能又不改变原来的类,那我们怎么办呢?那我就新建一个类,这个类实现接口,还持有接口的引用。
我们要记住这里的实现接口和接口引用。如下接口
public interface Shape {
void draw();
}
在这个接口的继承链中我可以先看到两条。这两条分别是实现了这个接口的Shape——Rectangle和Shape——Circle。下面代码
public class Rectangle implements Shape{
public void draw(){
System.out.println("Shape:Rectangle");
}
}
public class Circle implements Shape {
@Override
public void draw() {
// TODO Auto-generated method stub
System.out.println("Shape:Circle");
}
}
上面的很容易理解,但是现在有一个情况就是要我们打印出Rectangle和Circle边界的颜色,但是我们没有办法修改上面的代码。这时候我们就要用到装饰者模式。
添加新的功能,打印边界的颜色,note:这里添加新功能不是在上面的代码中添加,不然就违背了开闭原则.我们要新建一个类ShapeDecorator (形状装饰者类)
代码如下
/**
*
* @author huxiongda
*抽象装饰模式
*/
public abstract class ShapeDecorator implements Shape{
protected Shape decoratorShape;
public ShapeDecorator(Shape decoratorShape){
this.decoratorShape=decoratorShape;
}
public void draw(){
decoratorShape.draw();
}
}
一看也很简单对吧,此时有了第三条继承链,分析下 上面的抽象类实现了Shape接口,重写了draw()方法,构造器中持有一个shape引用。在这里我们没有看到添加的功能,因为在下面的代码中
/**
*
* @author huxiongda
*具体装饰模式
*/
public class RedShapeDecorator extends ShapeDecorator{
public RedShapeDecorator(Shape decoratorShape) {
super(decoratorShape);
// TODO Auto-generated constructor stub
}
//重写draw方法
//并且在里面添加新的方法,从而遵守开闭原则
public void draw(){
decoratorShape.draw();
setRedBorder(decoratorShape);
}
private void setRedBorder(Shape decoratorShape){
System.out.println("Border Color:Red");
}
}
RedShapeDecorator(红色形状装饰者类)这个类不再是抽象类,在draw方法里面添加了打印边界颜色代码功能。
所有的代码都写完了,接下来就是写测试类
**
*
* @author huxiongda
*j
*/
public class DecoratorPatternDemo {
public static void main(String[] args) {
Shape circle =new Circle();
Circle circles=new Circle();
Shape redCircle=new RedShapeDecorator(new Circle());
Shape redRectangle=new RedShapeDecorator(new Rectangle());
System.out.println("Circle with normal border");
circle.draw();
circles.draw();
System.out.println("\nCircle of red border");
redCircle.draw();
System.out.println("\nRectangle of red border");
redRectangle.draw();
}
}
在来看下输出结果:
Circle with normal border
Shape:Circle
Shape:Circle
Circle of red border
Shape:Circle
Border Color:Red
Rectangle of red border
Shape:Rectangle
Border Color:Red
Shape:Circle
Shape:Circle
Circle of red border
Shape:Circle
Border Color:Red
Rectangle of red border
Shape:Rectangle
Border Color:Red