之前,我们对积分系统进行了需求分析和系统设计,那么具体实现是怎么样的呢?
我们将积分赚取,消费渠道和规则放在了上层系统中,那么这个积分系统负责的功能并不困难,开发也并不复杂,那么本章主要是讲解,为什么要分成MVC三层来开发,为什么要定义VO BO Entity 三者对象
其中的设计原则和思想是什么?
业务系统在设计完成后,我们需要负责的主要有 接口设计 数据库设计 业务逻辑,其中,数据库和接口一旦设计好,就不要轻易的进行改动了,以为即使是微小的改动,修改起来也比较麻烦,而具体的实现逻辑,由于不暴露给外者,那么可以对其进行改动
首先设计一下数据库表
具体的设计如上
然后是接口的设计
接口的设计要符合单一职责原则,粒度越小越通用,但是粒度太小会带来一些问题,比如接口间的调用是由远程调用的,那么多次调用会增加网络负担
另一方面,本该在一个接口内完成的原子操作,现在要拆分成两个接口做,可能出现分布式事务问题,于是,需要使用facade原则,在职责单一的细粒度接口上,再封装一层粗粒度接口给外部暴露
主要的接口如下
然后是业务模型的设计
大部分的业务系统开发可以分为Controller Service Repository三层,比如Repository层负责数据库,Service层负责业务逻辑,Controller负责对外暴露接口
而,我们说的有两种开发模式,基于贫血模型的传统三层架构,和基于充血模型的DDD开发模式,这个系统逻辑比较简单,建议使用基于贫血模型的传统三层架构,而从开发的角度来说,我们可以将其进行独立开发,也可以放到同一项目中进行开发,作为一个微服务,具体使用哪种开发手段,由项目具体决定,不过这个简单的系统,还是放在营销系统中部署比较好,虽然放在了一起,但是只要边界处理的好,后期转型是没有问题的
再解答一个问题,为什么要分为MVC三层开发
1.代码的复用性
如果Service层不定义了getUserById,而UserController,AdminController去哪里获取呢?如果每一个Controller都实现这个逻辑,是否违反了DRY原则
2.进行隔离变化
如果Repository层负责的数据库进行了更改,从MySQL换到了Oracle中,只需要改动Resposisty层即可,Service层不需要改动
3.隔离关注点,让每个层更关系自身
Repository层只负责数据的读写,Service层只负责业务逻辑,Controller层只和外界交互,更加专注于自身
4.提高可测试性
单元测试不依赖于不可控的外部组件,比如数据库,分层后,Repsitory层代码通过依赖注入供Servcie层使用,如果编写单元测试,我们可以用mock数据来代替真实数据库,注入到Service层中
5.分层能应对系统复杂度
如果不分层,我们可能需要设计一套大而全的类,那么这个类的代码维护性和可读性想必很低,必然需要对这个类记性拆分,水平拆分和垂直拆分两种方向,水平方向进行模块的拆分,垂直方向进行三层的拆分
那么,BO VO Entity的意义是什么?
对于这三个,存在大量重复字段的类,如果看待?
如果定义公共的数据对象,会怎么样?
那么对于业务,比如User类,我们可以在BO Entity中定义Password字段,但是不能将Password字段暴露给Vo中,避免泄漏
于是可以认为,这三者的语义不一致,并不违反DRY预知呢
虽然,有很多重复字段,但是职责的边界很清晰,每一层都会维护自己的数据对象,很多时候,清晰是第一位的
那么如何解决代码重复的问题呢?
如果将一份代码写多份,也是很难受的,而且维护起来并不轻松
我们可以使用继承的思想,将共同的属性抽取到父类中,这样修改起来并不困难
或者使用组合的方式,减少代码重复
代码重复问题解决了,如何解决数据对象转换问题呢?
进行手动复制这种没有技术含量的工作,我们可以考虑利用Java中的BeanUtils,Dozer这种工具,来进行对象间的转换
Vo Bo Entity的转换,必然破坏了面向对象思想的封装性,如何是好?
对于Entity和Vo来说,生命周期是有限的,不会有太多改动,所以无须在意,对于Service来说,Bo修改几率大,这就需要我们进行权衡
总结下来,我们对于设计这个系统,使用的设计原则 思想 模式有
1.高内聚,低耦合 讲不通的功能分为不同的模块,做到高内聚,低耦合
2.单一职责原则 分层的主要目的,就是为了每层专注于自身
3.依赖注入原则,下一层的类通过依赖注入到上一层中
4.基于接口而非实现编程 Service层使用的是Repository层的接口,并不关心其底层的依赖是那种数据库,遵循基于接口而非实现编程
5.封装 抽象 虽然破坏了封装性,但是在Controller层,我们只暴露了接口
6.DRY 继承 组合 对于BO VO Entity,我们为了解决三者的代码重复,用到了继承和组合
7.面向对象思想