|
前言
相信很多人都有类似的经历:随着业务越来越多, 系统的越来越复杂, 我们都会感觉我们的代码越来越难看, 重复代码越来越多, 越来越难以维护。 恩, 这确实是个问题, 但有没有可能解决的办法? 老实说, 确实很难, 但不是完全没有可能, 或者说有改善的可能。 最近就关于这方面进行了一些学习和考虑, 以纯理论的方式总结了一下, 希望能对对这方面有兴趣的同学有所帮助。
很多面向应用的系统是以数据为中心的, 在这些系统中, 以数据库存储数据; 业务逻辑代码则根据需求围绕着数据库中存储的数据来组织逻辑;以购买商品的系统为例, 商品数据, 交易数据和用户数据是系统中的核心数据, 绝大多数业务代码则是根据需求来倒腾这些数据。这个非常符合那个关于程序的定义: 程序 = 数据 + 行为; 在这里, 数据是数据库中的数据, 行为则对应业务逻辑。
对于所构建的系统, 我们自然希望可扩展性好, 可维护性;这是一个非常有挑战性对的事情, 大型的应用尤其如此; 能否真的做就在很大程度取决于逻辑的组织方式。 这篇文章大体介绍以数据库为中心的应用中的三个典型的业务逻辑组织方式。
逻辑组织方式
事务脚本方式
这里的事务与数据库术语事务有所区别, 这里的事务更多的指一次业务交互。
在应用系统中, 大多数业务逻辑可以看做一系列子任务的集合; 比如用户购买一个商品时, 可以大体分成几步:
先根据商品的信息到数据库中查询是否有可销售的商品存在;有的话, 添加一个用户购买商品的购买记录;然后把商品数量减少;其他事情, 比如发邮件通知用户等。
以事务脚本方式组织代码时, 业务逻辑组织上没有层次之分, 在实现一个具体业务时, 根据其业务的需要从前到后进行一系列的事务调用; 就购买商品为例, 先从数据库中查询商品数量, 然后判断是否足够, 足够的话添加用户购买商品的记录, 然后操作数据库减少商品。这种方式有个明显的特点, 一个事务脚本实现以一个用例或者或者一个功能。这个方式优点很明显, 简单,直观, 易学易用,开发速度快;这些容易理解, 因为这些写代码的方式与直观的思维方式类似, 在实际中, 很多系统都是这样实现的;尤其那些快速开发系统; 但是抽象度低, 容易导致重复代码多,与其他系统的耦合程度高, 维护麻烦,尤其是对于复杂的系统来说。 举个例子来说,购买商品购买这个功能,桌面版提供了之后,手机版的也需要实现, 由于手机版与桌面版是两个不同的用例, 如果用事务脚本来组织代码的话, 很自然的就会出现类似的代码出现在了不同的地方的情况。 一个很明显的优化是封装成函数, 但是封装成函数这个事情的模块化程度低, 在业务复杂的情况下, 对业务逻辑的有效管理和维护是一个挑战。
事务脚本这种方式适用于相对简单的业务逻辑环境,而且在现实中, 很多业务本身就是简单的, 这种方式可以在开发高效, 运行高效的前提下工作的很好; 另外对于快速开发环境中也非常适用。 但是当业务逻辑复杂, 而且上线后维护期很长或维护量很大的系统来说,可能不是一种很好的方式。
表模块方式
在事务脚本方式当中,很容易导致:相同或者类似的代码重复出现;相关逻辑分布在多个地方。
对于前一个问题, 可以通过把相同或者相似逻辑封装成函数来改进, 第二个问题通过流程或规范可以得到控制。 但是, 还是会在业务复杂的情况下对业务逻辑的有效管理和维护是一个挑战 因为缺乏一种有效的编码的机制来控制这样的问题。
表模块组织方可以从机制上提供一个相对好的解决办法, 其大概思路是,把与一个或者多个数据库表(或者视图)有关的逻辑组织成一个类, 把对与这个表有关的逻辑组织成这个类的方法。以上面那个购买商品为例, 查询商品是否足够可能是一个单独的方法, 修改商品数量是一个单独的方法;购买商品是一个方法,所完成的事情就是把前面两个方法组织起来。 一旦有了这个逻辑, 只要是需要用到购买商品逻辑的地方, 直接调用这个购买商品的方法就可以了; 除了这个购买商品之外, 其他与商品有关逻辑都组织在这个类里面,避免了与商品有关的逻辑分布到多个地方。
除了提供一个代码组织的方式外,这种组织方式还有一些其他的好处:不需要数据库表就直接可以测试,也便于打桩测试; 与很多数语言提供的数据库操作API配合使用方便, 很多数据库操作API返回的结果都市记录集的方式, 尤其以微软提供的相关API为典型代表, .NET提供的Dataset更是功能强大。实际上, 微软提供的开发平台倡导的就是以表模块方式组织逻辑, 并提供了各种便利的开发工具和API; 在管理代码的有效性和复杂度上有比较好的平衡,他比前面的事务脚本方式相对繁琐点, 比后面好提到的领域模型方式简单很多。
领域模型
领域模型方式组织代码就是OO的编程思想, 把领域逻辑对象化, 从而达到在复杂的业务逻辑是有好的可扩展性和可维护性。表模块组织方式在管理代码的有效性和复杂度上有比较好的平衡, 但是在其提供的抽象机制毕竟有限; 在管理复杂的业务逻辑方面有些不给力。比如, 对于不同类型的商品, 其购买逻辑可能不一样;这时候, 面向对编码的威力会就能比较好的发挥了, 商品这个例子中, 购买时的行为可能不一样, 利用多态机制, 对调用者来说可能是透明的。
领域模型这种方式与表模型的方式的区别在于OO的力度不一样; 表模型以表为单位来组织, 领域模型可能则以表里面的记录为单位来组织的, 因此代码中, 一个表只有一个类实例, 而领域模型则会针对一条记录有个对象。
模型这种方式的优点是便于有效的管理复杂性和可扩展性, 对于复杂的业务逻辑以及那种维护周期很长的系统来说比较适用; 但其缺点也很明: OO建模复杂,开发周期相对会长些;学习成本高, 尤其对于新团队来说; 同样, 如果代码组织不好, 也会出现其他方式中出现的类似问题, 如代码重复等。
小结
三种不同的逻辑组织方式各有特点, 适用于不同的场合, 可以根据实际情况选择, 一般来说, 简单应用, 要求快速开发快, 维护周期短的可以考虑事务脚本方式; 业务逻辑复杂, 维护周期长时, 在开发人员技能满足的条件下可以考虑领域模型; 在这个两个中间的情况可以考虑表模块方式, 尤其是在微软的平台上。 在实际中,由于实际业务的复杂性, 很多时候以一种单一的方式组织还不够, 可能几个方式综合起来运用。 比如, 把核心业务按领域对象的方式组织, 之上再以事务脚本来组织多变的应用业务。
it知识库:以数据库为中心的系统中的业务逻辑组织方式,转载需保留来源!
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。