1。何为装饰者模式(Decorator Pattern)?
"动态地给一个对象天剑一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活"。
2。装饰模式类图
3。代码如下:
书本例子:我们以卡通片《猫和老鼠》(《Tom and Jerry》)为例,看看如何包装小Jerry让它更强大。
Component接口:
/**
* Component
* @author decorator
*/
public interface Animal {
public void doStuff();
}
ConcreteComponent类:
/**
* ConcreteComponent
* @author decorator
*/
public class Rat implements Animal {
public void doStuff() {
System.out.println("Jerry play ...");
}
}
Decorator接口:
/**
* Decorator
* @author decorator
*/
public interface Feature{
public void load();
}
ConcreteDecorator1:
/**
* ConcreteDecorator
* @author decorator
*/
public class FlyFeature implements Feature {
public void load() {
System.out.println("增加一双翅膀...");
}
}
ConcreteDecorator2:
/**
* ConcreteDecorator
* @author decorator
*/
public class DigFeature implements Feature{
public void load() {
System.out.println("增加钻地能力...");
}
}
DecorateComponent:
public class DecorateAnimal implements Animal {
//被包装的动物
private Animal animal;
//使用拿一个包装器
private Class<? extends Feature> clz;
public DecorateAnimal(Animal _animal,Class<? extends Feature> _clz) {
animal = _animal;
clz = _clz;
}
@Override
public void doStuff() {
InvocationHandler handler = new InvocationHandler() {
@Override //具体包装行为
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object obj = null;
if(Modifier.isPublic(method.getModifiers())) {
obj = method.invoke(clz.newInstance(), args);
System.out.println(method.getName());
}
animal.doStuff();
return obj;
}
};
//当前加载类
ClassLoader cl = this.getClass().getClassLoader();
//接口动态代理
Feature proxy = (Feature) Proxy.newProxyInstance(cl,
//clz.getInterfaces(),
new Class[]{Feature.class},
handler);
// Class proxyClass = Proxy.getProxyClass(
// Feature.class.getClassLoader(),
// new Class[]{Feature.class});
// Feature proxy = null ;
// try {
// proxy=(Feature) proxyClass
// .getConstructor(InvocationHandler.class)
// .newInstance(new Object[]{handler});
// } catch (Exception e) {
// e.printStackTrace();
// }
proxy.load();
}
public static void main(String[] args) {
Animal jerry = new Rat();
jerry = new DecorateAnimal(jerry, FlyFeature.class);
jerry = new DecorateAnimal(jerry, DigFeature.class);
jerry.doStuff();
}
}