一、概述
假设客户的系统是一套成熟稳定的系统,我们在原有的业务逻辑的基础上进行进行代码的扩充和改造,会造成原有代码整体的破坏,基于开闭原则,我们不应该这么做。
23种设计模式,是基于6大基本开发原则,其中有一项重要的原则是开闭原则。
二、开闭原则
开闭原则指的是:对一个成熟的项目,我们可以做添加的操作,但是不可以做修改的操作。对于impl真正的实现类,已经成熟稳定了,基于开闭原则,不应该去触碰。
三、代理模式的引入
真正实现类不方便去处理的事情,我们可以交给代理实现类去完成。
四、代理模式和装饰模式的比较
二者之间,仅仅是在代码上有很多的相似之处,但是对于应用场景完全不同。装饰模式,原有类的功能不是特别齐全,经过装饰改造,对象的方法得到扩充,功能会越来越强大。代理模式,不触碰源代码,而装饰模式,是基于原有的对象,进行自身功能的扩充。
五、动态代理的引入
动态代理不属于23种设计模式之一,是传统的代理模式结合反射机制,形成一种更加灵活的代理方式。
创建步骤:
1.按照传统的代理模式的形式,来创建动态代理的模板
2.使得我们的模板具有通用性
3.关键接口和类
InvocationHandler接口,反射包
Proxy类,反射包
流程:
我们需要创建以个动态代理类来实现该接口,重写invoke方法,通过Proxy类调用相关方法来动态的取得代理类的对象。
public class TransactionInvocationHandler implements InvocationHandler{
//成员变量
/*
* 注意:不能写真正的impl为成员变量,否则就不能起到动态代理的作用
*/
private Object target;
public TransactionInvocationHandler(Object target){
this.target = target;
}
/*
* 代理类的业务方法
*
* 业务逻辑的实现(成员变量调用业务)
* 业务逻辑的扩充(事务机制)
*
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//事务机制
Connection conn = null;
Object obj = null;
try{
conn = DBUtil.getConn();
conn.setAutoCommit(false);
//业务逻辑
obj = method.invoke(target, args);
//事务机制
conn.commit();
}catch(Exception e){
conn.rollback();
e.printStackTrace();
}finally{
DBUtil.myClose(conn,null,null);
}
return obj;
}
//取得代理类的对象
public Object getProxy(){
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
}
public class ServiceFactory {
/*
* 传入真正实现类对象,取得代理实现类对象的过程
*/
public static Object getService(Object service){
return new TransactionInvocationHandler(service).getProxy();
}
}