设计模式-Java实现装饰器模式
装饰器模式允许向一个现有的对象添加新的功能,同时又不改变其结构。通俗的说,装饰器模式可以给一个已经确定的对象添加额外功能而且不需要改变其类的代码。在Java中基础的IO流就运用了这种模式,装饰器模式主要有以下几种角色
- 抽象接口(装饰器类和被装饰类都需要实现或者间接实现此接口)
- 具体的被装饰类(实现抽象接口,原始对象比如IO中的节点流如FileInputStream)
- 抽象装饰器类(所有的装饰器的父类,实现抽象接口,在类内部持有抽象接口实例。)
- 具体的装饰器类(继承自抽象装饰器类,比如IO中的缓冲流BufferedInputStream)
下面我们通过画一个几何图形,然后给图形加上颜色等各种属性来一步步学习。
第一步实现抽象接口
package com.hubin.Decorator;
/**
* 步骤1:创建一个接口 (原始对象和装饰器都需要实现或者间接实现此接口)
* @author hubin
*
*/
public interface Shape {
void draw();
}
第二步实现原始对象(被装饰对象)
package com.hubin.Decorator;
/**
* 步骤2:继承接口的实体类
* 具体的实现对象,实现了抽象接口
* 被装饰器装饰的原始对象
*
*/
public class Rectangle implements Shape{
@Override
public void draw() {
System.out.println("形状:矩形");
}
}
package com.hubin.Decorator;
public class Cicle implements Shape{
@Override
public void draw() {
System.out.println("形状:圆形");
}
}
第三步实现抽象装饰器(所有装饰器的父类)
package com.hubin.Decorator;
/**
* 步骤3: 创建实现了接口的抽象装饰器类 是所有装饰器的父类
* 抽象装饰器:持有一个指向原始对象的接口对象, 并定义一个与抽象接口一致的接口
* (主要是为了实现装饰器功能的复用,即具体的装饰器A可以装饰另外一个具体的装饰器B,因为装饰器类也可以当做一个原始对象),
* 并持有一个原始对象,该对象其实就是被装饰的对象。如果不继承组件接口类,则只能为某个组件添加单一的功能,
* 即装饰器对象不能在装饰其他的装饰器对象)
*/
public abstract class ShapeDecorator implements Shape {
protected Shape decoratedShape;
public ShapeDecorator(Shape decoratedShape) {
this.decoratedShape = decoratedShape;
}
@Override
public void draw() {
//转发请求给组件对象,可以在转发前后执行一些附加动作
decoratedShape.draw();
}
}
第四步实现具体的装饰器
package com.hubin.Decorator;
/**
* 步骤4:创建一个继承了抽象装饰器类实体装饰器类
*
* 具体的装饰器类,实现具体要向被装饰对象添加的功能。用来装饰具体的组件对象或者另外一个具体的装饰器对象
* @author hubin
*
*/
public class RedOutlineDecorator extends ShapeDecorator{
public RedOutlineDecorator(Shape decoratedShape) {
super(decoratedShape);
}
@Override
public void draw() {
//这里可以选择性的调用父类的方法,如果不调用则相当于完全改写了方法,
// 实现了新的功能 如 super.draw();
decoratedShape.draw();
this.setRedOutLine(decoratedShape);
}
/**
* 扩展的方法
* @param decoratedShap
*/
private void setRedOutLine(Shape decoratedShap){
System.out.println("边:红色");
}
}
package com.hubin.Decorator;
public class BlueContentDecorator extends ShapeDecorator{
public BlueContentDecorator(Shape decoratedShape) {
super(decoratedShape);
}
@Override
public void draw() {
decoratedShape.draw();
this.setBlueContent(decoratedShape);
}
private void setBlueContent(Shape decoratedShap){
System.out.println("内容:蓝色");
}
}
第五步测试
package com.hubin.Decorator;
public class Test {
public static void main(String agrs[]){
Shape cicle = new Cicle();
Shape rectangle = new Rectangle();
System.out.println();
System.out.println("原始图形:");
cicle.draw();
rectangle.draw();
System.out.println();
System.out.println("给图形边加上颜色:");
RedOutlineDecorator redOutlineCicle = new RedOutlineDecorator(cicle);
RedOutlineDecorator redOutlineRectangle = new RedOutlineDecorator(cicle);
redOutlineCicle.draw();
redOutlineRectangle.draw();
System.out.println();
System.out.println("给图形内容加上颜色:");
BlueContentDecorator blueContentCicle = new BlueContentDecorator(redOutlineCicle);
BlueContentDecorator blueContentRectangle = new BlueContentDecorator(redOutlineRectangle);
blueContentCicle.draw();
blueContentRectangle.draw();
}
}
运行结果为: