业务层结构优化 | 学习笔记

简介: 简介:快速学习业务层结构优化

开发者学堂课程【DAO 开发实战业务分析:业务层结构优化 】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/399/detail/5172


业务层结构优化

 

内容介绍:

一、功能

二、具体内容

三、总结


一、功能

首先必须要清楚一点,在实际的开发过程之中,业务层应该具备有如下几个功能:

· 负责数据库的关闭处理;

· 负责调用多个数据层的方法进行数据操作;

· 负责进行事务控制。

在之前所实现的业务层的操作子类里面,会发现充斥着大量的如下重复机构:

try {

// 进行数据层控制

returnDAOFactory.getInstance(MemberDAOImpl.class).findAll();

} catch (Exception e) {

throw e ;  // 异常产生之后交由控制层调用

} finally {  // 关闭数据库

DatabaseConnection.close() ;

}


二、具体内容

· 既然所有的业务层都有可能具备同样的功能形式,那么下面就建议对于整体的操作,采用动态代理的设计模式完成。因为在项目里面业务层的接口和实现子类可能有无数多个,不可能使用静态代理为每一个类设置一个代理类。

·在 cn.mldn.oracle.service.proxy 包之中定义一个 ServiceProxy 动态代理类。

但此动态代理类的写法要与反射相结合。动态代理类的前提实践要求是需要实现InvocationHandler接口。动态代理的基本操作要求是需要有一个真实的操作位对象,即 private Object target //需要有一个真实的操作位对象。客户端要想取得业务层对象,一定要有业务层的工厂。

