用动态代理可能产生一种比装饰器模式更接近混型模式的机制,用动态代理,产生的类型就是已经被混合后产生的组合类型。由于动态代理的限制,每个参与混型的类都必须实现某个或某些接口。
class MixinProxy implements InvocationHandler{
Map<String,Object> delegatesByMethod;
public MinxinProxy(TwoTuple<Object,Class<?>>...pairs){
delegatesByMethod = new HashMap<String,Object>();
for(TwoTuple<Object,Class<?>> pair : pairs){
for(Method method:pair.second.getMethods()){
String methodName = method.getName();
//The first interface in the map implements the method
if(!delegatesByMethod.containsKey(methodName)){
delegatesByMethod.put(methodeName,pair.first);
}
}
}
}
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
String methodName = method.getName();
Object delegate = delegatesByMethod.get(methodName);
return method.invoke(delegate,args);
}
public static Object newInstance(TwoTuple...pairs){
Class[] interfaces = new Class[pairs.length];
for(int i = 0; i < pairs.length; i++){
interfaces[i] = (Class)pairs[i].second;
}
ClassLoader cl = pairs[0].first.getClass().getClassLoader();
return Proxy.newProxyInstance(cl,interfaces,new MixinProxy(pairs));
}
public class DynamicProxyMixin{
public static void main(String[] args){
Object mixin = MixinProxy.newInstance(tuple(new BasicImp(),Basic.class),tuple(new TimeStampedImp(),TimeStamped.class),tuple(new SerialNumberedImp(),SerialNumber.class));
Basic b = (Basic)mixin;
TimeStamped t = (TimeStamped)mixin;
SerialNumbered s = (SerialNumbered)mixin;
b.set("hello");
System.out.println(b.get());
System.out.println(t.getStamp());
System.out.println(s.getSerialNumer());
}
}/*output:
Hello
1132519137015
1