装饰器模式概念
以下内容摘自菜鸟教程
意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。
何时使用:在不想增加很多子类的情况下扩展类。
如何解决:将具体功能职责划分,同时继承装饰者模式。
关键代码:
1、Component 类充当抽象角色,不应该具体实现。
2、修饰类引用和继承 Component 类,具体扩展类重写父类方法。应用实例:
1、孙悟空有 72 变,当他变成”庙宇”后,他的根本还是一只猴子,但是他又有了庙宇的功能。
2、不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。优点:
装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。缺点:多层装饰比较复杂。
使用场景:
1、扩展一个类的功能。
2、动态增加功能,动态撤销。注意事项:可代替继承。
装饰器,顾名思义,就是给我们的组件添加其原本不具有的属性或方法。由四部分组成,分别是:
Component(抽象组件):需要装饰类的抽象接口
ConcreteComponent(具体组件):需要装饰的类
Decorator(抽象装饰):装饰类的父类
ConcreteDecorator(具体装饰类):具体的装饰
案例
已知,有一只猫,它具有猫叫的方法,现在需要通过装饰器模式给其添加爬树方法。
Component
抽象组件,这里指动物接口,具有getAnimalProperty()方法
public interface Animal {
/**
* 描述动物特征
* @return void
* 时间:2018年4月25日
*/
public void getAnimalProperty();
}
ConcreteConponent
具体组件,这里指动物猫
public class Cat implements Animal{
@Override
public void getAnimalProperty() {
System.out.println("叫声:喵~");
}
}
Decorator
装饰器类,这里指爬树装饰器
public abstract class ClimbTreeDecorator implements Animal{
private Animal animal;
public ClimbTreeDecorator(Animal animal) {
this.animal = animal;
}
@Override
public void getAnimalProperty() {
animal.getAnimalProperty();
}
/**
* 爬树特征
* @return void
* 时间:2018年4月25日
*/
public abstract void climbTree();
}
ConcreteDecrator
具体装饰器类,这里主要负责爬树特征的实现
public class ConcreteClimbDecorator extends ClimbTreeDecorator{
public ConcreteClimbDecorator(Animal animal) {
super(animal);
}
@Override
public void climbTree() {
System.out.println("爬树");
}
@Override
public void getAnimalProperty() {
climbTree();
super.getAnimalProperty();
}
}
测试类
public class Test {
public static void main(String[] args) {
Animal cat = new Cat();
Animal animal = new ConcreteClimbDecorator(cat);
animal.getAnimalProperty();
}
}
总结
至此,装饰器模式就介绍完了。
其实装饰器模式很简单,我们首先理解装饰器模式的概念,它主要负责给一个已有的对象添加额外的属性或特征,这里,我们把添加叫做装饰。
而我们要如何给一个已有的对象装饰呢,要
- 先将该对象抽象化,创建它的父类接口
- 需要装饰的对象实现了这个父类接口
- 其次我们将装饰类抽象化,该抽象装饰类也实现了这个父类接口,同时通过组合的办法,注入需要装饰的对象,并且创建需要装饰的属性或方法
- 紧接着我们创建具体装饰类,继承这个抽象装饰类,那么其也就具有了父类的有参构造方法以及抽象的装饰方法,进行重写,再调用即可
另外
在这里我们比较一下装饰器模式和适配器模式
装饰器模式是给一个对象,添加全新的属性/方法,不影响其原本的属性/方法
而适配器模式是将一个对象中已有的属性/方法,装换成我们需要的属性/方法