代理设计模式
代理设计模式是在JAVA开发中使用较多的一种设计模式,是指用一个代理主题来操作真实主题,真实主题执行具体的业务操作,而代理主题负责其他相关业务的处理。
这里以数据库数据写入为例:
在进行数据库数据写入时,要先连接数据库,然后进行数据处理,接下来才是向数据库中写入数据,最后关闭数据库。而用户最关心的只有将数据写入数据库中这一步操作,而其他操作都是为写入数据而做准备,这不是用户所关心的。
静态代理设计模式实现
package com.cn.test;
interface IMemberService{
public void add ();
}
/**
*真实主题类
*/
class MemberServiceImpl implements IMemberService{
@Override
public void add() {
System.out.println("【真实业务主题】:向数据库中执行添加操作");
}
}
/**
*代理主题类
*/
class MemberServiceProxy implements IMemberService{
private IMemberService realSubject; //真实的业务操作
public MemberServiceProxy(IMemberService realSubject){
this.realSubject = realSubject;
}
public boolean connect(){
System.out.println("【代理主题】:进行数据库的访问链接。。。");
return true;
}
public void transaction(){
System.out.println("【代理主题】:事务提交,进行数据更新处理。。。");
}
@Override
public void add() {
if (connect()) {
this.transaction();
this.realSubject.add();
this.close();
}
}
public void close(){
System.out.println("【代理主题】:关闭数据库。。。");
}
}
/**
*工厂类
*/
class Factory{
private Factory(){}
public static IMemberService getInstance(){
return new MemberServiceProxy(new MemberServiceImpl());
}
}
/**
*测试类
*/
public class TestDemo {
public static void main(String[] args) {
IMemberService memberService = Factory.getInstance();
memberService.add();
}
}
但是静态代理设计模式还有一些弊端,在一个数据库里面不会只有一张表,有可能会存在几十上百张表,这样将会实现几十上百个接口,这个时候代理将会有出现大量代理,而且所有的代理步骤几乎雷同。要想解决这种代码重复的问题,就只能利用动态代理设计模式。
动态代理设计模式
-
创建一个实现接口InvocationHandler的类,它必须实现
invoke(Object obj , Method method, Object[] args) -
创建被代理的类以及接口
-
调用Proxy的静态方法,创建一个代理类
newProxyInstance(ClassLoaderloader , Class<?> interfaces , InvocationHandlerh) -
通过代理调用方法
实现如下:
package com.cn.test;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
*接口
*/
interface IMemberService{
public void add ();
}
/**
*被代理类
*/
class MemberServiceImpl implements IMemberService{
@Override
public void add() {
System.out.println("【真实业务主题】:向数据库中执行添加操作");
}
}
/**
*代理类,实现InvocationHandler接口
*/
class ServiceProxy implements InvocationHandler {
private Object target; //真实业务主题对象
/**
* 绑定真实主题对象,同时返回代理实例
* @param target 真正的接口操作对象。利用反射可以追溯其来源
* @return 代理对象
*/
public Object bind(Object target){
this.target = target; //保存真实业务对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
public boolean connect(){
System.out.println("【代理主题】:进行数据库的访问链接。。。");
return true;
}
public void transaction(){
System.out.println("【代理主题】:事务提交,进行数据更新处理。。。");
}
public void close(){
System.out.println("【代理主题】:关闭数据库。。。");
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object returnValue = null;
if (connect()) {
this.transaction();
returnValue = method.invoke(this.target,args); // 调用真实业务主题
this.close();
}
return returnValue;
}
}
class Factory{
private Factory(){}
public static IMemberService getInstance(){
return (IMemberService) new ServiceProxy().bind(new MemberServiceImpl());
}
}
public class TestDemo {
public static void main(String[] args) {
IMemberService memberService = Factory.getInstance();
memberService.add();
}
}