关于后台问题的一些思考
来源:互联网 发布:laylive客服系统源码 编辑:程序博客网 时间:2024/05/19 01:32
关于后台问题的一些思考
1. 关于异常
- 对于异常应该且必须输出到日志中(不能捕获后不处理),但是不应该直接返回给前台;
- 返回给前台的应该是可读的简易信息,并且要注意不要暴露后台保密信息(包括类名、数据库名、文件名、行号等);
- 应给为每类异常建立专门的异常类,而不是直接new Exception();
- 良好的异常类的设计不应该原封不动的继承Exception,直接调用super函数,而应该在异常类内部构造能够更加清楚的表示异常信息的Message。
public class AccountUnderflowException extends Exception { private static final long serialVersionUID = -6299588017190080876L; private Account account; private BigDecimal amount; public AccountUnderflowException(Account account, BigDecimal amount) { this.account = account; this.amount = amount; } public String getMessage() { return String.format("Not allowed to debit '%s' from account '%s'", amount, account); }}
注:代码出自http://download.csdn.net/download/angly/8206155
2. 关于返回值为null
- 如果确实是由“意外情况”(数据库错误、网络错误等)造成返回null,应给直接抛出异常信息;对于能确定造成空指针异常的,应给封装空指针异常后再进行抛出;
- 如果只是因为查询结果为空,那么应该构建空集合进行返回,但是需要注意的是Collections.emptyList()或Collections.EMPTY_LIST,返回的空集合是一个特殊集合,只能进行常见集合的部分操作,使用时要特别注意;
- 最容易出现空指针异常的情况:数据库查询、链式调用(对象不为null,对象的某个属性为null)、Java8 Stream、循环(List中可能含有null元素)。
推荐阅读:避免Java应用中NullPointerException的技巧和最佳实践
3. 关于分包
建议为所有的异常类、配置类、工具类、常量类、枚举类对应的建立专门的包进行存放。
4. 关于分层
所谓的分包分层,不过是为了让各个类的职责更清晰,复用代码更方便。
5. 关于Entity、DO、DTO、VO之间的转换
总体上有2中方案:
- 构造函数,如VO的一个构造函数为new VO(DTO,service...);
- 转换函数,也可以把构造函数转为静态转换函数fromDTO(DTO)或toVO(),或者把所有的DTO2VO的转换都集中写在一个转换类中。
6. 关于DDD(领域驱动设计)
按照官方的说法是:相当于把现有的Service层和Entity合并到一起,在Entity中加入业务方法,使其由贫血模型转变为充血模型。
我的理解是:
- 不要合并Service层和Entity,保留原来分层结构;
- 在Service层增加DOMAIN,用来取代BO、DO等实体类型,可以把上一条中提到的类型转换函数写在DOMAIN中,在DOMAIN中主要进行一些和实体关系紧密的验证和操作,以减轻service.impl中的函数复杂度;
- 实体转换顺序:Param(业务参数组合),Condition(分页排序等参数组合)->DOMAIN(->ENTITY)->VO;
- 增删改查,场景,事务等操作都放在Service层,在DOMAIN中只含有对域本身的操作,并且尽量把转换验证等操作都做成静态的,举例:如果在转化的过程中,需要引入其他service或dao,尽量通过作为函数参数引入,而不是类的成员变量,这样一来可以把所有的关联依赖都集中在Service中。DOMAIN中操作都是内存中进行,DOMAIN不可以操作数据库,所以DOMAIN中没有save()等方法,对DOMAIN的持久化应该在Service中进行;
- ENTITY和VO基本上都是贫血模型,可以按照数据库、持久化框架、前端界面等要求独立设计和演变;DOMAIN是充血模型,与业务相关,按照业务的要求进行演变;
- Service和DOMAIN都应该进行null判断,DOMAIN中的转换函数等本身有自身安全性要求,不能直接遇空报错;Service中的场景走向可能需要根据null判断来决定,切换场景、报错、返回空集合、返回null。
7. 关于命名
1. 第一层:表现层,对外服务层,User Interface layer
如果是面向前端网站,包可以用controller、api,类可以用**Controller、**Api;
如果是面向服务,包可以用facade、application、api,类可以用**Facade、**ApiService、**Api;
作为参数传入这层的实体类,一般放在query、condition包下,可以用**Param(业务参数组合)、**Condition(分页排序等参数组合)、**Form(表单参数);
作为返回值传出这层的实体类,一般放在model、vo、dto等包下,可以用**VO(面向前端)、**DTO(面向服务)。
2. 第二层:业务层,业务逻辑层,Business Logic Layer
一般包名 service、business(简写biz),类名可用**Service、**Business(Biz);
这层的实体,一般放在domain包下,为所谓的BO、DOMAIN等从现实生活中提取的对应的业务对象,是在系统中操作起来最方便的实体类,并且负责连接和转换第一层和第三次的实体对象,建议使用不带后缀实体名。
3. 第三层:持久层,数据访问层,Data access layer
一般包名可用dao、repository等,类名可用**Dao、**Repository等;
这层是实体,一般放在entity包下,可以用**Entity。
另外,包名一般为:com.公司/产品线.项目名.各层分类.功能分类,如com.taobao.cainiao.controller.address下面放着和地址相关的接口。
8. 关于发布
如果是面向前端的项目一般打成一个包即可;如果是面向服务的项目一般打成两个包:
一个包是第一层的接口和实体,可以命名为***-api:
另一个包是剩下的部分,可以命名为***-service。
附录:
后台模型
后台目录
阅读全文
0 0
- 关于后台问题的一些思考
- 关于后台从阿里云获取文件的一些思考
- 关于生产者-消费者问题的一些思考
- 关于软件盗版问题的一些思考
- 关于进程问题的一些思考
- 关于后台分工的思考
- 一些思考的问题
- 关于c++中一些指针问题的思考
- 项目q总结:关于Linux性能问题的一些思考
- 关于二分查找及其上下界问题的一些思考
- 关于博客更新的一些问题与思考
- 一些前台后台的关于浏览器差异的问题
- 关于 sizeof() 的一些思考
- 关于sizeof()的一些思考
- 关于useBean的一些思考
- 关于素质的一些思考
- 关于 sizeof() 的一些思考
- 关于 sizeof() 的一些思考
- scapy安装在win7上
- ARM笔记(中断)
- JAVA | 49
- 二叉树的有关操作
- Numpy学习——数组填充np.pad()函数的应用
- 关于后台问题的一些思考
- Altium Designer高级功能初探之——覆铜规则
- AXIS2发布WebService
- Android语言切换的源码分析
- 单例模式和多线程
- 异或运算
- peak-linux-driver编译问题,无法找到popt.h
- winsock
- J2EE规范