装饰者模式
概述
指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。
装饰者与被装饰者拥有共同的超类,继承的目的是继承类型,而不是行为
结构
Component:可以是接口或者是抽象类,被装饰的原始对象。
ConcreteComponent:组件具体实现类。Component的具体实现,被装饰的具体对象【即包含原有功能的对象】。
Decorator:抽象装饰者,新增装饰类,用来扩展原有Component类的功能,对于Component来说无须知道Decorator的存在,所以在它的属性中必然有一个private变量指向Component抽象组件。
ConcreteDecorator:装饰者的具体实现类。
实现
被装饰的原始对象
我们先定义一个人的抽象类,里面有运动的抽象方法
public abstract class Person {
/**
* Person 人有可以运动的抽象方法
*/
public abstract void sport();
}
被装饰的具体对象
这里是具体的一个普通人,作为一个普通人他当然会运动,当然在未被装饰的情况下他只会走路。
public class CommonPerson extends Person {
@Override
public void sport() {
System.out.println("普通人运动只会走路");
}
}
抽象装饰者
抽象装饰者保证了一个对抽象组件的引用,方便调用被装饰对象中的方法。在这里运动大师需要持有人(Person)的引用,方便教授他其他运动,最终成为运动健将。
public abstract class Master extends Person {
private Person mPerson;
public Master(Person person) {
mPerson = person;
}
@Override
public void sport() {
mPerson.sport();
}
}
装饰者具体实现类
这里有两个装饰者具体实现类,分别是宁泽涛跟邹市明,他们(装饰者)负责向普通人(被装饰者)教授游泳跟拳击。
public class Ningzetao extends Master {
public Ningzetao(Person person){
super(person);
}
@Override
public void sport() {
super.sport();
teachSwimming();
}
public void teachSwimming(){
System.out.println("宁泽涛教普通人游泳");
}
}
public class Zoushiming extends Master {
public Zoushiming(Person person){
super(person)
}
@Override
public void sport() {
super.sport();
teachBoxing();
}
public void teachBoxing(){
System.out.println("邹市明教普通人拳击");
}
}
客户端调用
public class Client {
public static void main (String[] args) {
//创建普通人,只会走路
CommonPerson mCommonPerson = new CommonPerson();
//宁泽涛教普通人学游泳,普通人学会了游泳
Ningzetao mNingzetao = new Ningzetao(mCommonPerson);
mNingzetao.sport();
//邹市明教普通人学拳击,普通人学会了拳击
Zoushiming mZoushiming = new Zoushiming(mCommonPerson);
mZoushiming.sport();
}
}
优点
装饰者模式比继承更具良好的扩展性,完美的遵循开闭原则,继承是静态的附加责任,装饰者则是动态的附加责任。
装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。
应用场景
- 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。
不能采用继承的情况主要有两类:
第一类是系统中存在大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长;
第二类是因为类定义不能继承(如final类) - 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
- 当对象的功能要求可以动态地添加,也可以再动态地撤销时。
参考链接:https://blog.csdn.net/jason0539/article/details/22713711
https://blog.csdn.net/u012440207/article/details/111070772