上一篇:设计模式(八)——代理模式
下一篇:设计模式(十)——组合模式
一、需求
官方解释: Attach additional responsibilities to an object dynamically keeping the same interface.Decorators provide a flexible alternative to subclassing for extending functionality.(动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。)
我的理解: 装饰器模式就是给现有的类添加新的属性、新的方法,但是不能在现有类上做修改。所以只有两种方式,继承或组合:继承,新建一个类继承现有的类,然后给新类添加属性或方法;组合,新建一个类,将现有类引用注入新类,在新类中新增属性或方法。由于设计模式的原则是优先使用组合而非继承,所以我们要讲的装饰器模式是用组合方式实现的。
值得注意的是,装饰器和实体类都是继承于同一父类,参见代码1。RealImage和ImageDecorator都是继承于Image接口(专业说法为“实现于Image接口” 这里仅表达意思,读者自己懂就好)
参与者: AbstractComponent抽象组件、ConcreteComponent具体组件、AbstractDecorator抽象装饰类、ConcreteDecorator具体装饰类
类图:
二、代码
代码1——装饰器模式: 给图片加上白色背景色
package mypackage;
public class DesignPatternDemo {
public static void main(String[] args) {
Image image_decorator = new ImageDecorator(new RealImage());
image_decorator.display();
}
}
interface Image {
public void display();
}
class RealImage implements Image {
@Override
public void display() {
System.out.print("This is an Image");
}
}
class ImageDecorator implements Image {
private RealImage _image;
public ImageDecorator(RealImage _iImage) {
this._image = _iImage;
}
@Override
public void display() {
_image.display();
decorator();
}
public void decorator(){
System.out.println(" , BackColor: white");
}
}
输出1:
This is an Image , BackColor: white
通常来说,一个是实体类可以有多个装饰器类,但是一般一个装饰器类只作用一个实体类
代码2——装饰器模式扩展:
扩展起来也是非常方便的,可以在原有的装饰器中添加方法进一步装饰,也可以再次新建一个装饰器类用于装饰
package mypackage;
public class DesignPatternDemo {
public static void main(String[] args) {
Image image_decorator = new ImageDecorator(new RealImage());
image_decorator.display();
image_decorator=new ImageBorderDecorater(new RealImage());
image_decorator.display();
}
}
interface Image {
public void display();
}
class RealImage implements Image {
@Override
public void display() {
System.out.print("This is an Image");
}
}
class ImageDecorator implements Image {
private RealImage _image;
public ImageDecorator(RealImage _iImage) {
this._image = _iImage;
}
@Override
public void display() {
_image.display();
decorator();
decoratorForeColor();
}
public void decorator(){
System.out.print(" , BackColor: white");
}
public void decoratorForeColor(){
System.out.println(" , ForeColor: red");
}
}
class ImageBorderDecorater implements Image{
private RealImage _image;
public ImageBorderDecorater(RealImage _iImage) {
this._image = _iImage;
}
@Override
public void display() {
_image.display();
decoratorBorder();
}
public void decoratorBorder(){
System.out.print(" , Border_width: 1");
System.out.print(" , Border_style: Flat");
System.out.println(" , Border_color: blue");
}
}
输出2:
This is an Image , BackColor: white , ForeColor: red
This is an Image , Border_width: 1 , Border_style: Flat , Border_color: blue
三、小结
设计模式只重其意不重其形,装饰器模式就是新建一个装饰器类,将现有类引用注入装饰器类,在装饰器类中新增属性或方法,客户端只要操作装饰器类即可。
附:桥接模式、代理模式与装饰器模式对比
| 桥接模式 | 代理模式 | 装饰器模式 | |
|---|---|---|---|
| 关键类 | 多个维度,各个维度父类和子类 | 代理类 | 装饰类 |
| 继承关系 | 各个维度内父类和子类继承关系,便于面向接口编程,各个维度之间类与类没有关系,相互独立 | 实体类和代理类都继承于同一父类,它们与父类是继承关系,便于客户端面向接口编程 | 实体类和装饰类都继承于同一父类,它们与父类是继承关系,便于客户端面向接口编程 |
| 组合关系 | 各个维度之间类与类使用组合注入方式联系 | 实体类和代理类之间是组合关系,将实体类引用注入代理类,在代理类中调用实体类方法或属性 | 实体类和装饰类之间是组合关系,将实体类引用注入装饰类,在装饰类中调用实体类方法或属性,还有装饰类自己新增的方法和属性 |
| 联系 | 装饰器模式=代理模式+装饰方法 |
桥接模式:blog.csdn.net/qq_36963950…
代理模式:blog.csdn.net/qq_36963950…
装饰器模式:blog.csdn.net/qq_36963950…
上一篇:设计模式(八)——代理模式
下一篇:设计模式(十)——组合模式