深入浅出学习和掌握Java中的装饰器设计模式
1.概述
今天,来讨论一种众所周知且常用的模式,称为装饰器设计模式(Decorator Design Pattern),简称 装饰模式 。通过下面简要描述,来初步掌握装饰模式的内涵精髓。
装饰器设计模式允许我们动态地向对象添加功能和行为,而不会影响同一类中其他现有对象的行为。
我们使用继承来扩展类的行为。 这发生在编译时,该类的所有实例都获得扩展行为。
装饰器设计模式允许我们在运行时向对象(而不是类)添加功能,并且可以根据我们的要求和选择将此自定义功能应用于单个对象。
● 装饰器模式允许用户在不改变其结构的情况下向现有对象添加新功能。 因此,原始类没有变化。
● 装饰器设计模式是一种结构模式,它为现有类提供了一个包装器。
● 装饰器设计模式使用 抽象类 或接口与组合来实现包装器。
● 装饰器设计模式创建装饰器类,它包装原始类并通过保持类方法的签名不变来提供其他功能。
● 装饰器设计模式最常用于应用单一责任原则,其由于我们将功能划分为具有独特关注领域的类。
● 装饰设计模式在结构上类似于责任链模式。
让我们通过一个例子以便来更好地理解装饰器设计模式场景和应用。
2.装饰模式实现步骤
2.1.设计接口和实现类
假设我们有一个 Shape 接口,它可以包括draw(),resize(),isHide()和description()。
清单-1:Shape接口代码
package design.decorator; public interface Shape { void draw(); void resize(); String description(); boolean isHide(); }
现在,我们有两个具体的Shape类——Circle和Rectangle,用来定义特定的形状。
下面是Circle的代码
清单-2:Circle类代码
package design.decorator;
public class Circle implements Shape {
@ Override
public void draw() {
System.out.println("Drawing Circle");
}
@Override
public void resize() {
System.out.println("Resizing Circle");
}
@Override
public String description() {
return "Circle object";
}
@Override
public boolean isHide() {
return false;
}
}
清单-3:Rectangle 类代码
package design.decorator; public class Rectangle implements Shape { @Override public void draw() { System.out.println("Drawing Rectangle"); } @Override public void resize() { System.out.println("Resizing Rectangle"); } @Override public String description() { return "Rectangle object"; } @Override public boolean isHide() { return false; } }
2.2.设计实现装饰器抽象类
现在,我们来看看装饰部分。 到目前为止,一切都很好,我们可以画圆和矩形(Circle 和 Rectangle)。 但是,我们希望为Shape提供一些额外的功能,如填充颜色、线条颜色、线条细度,线条样式等。
首先,我们将创建一个实现Shape的抽象包装器(装饰器)类。 我将在这个例子中使用ShapeDecorator。
清单-4:装饰器抽象类
package design.decorator; public abstract class ShapeDecorator implements Shape { protected Shape decoratedShape; public ShapeDecorator(Shape decoratedShape) { super(); this.decoratedShape = decoratedShape; } }
定义为抽象类以避免任何直接实例化,因为这只是一个包装器并且不会在Shape中添加任何功能。 另外,我已经实现了Shape,允许在这种情况下为所有已定义的具体Shape类(Circle和Rectanagle)添加其他功能。
另外,(在实际应用中根据需要,创建一些必要的的辅助类)为形状创建Color和LineStyle的枚举。 下面是Color的枚举:
清单-5:Color枚举
package design.decorator; public enum Color { RED, GREEN , BLUE , YELLOW, WHITE, BLACK , ORANGE, MAROON }
清单-6:LineStyle枚举
package design.decorator; public enum LineStyle { SOLID, DASH, DOT, DOUBLE_DASH, DASH_SPACE }
2.3.实现装饰器实体类
主要包括4个装饰器实现类,分别填充颜色、线条颜色、线条细度,线条样式4个装饰器实现类。分别描述如下:
创建FillColorDecorator以在形状中添加填充颜色的功能。
清单-7:FillColorDecorator类代码
package design.decorator; public class FillColorDecorator extends ShapeDecorator { protected Color color; public FillColorDecorator(Shape decoratedShape, Color color) { super(decoratedShape); this.color = color; } @Override public void draw() { decoratedShape.draw(); System.out.println("Fill Color: " + color); } // 没有改变功能 // 如果喜欢可以添加功能. 除了维护Shape API的结构外,没有限制 @Override public void resize() { decoratedShape.resize(); } @Override public String description() { return decoratedShape.description() + " filled with " + color + " color."; } // 功能没有改变 @Override public boolean isHide() { return decoratedShape.isHide(); } }
创建LineColorDecorator以在形状中添加线条颜色的功能。
清单-8:LineColorDecorator类代码
package design.decorator; public class LineColorDecorator extends ShapeDecorator { protected Color color; public LineColorDecorator(Shape decoratedShape, Color color) { super(decoratedShape); this.color = color; } @Override public void draw() { decoratedShape.draw(); System.out.println("Line Color: " + color); } // 功能不变 @Override public void resize() { decoratedShape.resize(); } @Override public String description() { return decoratedShape.description() + " drawn with " + color + " color."; } // 功能不变 @Override public boolean isHide() { return decoratedShape.isHide(); } }
创建LineThicknessDecorator以在形状中添加自定义线条粗细的功能。
清单-9:LineThicknessDecorator类
package design.decorator; public class LineThinknessDecorator extends ShapeDecorator { protected double thickness; public LineThinknessDecorator(Shape decoratedShape, double thickness) { super(decoratedShape); this.thickness = thickness; } @Override public void draw() { decoratedShape.draw(); System.out.println("Line thickness: " + thickness); } // 功能不变 @Override public void resize() { decoratedShape.resize(); } @Override public String description() { return decoratedShape.description() + " drawn with line thickness " + thickness + "."; } // 功能不变 @Override public boolean isHide() { return decoratedShape.isHide(); } }
创建LineStyleDecorator以在形状中添加自定义线型的功能。
清单-10: LineStyleDecorator类代码
package design.decorator; public class LineStyleDecorator extends ShapeDecorator { protected LineStyle style; public LineStyleDecorator(Shape decoratedShape, LineStyle style) { super(decoratedShape); this.style = style; } @Override public void draw() { decoratedShape.draw(); System.out.println("Line Style: " + style); } // 功能不变 @Override public void resize() { decoratedShape.resize(); } @Override public String description() { return decoratedShape.description() + " drawn with " + style + " lines."; } //功能不变 @Override public boolean isHide() { return decoratedShape.isHide(); } }
2.4.创建装饰器调用主程序
创建一个示例主程序来执行和测试装饰器代码。
清单-11:调用测试主类
package design.decorator; public class Main { public static void main(String[] args) { System.out.println("Creating Simple Shape Objects..."); Shape rectangle = new Rectangle(); Shape circle = new Circle(); System.out.println("Drawing Simple Shape Objects..."); rectangle.draw(); System.out.println(); circle.draw(); System.out.println(); System.out.println("Creating Decorated Circle with Red Color, Blue Lines in dash pattern and thickness of 2 ..."); Shape circle1 = new FillColorDecorator(new LineColorDecorator(new LineStyleDecorator( new LineThinknessDecorator(new Circle(), 2.0d), LineStyle.DASH), Color.BLUE), Color.RED); circle1.draw(); System.out.println(); // 这里装饰器顺序不是非常重要,因为相应装饰器功能单一. // 我们也可以在单独的语句中嵌套功能来实现。 System.out.println("creating object with similar functionalities in separate statements."); Circle c = new Circle(); LineThinknessDecorator lt = new LineThinknessDecorator(c, 2.0d); LineStyleDecorator ls = new LineStyleDecorator(lt, LineStyle.DASH); LineColorDecorator lc = new LineColorDecorator(ls, Color.BLUE); FillColorDecorator fc = new FillColorDecorator(lc, Color.RED); Shape circle3 = fc; circle3.draw(); System.out.println(); System.out.println("Creating Decorated Circle with Green Color, Black Lines ..."); Shape circle2 = new FillColorDecorator(new LineColorDecorator(new Circle(), Color.BLACK), Color.GREEN); circle2.draw(); System.out.println(); System.out.println("Creating Decorated Rectange with Yellow Color, Red Lines in double dash pattern..."); Shape rectangle1 = new FillColorDecorator(new LineColorDecorator(new Rectangle(), Color.RED), Color.YELLOW); rectangle1.draw(); System.out.println(); } }
运行程序输出参考结果如下:
可以看到,我们没有更改核心类——Shape,Circle和Rectangle。 只是通过创建包装器和装饰器类,我们添加并自定义了Shape,Circle和Rectangle的行为,并已完成它们。 通过这个示例,希望我们现在对装饰设计模式很清楚。
装饰器模式的应用,这里主要要注意的就是这样几点:
1) 接口和实现类——需要装饰的对象类;
2) 抽象装饰器类——实现不破坏已有实现类的包装;
3) 实现装饰器类——基于不同的需要,完成各自最终的装饰工作。
好了,就写这些了。就请多关注本头条号吧^_^