在开发过程中,将工厂方法模式和代理模式结合对切面编程有很大的帮助;能在修改尽可能少的代码情况下实现功能。
现在有三个类Boy、Girl、Child都继承Person接口,并实现say方法,类实例的构造采用工厂方法模式,代码如下:
package com.proxy.test;
public interface Person {
void say();
}
package com.proxy.test;
public class Boy implements Person {
public void say() {
System.out.println("I am a boy!");
}
}
package com.proxy.test;
public class Girl implements Person {
public void say() {
System.out.println("I am a girl!");
}
}
package com.proxy.test;
public class Child implements Person {
public void say() {
System.out.println("I am a child!");
}
}
package com.proxy.test;
public class ObjFactory {
public static Person getObj(String objName) {
Person person = null;
if ("Boy".equalsIgnoreCase(objName)) {
person = new Boy();
} else if ("Girl".equalsIgnoreCase(objName)) {
person = new Girl();
} else if ("Child".equalsIgnoreCase(objName)) {
person = new Child();
}
if (null == person) {
throw new RuntimeException("unkown objName!");
}
return person;
}
}
测试类如下:
package com.proxy.test;
public class Test {
public static void main(String[] args) {
Person boy = ObjFactory.getObj("Boy");
boy.say();
Person girl = ObjFactory.getObj("Girl");
girl.say();
Person child = ObjFactory.getObj("Child");
child.say();
}
}
现在如果想在say方法前后添加“begin”和“end”之类的打印语句,如果修改所有的子类,需要修改的代码地方很多,而且当需求变动时不利于长期维护;下面是用java动态代理实现的方式:
首先,增加一个hanlder处理类:
package com.proxy.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class PersonHandler implements InvocationHandler {
// 目标对象
private Object target;
/**
* 构造方法
*
* @param target
* 目标对象
*/
public PersonHandler(Object target) {
super();
this.target = target;
}
/**
* 执行目标对象的方法
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// 在目标对象的方法执行之前简单的打印一下
System.out.println(target.getClass().getSimpleName() + "--"
+ method.getName() + "--begin");
// 执行目标对象的方法
Object result = method.invoke(target, args);
// 在目标对象的方法执行之后简单的打印一下
System.out.println(target.getClass().getSimpleName() + "--"
+ method.getName() + "--end");
return result;
}
/**
* 获取目标对象的代理对象
*
* @return 代理对象
*/
public Object getProxy() {
return Proxy.newProxyInstance(Thread.currentThread()
.getContextClassLoader(), target.getClass().getInterfaces(),
this);
}
}
然后,修改工厂方法:
package com.proxy.test;
public class ObjFactory {
public static Person getObj(String objName) {
Person person = null;
if ("Boy".equalsIgnoreCase(objName)) {
person = new Boy();
} else if ("Girl".equalsIgnoreCase(objName)) {
person = new Girl();
} else if ("Child".equalsIgnoreCase(objName)) {
person = new Child();
}
if (null == person) {
throw new RuntimeException("unkown objName!");
}
PersonHandler personHandler = new PersonHandler(person);
person = (Person) personHandler.getProxy();
return person;
}
}
标红色的为新增加的语句,可以看到使用代理时,只需要修改工厂方法类、添加一个处理类就可以达到效果。