装饰模式
定义:
不改变类文件和继承的情况下,动态的为对象添加额外的职责
使用场景
- 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责
- 需要动态的给一个对象添加额外的功能,这些功能可以动态的撤销
- 当不能采用集成的方式对系统进行扩充或者采用集成不利于系统扩展和维护
装饰模式的写法
UML图如下:
- Component:抽象组件,给对象动态的添加职责。
- ConcreteComponent:组件具体实现类。
- Decorator:抽象装饰者,继承Component,从外类来拓展Component类的功能,但对于Component来说无需知道Decorator的存在。
- ConcreteDecorator:装饰者具体实现类
定义Component
//以小孩穿衣服为例
public abstract class Person {
/**
* 穿衣服
*/
public abstract void dressClothes();
}
创建ConcreteComponent
//创建一个小孩“萌萌”
public class MengMeng extends Person {
@Override
public void dressClothes() {
System.out.println("穿上裤子");
}
}
定义Decorator
/**
* 定义抽象装饰者 “家长”
*/
public abstract class Parent extends Person {
//对抽象组件的引用
private Person mPerson;
public Mother(Person mPerson) {
this.mPerson = mPerson;
}
@Override
public void dressClothes() {
//调用被装饰对象中的方法
mPerson.dressClothes();
}
}
创建ConcreteDecorator
/**
创建两个装饰者:父亲、母亲。萌萌作为被装饰者,现有的功能是“穿上了裤子”,父亲母亲为他添加额外的功能:“穿上外套”
“穿上鞋子”
*/
public class Mother extends Parent {
public Mother(Person mPerson) {
super(mPerson);
}
@Override
public void dressClothes() {
//这句是被装饰者本身所有的功能
super.dressClothes();
//这是额外添加的功能
dressOuterWear();
}
private void dressOuterWear() {
System.out.println("穿上外套");
}
}
//
public class Father extends Parent {
public Father(Person mPerson) {
super(mPerson);
}
@Override
public void dressClothes() {
//这句是被装饰者本身所有的功能
super.dressClothes();
//这是额外添加的功能
dressShoes();
}
private void dressShoes() {
System.out.println("穿上鞋子");
}
}
客户端调用
public class Client {
public static void main(String[] args){
//创建“萌萌”
MengMeng mengMeng = new MengMeng();
mengMeng.dressClothes();
//妈妈给他穿上外套,“萌萌”有了外套
Mother mother = new Mother(mengMeng);
mother.dressClothes();
//爸爸给他穿上鞋子,“萌萌”有了鞋子
Father father = new Father(mengMeng);
father.dressClothes();
}
}
我们可以看出当使用不同的装饰器的时候,就会实现不同的行为,这种行为是可以随时的添加去掉。这种模式有效的避免了使用继承方式带来的灵活性差,子类无限扩展的问题,同时具体的组建类和具体的装饰类可以根据实际需求创建新的,使用时进行组合即可,原有代码无须改变,当然上述的内容添加的单一的功能,可以使用装饰链来添加多个功能,但是装饰链不能过长,否则会影响效率,同时这种灵活的方式也会造成排错的困难加剧
new Father(new Mother(new MengMeng()));
Context#startActivity
我们先来看一下Context的UML图:
- Component:即是Context抽象类,即是抽象组件
- ConcreteComponent:即是ContextImpl,组件具体实现类。
- Decorator:即是ContextWrapper,抽象装饰者
- ConcreteDecorator:即是Activity、Service和Application,这些作为装饰器
ContextWrapper源码:
/**
这里省略多余的代码,可以看到这和我们上面所写的是一模一样的,同样是持有抽象组件的引用
*/
public class ContextWrapper extends Context {
Context mBase;
public ContextWrapper(Context base) {
mBase = base;
}
//省略代码 只看这个方法
@Override
public void startActivity(Intent intent) {
mBase.startActivity(intent);
}
.......
}