浅论工厂方法模式和代理模式的结合

来源:互联网 发布:你好我是淘宝客服 编辑:程序博客网 时间:2024/05/16 14:35

在开发过程中,将工厂方法模式和代理模式结合对切面编程有很大的帮助;能在修改尽可能少的代码情况下实现功能。

现在有三个类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;
 }
}

标红色的为新增加的语句,可以看到使用代理时,只需要修改工厂方法类、添加一个处理类就可以达到效果。

 

0 0