当代码改为动态代理模式后,业务层工厂方法应该返回代理类对象,需要跟上public < T > bind() {,而此如果有Class则会产生对象,即 public < T > bind(Class < T > cls) {。返回到Service接口上,其中也存在 cls ,从而代码的最好写法为 return new ServiceProxy().bind(cls) ;,负责产生对象,产生的对象是包含有指定业务层接口真实对象的代理类对象。

动态代理类的实现需要 return Proxy.newProxyInstance(cls.get, interfaces, h),也可直接找到 this.target = cls.newInstance9};,再进行跟上

returnProxy.newProxyInstance(this.target.getClass().getClassLoader(),this.target.getClass.getInterfaces(), this),于是返回代理类对象,但里面存在泛型,所以将其强制转成具体的泛型的子类型,加上 try {、} catch(Exception e);做一个处理。

如果出现一个错误,将异常输出,即return null ;,将警告压制下去,这就实现了一个代理对象的动态生成。用泛型的目的是为了能返回指定类型。所以ServiceProxy之中要通过 return new ServiceProxy().bind(cls) ;进行操作。invoke中最真实的处理模式是要返回业务层的操作结果。

业务层的操作结果通过 Object ret = method.invoke(this.target, args) ;,但是在过程之中都会抛异常,如果代码之中产生了异常,要向上抛异常,即 throw e ;,再跟上} finally {,然后再进行跟上 DatabaseConnection.close();,于是就实现了动态代理设计模式的操作。

范例如下:

package cn.mldn.oracle.service.proxy;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import cn.mldn.oracle.dbc.DatabaseConnection;

public class ServiceProxy implements InvocationHandler {

private Object target //需要有一个真实的操作位对象

@SuppoessWarnings(“unchecked”)

public < T > bind(Class < T > cls) {

try {

this.target = cls.newInstance();

returnProxy.newProxyInstance(this.target.getClass().getClassLoader(),this.target.getClass.getInterfaces(), this);

} catch (Exception e) {

e.printStackTrace() ;

}

return null 

}

@Override 

public Object invoke(Object proxy, Method method, Object[] args) throws e;

try {

@Override 

public Object invoke(Object proxy, Method method, Object[] args) throws e; 

try {

Object ret = method.invoke(this.target, args) ; 

return ret ;

} catch (Exception e) {

throw e;

} finally {

DatabaseConnection.close();

}

}

}

在基础结构之中只是实现了数据库的关闭操作,只是要调用真实的业务层主题,而后实现数据库的关闭处理,最关键的是所有的代理类与业务层都能通过代理类操作进行关闭。

· 那么随后可以将 MessageService 子类里面所有方法中的异常处理和数据库关闭部分取消掉。所以要将 try、catch 全部删掉。代理的设计思想是处理核心业务,所有可能产生重复的处理操作全部取消掉,而这样的模式便实现了代理设计模式的处理过程。再做一次 junit 测试后正常通过。

· 那么此时每一个业务层的实现子类都可以采用动态代理对象,对数据库的关闭进行统一方式的处理。在整个过程之中,客户端测试的操作没有发生任何更改,因为处理过程中 ServiceFactory 进行改变后,将真实主题类对象变成了代理类对象返回。

· 但是现在有一点比较麻烦:在代理设计模式之中还需要考虑到事务的控制问题。

所有的更新处理都需要事务的操作控制。找到业务层接口,以 add、edit、remove等开头的需要进行事务的操作控制, 所以更好的控制指的是对方法的名称的开头做一个限制,例如如果以 add*、edit*、remove*、delete*、update* 等等为开头的方法都应该自动启动事务控制。

此时将 method 取出来,即 String methodName = method.getName() ;,表示取得方法名称。

而后要在这里进行一个判断,判断要考虑两种情况:一是需要事务;二是不需要事务。

如果if (methodName.startsWith(“add”) || 

methodName.startsWith(“edit) ||

methodName.startsWith(“remove)) { 

则按照一种方式处理,其余的则按照另外一种方式处理,即} else {,跟上= method.invoke(this.target.args) ;,无论怎样处理,都需要操控和返回值,这时则需要 Connection 来进行控制。

事务的最原始的控制操作由 Connection 接口定义,所以可以直接利用DstabaseConnection 类中的 getConnection()方法取得Connection接口对象。如果想要操作此流程,则需要跟上 DstabaseConnection. getConnection().setAutoCommit(false); 但要加上子的异常而不是 wand 异常,因为wand异常是控制关闭的。跟上} catch(Exception e) {,如果没有问题,ret = method.invoke(this.target, args) ;,调用真实主题操作。如果没有问题,则要提交,即

DstabaseConnection. getConnection().commit();,如果有问题则提交DstabaseConnection. getConnection().rollback();,进行一个回滚。整个代码完成后则要进行关闭。程序执行测试后通过,才是真正意义上可以真正使用的代理类,

如下:

package cn.mldn.oracle.service.proxy;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import cn.mldn.oracle.dbc.DatabaseConnection;

public class ServiceProxy implements InvocationHandler {

private Object target //需要有一个真实的操作位对象

@SuppoessWarnings(“unchecked”)

public < T > bind(Class < T > cls) {

try {

this.target = cls.newInstance();

returnProxy.newProxyInstance(this.target.getClass().getClassLoader(),this.target.getClass.getInterfaces(), this);

} catch (Exception e) {

e.printStackTrace() ;

}

return null 

}

@Override 

public Object invoke(Object proxy, Method method, Object[] args) throws e;

try {

object ret = null;

String methodName = method.getName() ;

// 表示取得方法名称

if (methodName.startsWith(“add”) || 

methodName.startsWith(“edit) ||

methodName.startsWith(“remove)) {

try {

DatabaseConnection.getConnection().setAutoCommit(false); 

ret = method.invoke(this.target, args) ;

DatabaseConnection.getConnection().commit() ;

} catch(Exception e) {

DatabaseConnection.getConnection().rollback() ;

}

}else{

ret = method.invoke(this.target, args) ;

}

return ret ;

} catch (Exception e) {

throw e ;

} finally {

DatabaseConnection.close() ;

}

}

在这个代理程序中,有着全面的连接控制和事务控制,但本程序的最大缺陷在于所有需要进行事务控制的方法都必须以明确的代码形式进行编写后才可以实现控制。

 

三、总结

这个时候的代码又被优化了,而此时给出的 DatabaseConnection 以及ServiceProxy 两个类都可以在各个项目使用,前提是项目运用的是原始技术而没有使用开发框架,框架的好处是简化开发。

相关文章
|
3月前
|
SQL Java 数据库
建模底层逻辑问题之ORM框架建模中,执行SQL的过程中被抽象和组织是如何实现的
建模底层逻辑问题之ORM框架建模中,执行SQL的过程中被抽象和组织是如何实现的
|
存储 缓存 算法
缓存层设计套路(一)
对于传统的后端业务场景或者单机应用中访问量以及对响应时间的要求均不高通常只使用DB即可满足要求。这种架构简单便于快速部署很多网站发展初期均考虑使用这种架构。但是随着访问量的上升以及对响应时间的要求提升单DB无法再满足要求。
3600 0
|
3月前
|
前端开发 Java 应用服务中间件
Java应用结构规范问题之dal层实现对数据源的操作的问题如何解决
Java应用结构规范问题之dal层实现对数据源的操作的问题如何解决
|
3月前
|
存储 缓存 前端开发
构建前端防腐策略问题之防腐层帮助前端实现稳定性兜底难的问题如何解决
构建前端防腐策略问题之防腐层帮助前端实现稳定性兜底难的问题如何解决
|
3月前
|
安全 Java
建模底层逻辑问题之在建模过程中,知识层和操作层如何区分
建模底层逻辑问题之在建模过程中,知识层和操作层如何区分
|
4月前
|
API
业务系统架构实践问题之api层和biz层存在冗余问题如何解决
业务系统架构实践问题之api层和biz层存在冗余问题如何解决
|
6月前
|
SQL 设计模式 Java
【软件工程底层逻辑系列】建模的底层逻辑
在本文中,给出建模的底层逻辑:用图形逻辑地表达现实业务的抽象,通过一些大家通识的技术案例讲述建模的过程。
74968 3
|
监控 小程序 Java
《优化接口设计的思路》系列:第五篇—接口发生异常如何统一处理
大家好!我是sum墨,一个一线的底层码农,平时喜欢研究和思考一些技术相关的问题并整理成文,限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。
369 0
《优化接口设计的思路》系列:第五篇—接口发生异常如何统一处理
|
存储 设计模式 缓存
复杂逻辑业务层治理探究
复杂逻辑业务层治理探究
375 1
|
JSON 缓存 监控
代码分层设计
在搭建一个项目之前,除了要进行架构和业务方面的设计和分析,往往还需要对代码的结构进行规范化设计。而分层思想,是应用系统最常见的一种架构模式。
588 0