装饰器模式
1、别称装饰模式,英文名Decorator
2、别称包装器模式,英文名Wrapper
出现背景
每个设计模式,都是大佬的血泪史,他们在做需求的时候,遇到这些问题,比如有1000个的函数,都需要增加一个计算函数执行时间的功能,你想想如果每个函数都去增加功能,多累啊,但是改出错怎么办,为了尽可能少的不修改原来的代码,出现了这个设计模式,常见的有Collections下synchronizedList方法,可以把
ArrayList与LinkedList转成线程安全的,靠的就是装饰器模式
1、同代理模式一样,都是通过不改变原有代码都基础上,为原有的方法增加那新的功能
2、代理模式是自己创建委托类对象,当然也是可以依赖传进来(通过构造方法)的委托类对象
3、而装饰器模式则依赖传进来的委托类对象
定义一个接口,表示具备的能力(功能)
public interface IExpression {
public void shout();
}
谁实现了此接口,说明具备叫喊的能力
创建Cat类,实现了IExpression接口
public class Cat implements IExpression{
@Override
public void shout() {
System.out.println("猫叫了一声");
}
}
猫具备喊叫能力,但是觉得猫只叫了一声,能不能这只猫叫之前再稍微厉害点,可我们不想再改代码了……怕改出错
创建第一个装饰器类
public class CatWrapper implements IExpression{
public IExpression iex;
public CatWrapper(IExpression iex) {
this.iex = iex; //持有传进来的委托类对象iex
}
@Override
public void shout() {
System.out.println("稍微厉害点的猫");
System.out.println("抖一抖胡子"); //为持有的委托类对象新增类能力
iex.shout();
}
}
1、它同样实现的是同一个接口
2、它需要持有实际需要增加功能的对象
3、在实际需要增加功能的方法中,加入需要的代码
再写一个装饰器类
public class MoreCatWrapper extends CatWrapper{
public MoreCatWrapper(IExpression iex) {
super(iex);
}
@Override
public void shout(){
System.out.println("大猫,比普通的更厉害");
System.out.println("跺一跺地板");
super.shout();
}
}
1、为了进一步的扩充功能,我们直接继承了原来的装饰器类,而不是在原始类上增加
入口类Main使用装饰器类
public class Main {
public static void main(String args[]) {
IExpression baseIex = new Cat();
baseIex.shout();
IExpression bigIex = new MoreCatWrapper(baseIex);
bigIex.shout();
}
}
输出结果:
猫叫了一声
大猫,比普通的更厉害
跺一跺地板
稍微厉害点的猫
抖一抖胡子
猫叫了一声
Anroid下的Wrapper模式,Activity就用了模式哦,请看源码
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory2,
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks2,
Window.OnWindowDismissedCallback, WindowControllerCallback,
AutofillManager.AutofillClient {
}
public class ContextThemeWrapper extends ContextWrapper {
}
public class ContextWrapper extends Context {
}
public abstract class Context {
}