引入
书接上回,我们来聊聊啥是装饰模式?
装饰模式(别名:包装器):动态地给对象添加一些额外的职责。
它是一种用于替代继承的模式,使用对象之间的关联关系取代类之间的继承关系
适合用装饰模式的场景
- 程序希望动态地增强类的某个对象的功能,而又不影响到该类的其他对象
- 采用继承来增强对象功能不利于系统的扩展和维护
在现实生活中,常常需要对现有产品增加新的功能或美化其外观,如房子装修、相片加相框等。
在软件开发过程中,有时想用一些现存的组件。这些组件可能只是完成了一些核心功能。但在不改变其结构的情况下,可以动态地扩展其功能。
所有这些都可以釆用装饰模式来实现。
装饰模式的结构
装饰模式主要包含以下角色。
抽象构件(Component)角色:定义一个抽象接口以规范准备接收附加责任的对象。
具体构件(Concrete Component)角色:实现抽象构件,通过装饰角色为其添加一些职责。
抽象装饰(Decorator)角色:继承抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
具体装饰(ConcreteDecorator)角色:实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
让麻雀多飞100米的例子
这里我专门改了一下,把抽象组件和抽象装饰的关系表现的更明显。
抽象装饰继承于抽象组件并将在其中引用抽象组件,这样才能二次封装这个被装饰者
抽象组件:
//小鸟抽象类(抽象组件),使用抽象组件更方便装饰者的扩展,抽象装饰继承于抽象组件,让装饰者也可以成为新被装饰者
public abstract class Bird {
public abstract int fly();
}
抽象装饰
//用一个抽象类继承抽象组件,可以保证具体装饰的扩展性
public abstract class Decorator extends Bird {
protected Bird bird;//拿抽象组件作为类成员
public Decorator(){
}
public Decorator(Bird bird){
this.bird = bird;
}
}
被装饰者
//返回100的麻雀
public class Sparrow extends Bird{
public final int distance = 100;
@Override
public int fly() {
return distance;
}
}
具体装饰
public class SparrowDecorator extends Decorator{
public final int distance = 50 ;
SparrowDecorator(Bird bird){
super(bird);
}
// 装饰者新添加的方法
private int eleFly(){
return distance;
}
//重写fly函数(其中再调用被装饰者的fly函数)
@Override
public int fly() {
int flyDistance = 0;
flyDistance = bird.fly()+eleFly();
return flyDistance;
}
}
调用程序
public class Application {
public void needBird(Bird bird){
int flyDistance = bird.fly();
System.out.println("这只鸟能飞行"+flyDistance+"米");
}
public static void main(String[] args) {
Application client = new Application();
Bird sparrow = new Sparrow();//被装饰者
Bird sparrowDecorator1 = new SparrowDecorator(sparrow);
client.needBird(sparrowDecorator1);//装饰者1
//这里就可以看出用Bird这个抽象组件的好处,装饰者1可以被装饰者2再次装饰
Bird sparrowDecorator2 = new SparrowDecorator(sparrowDecorator1);//装饰者2
client.needBird(sparrowDecorator2);
}
}