文章目录
装饰器模式
装饰器模式又称为包装模式。可以动态的为一个对象增加新的功能。
装饰器模式是一种用于代替继承的技术,当每一个子类都有自己不同的特性,但我们需要让特性进行任意的组合。当使用继承的技术,会总造成组合爆炸,且有大量的代码重复。
我们可以对特性构造子类,通过子类委派机制增加到对象上。
我们还是拿动物举例进行说明:
public interface Animal {
public void doSomething();
}
用来实现最基本的功能
public class normalAnimal implements Animal{
public normalAnimal(){...};
public void doSomething();
}
装饰器
public abstract class Decorator implements Animal{
protected final Animal animal;
public Decorator(Animal animal){
this.animal = animal;
}
public void doSomething(){
animal.doSomething();
}
}
具体装饰
可以飞:
public class canFly extends Decorator{
public canFly(Animal animal){
super(animal);
}
public void doSomething(){
super.doSomething();
fly();
}
public void fly(){...}
}
可以游泳:
public class canSwim extends Decorator{
public canSwim(Animal animal){
super(animal);
}
public void doSomething(){
super.doSomething();
swim();
}
public void swim(){...}
}
在上面的例子中,我们先对Animal接口进行基本功能的实现,随后定义了抽象类Decorator装饰器,在装饰器中,首先我们需要注意的是它有一个rep为Animal animal,在构造函数中我们将会利用被传进来的animal,也就是我们想要装饰的对象对上面的rep进行赋值。随后对增加我们想要实现的新特性。
!!!这里体现了装饰器与普通的继承的不同,我们并不是简单的对父类的方法进行override,而是在保持父类特性的基础上(super的调用),对方法增加新的特性,这样做不仅减少了大量的代码重复,并且可以有效的增加新的特性,而不是去新建一个拥有各种特性的子类(组合爆炸)。
我们再来看一下在客户端代码中如何使用装饰器:
public class Client {
public static void main(String[] args) {
Animal a=new normalAnimal();
a.doSomething();
System.out.println("增加飞行特性");
canfly b=new canFly(a);
b.doSomething();
System.out.println("增加游泳特性");
canSwim c=new canSwim(b);
c.doSomething();
}
}
在客户端代码中,我们首先构造了可以实现最基础功能的a,随后用canFly与canSwim对其进行包装,最终生成了可以实现特性飞行与游泳的组合。
也可以使用
Animal c = new canSwim(new canFly(new normalAnimal()))进行一次性的修饰。
就像课程中所说,这样的过程就像是一层一层的穿衣服,我们可以通过一层一层的装饰来实现不同特性间的组合。
而不是将衣服全部脱下后再穿上与之前相同的衣服后再穿上一件特殊的衣服。