简议使用业务模型驱动进行软件的设计
在我工作的这些年里,前几年做的大多项目都是数据库驱动型的,我想很多人也都是这样的。对于数据库驱动型的项目,我们的核心都是围绕数据库在做开发,通常我们都在写CRUD的代码,后来有了代码生成器、ORM,我们的工作是变的更少了。但是大家有没有觉得,虽然自己一直在使用面向对象的语言在做开发,但是通常我们使用面向对象进行设计的能力并没有多少的提升。最近几年我脱离了做以数据库驱动为主的项目,来到了一个陌生的领域,刚开始的路很难,因为你要从需求抽象出系统的业务模型,而业务模型设计的对错将直接影响到系统的稳定性,可扩展性等等,这才是我觉得 软件设计师 的工作。
后来我遇到项目,我大体会用业务对象进行建模,而业务对象的计算所使用的数据,则根据业务对象的特点进行获取或保存。这使我豁然开朗,在这些的设计过程中,开始理解设计模式的好处,开始以全局观的角度去看待系统。你的视角提高了,那么对于系统使用什么样的数据库,使用什么样的消息队列,使用什么样的缓存的这些问题,你会觉得其实这些问题只是为了能够充分发挥业务对象的能力,其核心还在于业务对象上。对于计算强度大的业务对象,可以为其设计多线程的,多进程的,亦或是分布式的。一切的一切都以业务为核心,把业务对象为系统内的一等公民,我觉得这才是基于面向对象的设计与实现。
再回过头来看数据库驱动型的项目,也可以使用基于业务模型驱动的设计进行重构。通常我们做基于DB的项目,通常是先建立了DB,再通过代码生成工具生成代码。对于ORM(对象关系映射),也只是解决了你不用以结构化查询的角度去构造SQL语句,再对返回的结构化数据进行转义成对象的工作。这有存在一个很大的问题就是DB的设计与真实系统的业务对象往往有时候很难融合。在这种情况下,我们的业务对象在设计的时候,不得不照顾DB上的设计。否则业务对象的数据保存将是一个很大的问题(至少不会那么顺手)。其实我觉得正确的做法应该是:先分析系统的核心业务模型,在业务模型确定的情况下,在确定什么样的业务对象的数据需要持久化。在这个基础上为业务对象的数据持久化再设计如何保存数据。当然了数据库也有数据库的好处,对于数据量大的查询和历史数据的保存使用DB还是不二的选择。
在最近的一次项目中,由于项目的负责人偏硬件,对软件了解的比较少。在需求文档还未成型的时间,就让我先设计系统的数据库结构,这使得我很苦恼。在不得已的情况下完成了工作,随着后面的业务模型的建立,我发现存在一些数据库对象我没法使用,我不得不为领域模型再一次的建立数据对象类,通过新的数据对象类通过一些契约的方式去调用基于数据库生成的数据对象类来完成读取和保存工作。当然了,你会问我,为何不重构数据库结构。问题是,项目里负责UI的工程师的习惯还是比较倾向与以DB为驱动的,所以......。像这样的问题我估计会是很多数,很多人还是习惯以数据库驱动的方法去完成工作。
设计步骤
1 接到需求后,先通过和熟悉当前领域的工程师进行确认系统中的领域模型;
2 对领域模型进行建模,之间也需要和领域工程师进行多次的确认,以获得一个双方都认可的领域模型;
3 根据领域模型,设计出系统的业务模型(类);
4 实现业务模型和测试;
对于业务模型的数据保存问题,可根据不同的业务模型性质和系统需求进行不同的持久化保存;
通常的保存有:
A 内存
B 文件(平面文件、结构化文件、关系数据库、非关系数据库、队列 等)
通常业务模型是整个系统中的核心。通常客户的需求会改变,所以我们的UI在使用业务模型的时候,都需要基于业务模型的接口进行编程。通常我会使用简单类工厂或IOC 容器去处理对象的创建以及对象间的依赖关系;而对于系统中的其它方面,比如:日志,权限等,我会通过AOP的方式注入业务模型中,这样使得我们的工程师将核心精力放到业务模型的实现上。
在以业务模型为第一公民的设计理念上,所有的其它操作都要围绕业务模型,比如对于业务模型的数据保存上,我们持久化的方式就有很多的选择,可以根据业务模型的数据特点,选择不同的数据保存方式。对于简单的非系统全局化的业务对象,它的数据可以保存以平面文件或结构化文件的方式进行保存。而对于系统全局化的业务对象,这些数据可以保存到数据库中。