一,背景 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。
二,优缺点 优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
缺点:多层装饰比较复杂。
三,实现 基础接口
- public interface Component {
- void biu();
- }
复制代码 具体实现类
- public class ConcretComponent implements Component {
- public void biu() {
- System.out.println("biubiubiu");
- }
- }
复制代码 装饰类
- public class Decorator implements Component {
-
- public Component component;
-
- public Decorator(Component component) {
-
- this.component = component;
- }
-
- public void biu() {
-
- this.component.biu();
- }
- }
复制代码 具体装饰类
- public class ConcreteDecorator extends Decorator {
-
- public ConcreteDecorator(Component component) {
-
- super(component);
- }
-
- public void biu() {
-
- System.out.println("ready?go!");
- this.component.biu();
- }
- }
复制代码 测试
- Component component = new ConcreteDecorator(new ConcretComponent());
- component.biu();
复制代码 四,为何使用装饰器模式 一个设计模式的出现一定有他特殊的价值。仅仅看见上面的结构图你可能会想,为何要兜这么一圈来实现?仅仅是想要多一行输出,我直接继承ConcretComponent,或者直接在另一个Component的实现类中实现不是一样吗?
首先,装饰器的价值在于装饰,他并不影响被装饰类本身的核心功能。在一个继承的体系中,子类通常是互斥的。比如一辆车,品牌只能要么是奥迪、要么是宝马,不可能同时属于奥迪和宝马,而品牌也是一辆车本身的重要属性特征。但当你想要给汽车喷漆,换坐垫,或者更换音响时,这些功能是互相可能兼容的,并且他们的存在不会影响车的核心属性:那就是他是一辆什么车。这时你就可以定义一个装饰器:喷了漆的车。不管他装饰的车是宝马还是奥迪,他的喷漆效果都可以实现。
再回到这个例子中,我们看到的仅仅是一个ConcreteComponent类。在复杂的大型项目中,同一级下的兄弟类通常有很多。当你有五个甚至十个ConcreteComponent时,再想要为每个类都加上“ready?go!”的效果,就要写出五个子类了。毫无疑问这是不合理的。装饰器模式在不影响各个ConcreteComponent核心价值的同时,添加了他特有的装饰效果,具备非常好的通用性,这也是他存在的最大价值。
来源:51CTO技术博客
|
|
|
|
|