首页 > 代码库 > 设计模式之装饰器模式
设计模式之装饰器模式
装饰者模式属于结构型设计模式,它是作为现有的类的一个包装。
定义:在不必改变原类文件和使用继承的情况下,动态地给一个对象添加一些额外的功能。
问题描述:在软件系统中,有时候我们会使用继承来扩展对象的功能,但是由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性,并且随着子类的增多,各种子类的组合会导致更多子类的膨胀,系统将不易维护。
解决方案:使用装饰者模式,在不改变原有代码的情况下,创建一个装饰类来包装原有的类,提供一些额外的功能。
结构图:
说明:
1. Component:抽象构件角色,一般是一个接口,以规范准备接受附加责任的对象;
2. ConcreteComponent:具体构件角色,实现或重写了Component中的方法。
3. Decorator:装饰角色,一般是一个抽象类,持有一个Component对象的实例,并实现一个与抽象构件接口一致的接口。
4. ConcreteDecorator:具体装饰角色,继承父类Decorator,并重写父类中的方法,负责给构件对象添加附加的责任。
举个栗子:讲一个插花的故事。。。
我们现有一个白色的花瓶,十分好看,我们将要对它进行装饰,可以插入一些红玫瑰,也可以插入一些黄菊。于是在代码的世界里,我们要有一个抽象接口Vase和一个实现了Vase接口的花瓶类FlowerVase,一个持有Vase对象实例的装饰者类(接口或抽象类)FlowerVaseDecorator和两个负责给花瓶对象添加附加功能的具体装饰类,一个负责插入红玫瑰RoseFlowerVase,另一个负责插入黄菊AnthemisFlowerVase。具体实现方式如下:
1. 新建一个抽象接口Vase,花瓶和抽象装饰者都将实现这个接口,接口中定义了将要被实现的业务方法。代码如下:
2. 新建一个花瓶类FlowerVase,实现Vase接口中的方法。代码如下:
3. 新建一个抽象装饰者类FlowerVaseDecorator,它实现了Vase接口,并持有一个抽象接口Vase对象的引用,它只是简单地调用了成员变量的方法,具体职能的增加放入到了子类当中去实现。代码如下:
4. 新建一个负责插入红玫瑰的具体装饰类RoseFlowerVase和一个负责插入黄菊的具体装饰类AnthemisFlowerVase,两者均继承抽象装饰者类并重写其中的业务方法,在业务方法中加入新的职能---插花。代码如下:
5. 在类DecoratorFragment中使用FlowerVaseDecorator来装饰Vase对象。核心代码如下:
6. 运行后的效果,如图所示:
综上,我们并没有改变被装饰者---花瓶类,只是通过装饰者类对其进行了包装,然后提供了新的额外的功能,这样就避免了因为使用子类继承而导致类的个数急剧增加,且被装饰者和装饰者可以独立变化,方便扩展,符合开闭原则。
优点:
1. 可以动态地为类添加新的功能,且可以多次装饰,使用不同的装饰类进行组合可以实现复杂的功能;
2. 具体的被装饰类和装饰类可以独立变化,扩展方便。
缺点:多层装饰比较复杂。
适用场景:
1. 在不影响原有类的情况下,扩展一个类的功能;
2. 动态地增加或撤销功能。
设计模式之装饰器模式