细说业务逻辑(后篇)

2023-11-08

细说业务逻辑(后篇)

作者: EricZhang(T2噬菌体)   来源: 博客园   时间:2009-11-01  阅读:295 次   原文链接    [收藏]   

  前篇: http://kb.cnblogs.com/page/50470/

 


  3、业务逻辑的架构模式及实现

   Martin Fowler在《Patterns of Enterprise Application Architecture》一书中,总结了四种企业应用中业务逻辑的组织方式 :Transcation Script,Domain Model,Table Module及Service Layer,另外,本书的第十章“Data Source Architecture Patterns”中包含一种模式——Active Record。结合软件体系结构的近期发展及个人的理解,我更倾向将Active Record归入业务逻辑的组织模式,而Service Layer应该不算做业务逻辑特有的模式,所以,在本文中,将介绍四种模式:Transcation Script,Table Module,Active Record及Domain Model。

  3.1、Transction Script

      3.1.1、概述

      Transction Script(以下简称TS)是一种面向过程的业务逻辑组织方式。这里首先要强调一点,这里的Transction一词与数据库系统中表示“事务”的Transction没有任何联系。TS是将领域中的业务分解为一个个业务过程,每个过程实现一项业务功能,具体到程序中,一个业务过程往往映射到一个方法。TS是完全面向过程的业务组织模式,适合应用于业务逻辑较简单的场合。

      应该说,我们见到的绝大多数系统都是以TS组织业务的。例如PetShop及Oxite等经典示例。有时为了方便维护,开发者会将同一领域实体相关的业务方法集中到一个类中,这里虽然用到了领域实体和类的概念,但和面向对象没有任何关系,完全是面向过程的。

      当使用TS时,可以不需要数据访问层,而是将数据操作执行代码(如执行SQL或存储过程的代码)直接嵌入在业务方法中,有时为了复用性和维护性可以编写一 个helper类封装数据库的操作。当然这并不是说TS不能配合数据访问层使用,但由于应用TS的场合一般业务非常简单,如果配合Repository或 ORM使用,业务逻辑层往往就会变得非常“瘦”,看起来仅仅是对数据访问层的封装。一般在需要支持多数据库的场合,要配合Repository和 Abstract Factory使用。

      TS的示意图如下所示:

图3-1

图3-1、 Transcation Script架构示意

  可以看到,在TS中,业务层并没有面向对象的东西。也许会用到类,但类只是组织业务方法的模块,每个模块中有一个个业务方法,每个业务方法完成一个业务流程,完全按面向过程结构组织。

      3.1.2、分析

  • 什么时候可以用TS?

      应该说,如果具备以下条件之一 ,你可以考虑TS:

      1)系统业务十分简单直观,并且频繁变动的可能性不大

      2)工期很紧,需要尽量压缩设计的时间,尽快投入编码

      3)不能熟练掌握和使用OO进行系统的设计与开发

      4)厌恶OO,就是喜欢面向过程

  • TS的优点?

      1)设计阶段投入较小,启动耗费低。因为TS较容易掌握,使用起点低,所以使用TS的初期投入较少

      2)在业务比较简单直观的情况下,TS结构的代码直观易懂,具有良好的可维护性

  • TS的缺点?

      1)容易造成代码冗余。因为各个业务自行组织流程,所以减少了复用的机会,可能产生重复性代码

      2)因为TS天生不适合业务复杂的系统,当系统业务较复杂时,可能会令业务层代码繁杂不堪

  3.2、Table Module

  3.2.1、概述

      Table Module(以下简称TM)同样是一种面向过程的业务逻辑组织方式,与TS不同的是,TM更贴近关系型数据库结构。在 TS中,一般使用DTO等进行数据表示和传递,其着眼点一般在单个对象。而TM一般根据数据表组织业务模块,每个模块对应一个表,其中包含了这个表的相应 处理。并且在业务层内,使用库-表结构的对象进行数据操作,做到最大限度与数据表的对应。业务组织一般按照面向过程组织。

      一般当业务相对简单且业务基本集中在CRUD操作时,可以考虑TM。使用TM意味着使用数据驱动设计。通常自己实现一套库-表结构操作对象的库是难度比较 大的,所以一般选用TM时,所使用的平台应该包括这么一套库。如.NET平台上的ADO.net就内置了丰富的库-表操 作,DataSet,DataTable,DataAdapter等在TM架构的实现中可以起到非常方便的作用。

      使用TM后,一般不需要再配合Reponsitory或ORM,因为此时的业务层也是面向过程和面向关系型结构的,无须映射。

      TM的示意图如下:

图3-2 图3-2、Table Module架构示意  

      在使用TM后,业务代码中往往有各种对象对应数据库中的库、表、记录、字段等元素,并提供类似关系数据库的操作。

  3.2.2、分析

  • 什么时候可以用TM?

      如果同时 具备以下条件,你可以考虑TM:

      1)系统业务较直观,以CRUD操作比较集中

      2)整个开发的指导思想是数据驱动

      3)所选用的平台有成熟的库-表操作库支持

  • TM的优点?

      1)类似关系数据库的数据操作方式非常直观,使得设计和编写数据操作功能的代码简单高效

  • TM的缺点?

      1)TM需要完全的数据驱动,从业务到UI传递、存放数据都要以表结构形式,造成一定程度上的不灵活

      2)当业务并非CRUD集中型操作,特别是领域模型和数据库表模型差异较大时,使用TM组织业务的难度非常大

  3.3、Active Record

  3.3.1、概述

      Active Record(以下简称AR)是一种面向对象的业务逻辑组织方式。AR适用于在业务较简单的情况下,应用面向对象思想进行设计。它的基本思想就是将领域中每个实体抽象出一个业务类(BO),然后,将这个实体的数据和行为封装成类的属性和方法。特别的,将CRUD功能也封装进BO中。也就是说,AR中的BO同时具备业务方法和持久化功能。其本身具有ORM的特性,其内部要处理关系实体间的关联问题。

      使用AR时,一般最好有相应框架支持,否则完全手工实现AR有点麻烦。像Castle框架中就有AR功能,Linq to sql也有AR的意思。使用AR后,一般不需要再单独使用数据访问层。

      AR的组织架构如下图:

图3-3  图3-3、Active Record架构示意

      从图3-3中可以看出,AR对业务领域进行了一个简单的OO抽象,将各个实体抽象为AR业务对象,AR业务对象内含有数据、业务方法及数据访问相关的ORM方法。另外,AR业务对象要维护实体间简单的一对多和多对多等关系。

  3.3.2、分析

  • 什么时候可以用AR?

      如果同时 具备以下条件,你可以考虑AR:

      1)系统业务较直观

      2)想尝试使用或习惯于使用OO进行系统设计与实现

      3)平台上有成熟的AR框架可以用

  • AR的优点?

      1)使用OO的方式进行设计与实现,能在一定程度上避免冗余代码问题)

      2)使用AR后,与某个实体相关的数据和业务全部集中于AR业务对象中,模块内聚性好,便于维护

      3)实践证明,AR结构的业务层编码效率很高

  • AR的缺点?

      1)AR仍需要关注数据之间的关联,在一定程度上带有数据表和影子,没有完全摆脱数据驱动,所以当业务领域和数据库结构差距大时,实施困难

      2)AR的CRUD是以个体为粒度的,当进行批量操作时,如一次查数千个数据,如果严格尊从AR就需要生成数千个AR业务对象,这简直是场灾难。所以在有大规模查询的情况下,可以考虑使用TS配合AR

      3)如果业务非常复杂,AR将力不从心

  3.4、Domain Model

  3.4.1、概述

      Domain Model(以下简称DM)是一种适合领域驱动和为复杂业务系统组织业务的面向对象业务逻辑组织方式。前面三种架构模式都有一个共同的缺点——不适合业务 复杂的系统。那么何为复杂何为简单?很抱歉,我给不出明确答案,而且我估计世界上任何一个人都很难给出标准的无争议答案。因为软件系统中的复杂和简单本身 就是一个难以量化的指标,很多时候,只能靠专业人员的经验了。

      我个人估计,世界上95%的软件系统其业务难度都不会超出上述三种模式的能力范围,而若你不幸遇到剩下的5%,恐怕目前只有Domain Model能帮你了。Domain Model是一种纯面向对象的业务架构模式,它的核心思想是获取领域中的各种实体抽象,然后完全按照现实领域中的情况去建模和运行。并且业务对象是“持久化无知”的。 关于“持久化无知”下面细讨论。这个模式十分复杂和难以掌握,但一旦掌握并使用,其能力绝对会超乎你的想象。

      下面看一下DM的架构示意图:

图3-4   图3-4、Domain Model架构示意

      从图3-4中可以看出,DM看上去是个十分纠结的模式,而实际上,它确实很纠结!实际上,我认为如果能熟练掌握并运用DM进行业务逻辑的组织,那这人绝对是架构师中的大师级人物(我目前是做不到)。

      还是先结合图示分析一下DM中的要点。

      第一,DM中的业务对象是纯业务对象,不含数据访问操作。这个可以和AR中的业务对象对比一下。也就是说,DM中的业务对象是纯业务对象,它们只关注与业务的实现。

      第二,DM的组织内部对象多,关系复杂,而这种关系不再只是那种简单的一对一、一对多的关系,而是领域中的各种依赖和关联的抽象,关系类型多,非常复杂。

      第三,DM需要业务部分“持久化无知”。所谓持久化无知,指业务部分只需执行业务功能,而不必关系持久化。在使用DM时,必须设计一套ORM机制(注意这 里用到了“机制”一词,而不是“框架”或“库”),使得在业务系统运行时,自动在必要的时候执行数据持久化操作。这也是为什么上图数据源和业务层间的箭头 是虚线的关系。

      上文曾说过,DM要最大程度模拟现实情况。而现实世界和软件世界最大的区别就是现实世界是“内存无限大、永不停机的”,可以把现实世界看成在一个无限大内 存里永不停止运行的程序。而软件世界不同,它的内存有限制,我们不能将所有对象都放在内存,而且一旦掉电,它就会停止运行,正因如此,我们才需要持久化机 制去配合DM模拟现实世界。为了让业务更接近现实,它必须对持久化过程毫无感觉。而一套持久化机制默默为其营造了一个好似内存无限大、永不停机的环境,因 此DM才得以发挥威力。

      第四,DM往往需要Services Layer的配合。因为DM内部仅有一个个业务对象,它们互相调用,并没有提供一个友好的接口与UI交互,所以在使用DM时,往往在其上对各种UI需要的 服务进行封装(回顾一下Facade模式),形成一个Services Layer,以方便与UI交互。

  3.4.2、分析

  • 什么时候可以用DM?

      如果同时 具备以下条件,你可以考虑DM:

      1)系统业务极为复杂

      2)有功底扎实和经验丰富的精通OO的架构及设计师

      3)项目经费和时间充足

      4)贯彻领域驱动设计

  • DM的优点?

      1)完全的OO思想运用,将使你享受到OO的所有优势

      2)应付复杂业务的强力杀手锏。如果DM运用得当,将会使得复杂业务被高效解决

  • DM的缺点?

      1)使用门槛极高,难度极大,如果团队中没有精通OO和系统架构且经验丰富的专家很难实施

      2)设计过程极为复杂,可能会导致设计瘫痪

      3)如何设计良好的ORM机制辅助DM是一大难题

  3.5、各种架构模式的比较及选择

      相信看过上文内容后,各位一定对各种业务组织模式及其特点、优劣、应用场景有了清晰地认识,如果我在这里再喋喋不休讨论各种模式的比较及如何选择,难免有 侮辱各位智商之嫌O(∩_∩)O~,所以这里我只给大家呈现一幅决策网络图,以期起到一个梳理和归纳总结的作用。

图3-5

图3-5、业务架构模式决策网络

      (郑重声明:图3-5为本人原创, 并非摘录自已有文献,因此此图的选型流程仅代表个人意见。由于笔者水平有限,不能保证此图一定合理和正确。因此在实际选型时请多多参考已有文献及咨询相关 专家,此图只起总结归纳和探讨作用,不作为任何指导和规范。若因遵循此图选型而给项目带来的任何经济及其他方面损失,笔者不承担任何责任。)

  4、结束语

      本文通过两篇文章的篇幅,先后介绍了业务逻辑的定义、相关理论及经典的业务逻辑相关的架构模式。本文中阐述了不少已有理论,亦掺杂诸多个人理解及看法。因此请各位在阅读时多进行批判吸收,同时参考以后经典文献及书目综合理解业务逻辑,切勿仅看我一家之言。

      另外,由于本文仅仅是综述性文章,不能具名业务逻辑的各个方面,在深度上也基本是浅尝辄止。因此,若希望深入理解业务逻辑,可以看到相关经典书籍及文献。

  参考文献

   [1] [意]Dino Esposito, Andrea Saltarello, .NET软件架构之美英文版(原名Microsoft .NET Architecting Application for the Enterprise), 人民邮电出版社, 2009

  [2] [美]Martin Fowler, 企业应用架构模式影印版(原名Patterns of Enterprise Application Architecture), 中国电力出版社, 2004

  [3] [美]Mclaughlin, Pollice, West, 深入浅出面向对象分析与设计影印版(原名Head First OOA&D), 东南大学出版社, 2007

  [4] Google, www.google.com

  作者: T2噬菌体
  出处: http://leoo2sk.cnblogs.com
  本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

细说业务逻辑(后篇) 的相关文章

  • 如何获取包含表的列名的数组

    我需要一个包含表的列名的数组 有什么想法如何使用 Rails 3 0 0rc 做到这一点吗 假设您有一个 Post 模型 Post column names or Post columns map column column name 它将
  • 检索 AR 模型的所有关联属性?

    您认为检索 AR 模型所有关联的所有属性的最佳方法是什么 即 假设我们有模型Target class Target lt ActiveRecord Base has many countries has many cities has ma
  • 代码高尔夫!有没有一种简单的方法可以在Python中将字母转换为数字?

    你知道 比如 A 1 B 2 等 我可以列出一长串 if then 但也许已经有一个模块了 如果它像 Excel 坐标 中那样工作 其中 A 27 并继续 那就更好了 这算不算 26 进制数 def foo c return ord c 6
  • 为什么模块中的公共函数不可访问

    我有一个由几个有用的小实用程序组成的程序集 其中我有一个包含简单公共功能的模块 Module FishTrackerConfigurations Public Function GetValueOfUseProductId As Boole
  • 从子模块隐式导入

    我有一个这样的包 foo init py bar py baz py 我希望在导入时自动使用子模块的功能foo So if bar py has def spam 在某个地方 我希望能够直接调用它 就像foo spam 实现这一目标的最佳方
  • 为什么所有的 Active Record 都讨厌? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Rails:如何自动完成名称搜索但保存 ID?

    我用过这个视频http railscasts com episodes 102 auto complete association revised http railscasts com episodes 102 auto complete
  • # 的未定义方法“type_cast”(NoMethodError)

    ActiveRecord ConnectionAdapters Column曾经有一个方法叫做type cast它接受一个字符串并将其转换为 到适当的实例 这似乎在某个时候被删除了 我不知道应该做什么来替换它 这是使用它的代码 Create
  • ActiveRecord 迁移后的括号 [5.1] 是什么?它是如何工作的? [复制]

    这个问题在这里已经有答案了 使用生成新迁移时bin rails g migration CreateUser第一行如下所示 class CreateUser lt ActiveRecord Migration 5 1 什么是 5 1 代表什
  • 将实现拆分到多个文件/模块,并尽可能保持所有内容的私密性

    考虑我的库中的以下代码 pub struct Foo impl Foo fn helper self pub fn do something foo Foo foo helper 我的图书馆的用户应该能够使用Foo and do somet
  • Rails 数据库默认值和布尔字段的模型验证

    在 Rails 模型中我有一个属性is subscriber 当我构建数据库迁移以将此列添加到数据库时 我指定默认值为 false t boolean is subscriber default gt false 我还在模型中指定了该属性需
  • 如何全局公开 es6 模块

    我需要编写一个可在全局窗口上使用的模块 我使用 es6 创建模块 我定义的每个类都有它自己的文件 我正在使用 webpack 来 babelify 并捆绑这些类 我的模块的入口点也是包含要公开的全局的文件 我尝试了各种方法来实现这一点 包括
  • ruby-on-rails 检查查询结果是否为空(Model.find)

    我正在 Rails 上使用 ruby 并尝试检查查询是否返回值 这是查询 search Customer find by name login name 如果查询找到结果 一切都很好 但是我如何对空结果做出反应 I tried if sea
  • 导入 python 模块时如何解决 KeyError?

    我试图从不同的目录级别导入模块 所以我使用了 import os import sys sys path insert 0 os path abspath os path join os path dirname file 但现在我收到这个
  • Intellij 12 - 无法重新导入模块

    所以今天我遇到了一个奇怪的问题 我在 IntelliJ 中的一个模块遇到了一些问题 所以我决定尝试将其清除并从新的结账中重建它 我从 项目 窗口中删除了该模块 然后从我的文件系统中删除 重新下载 我回到 Intellij 并尝试导入该模块
  • Rails - 将模块包含到控制器中,以在视图中使用

    我对 Rails 很陌生 我尝试设置一个要在视图中使用的模块文件 所以我相信正确的行为是将模块定义为控制器中的助手 瞧 它应该可以工作 然而 对我来说情况并非如此 这是结构 lib functions form manager rb 表单管
  • Webpack 5 - 资产模块 - 缺少 url-loader 功能 - postTransformPublicPath

    我想按照建议切换到 webpack 5 asset 模块 不幸的是我错过了 webpack url loader 的函数 postTransformPublicPath path any gt any 由于我们应用程序的结构 资产的公共区域
  • has_many 关系的动态 class_name

    我正在尝试与动态 class name 属性建立 has many 关系 class Category lt ActiveRecord Base has many ads class name gt lambda return self i
  • 覆盖 Rails ActiveRecord 销毁行为的最佳方法是什么?

    我有一个应用程序 我想在其中覆盖许多模型的销毁行为 用例是用户可能有删除特定记录的合法需要 但实际上从数据库中删除该行会破坏引用完整性 从而影响其他相关模型 例如 系统的用户可能想要删除不再与其有业务往来的客户 但需要维护与该客户的交易 看
  • 销毁/删除 Rails 中的数据库

    是否可以从现有应用程序中完全删除数据库和所有迁移记录等 以便我可以从头开始重新设计数据库 通过发行rake T您有以下数据库任务 rake db create Create the database from DATABASE URL or

随机推荐

  • AttributeError: module 'random' has no attribute 'rand

    问题 在跟着 机器学习实战 这本书练习的时候 遇到AttributeError module random has no attribute rand的问题 1 出现如下的报错 2 原因 后来发现当时为了方便能够知道自己 py文件是主要练习
  • 【华为OD机试】数字序列比大小【2023 B卷

    华为OD机试 真题 点这里 华为OD机试 真题考点分类 点这里 题目描述 A B两个人玩一个数字比大小的游戏 在游戏前 两个人会拿到相同长度的两个数字序列 两个数字序列不相同的 且其中的数字是随机的 A B各自从数字序列中挑选出一个数字进行
  • 进军微信第一步:接入微信JS-SDK

    前言 某天 接到这么一个需求 自定义微信网页分享出来的标题 描述和图标 以前没玩过这个 感觉应该很简单 动手了之后 躺过各种坑才知道并没那么容易 完全独立研究排错 感受颇多 分享出来给大家铺一铺路 一 需求来源 开发了一个移动端H5活动页面
  • LaTeX技巧189:LaTeX括号总结

    begin longtable l 1 你好啊 2 吃了没 end longtable 功能 语法 显示 不好看 frac 1 2 好一点 left frac 1 2 right 您可以使用 left和 right来显示不同的括号 功能 语
  • 在WPF中获取程序的专用工作集内存 PerformanceCounter

    使用 PerformanceCounter 获取程序的专用工作集内存并不难 但是就是得找一下属性 通过 CategoryName 遍历 InsanceName 再通过它们遍历 CounterName 之后通过这三个属性得到我们想要的内存 p
  • 数字电路设计之Leon系列处理器结构

    LEON处理器核心是一个与SPARCV8兼容的整数处理单元IU Integer Unit LEON2 是 5 级流水线 LEON3 是 7 级流水线 LEON 包含整数硬件乘法和除法单元 双协处理器 接口 FPU 浮点处理单元和Co pro
  • Python Web:绝对路径和相对路径

    Python Web篇学习汇总 Python Web 操作系统与虚拟机软件 Python Web 了解Ubuntu操作系统 Python Web Linux查看 切换目录命令 努力为大家更新Python web部分的内容 想看持续更新的记得
  • 电脑中常用的“扇区”、“簇”、“块”、“页”等概念

    先看百度百科对于磁盘簇的解释 扇区是磁盘最小的物理存储单元 但由于操作系统无法对数目众多的扇区进行寻址 所以操作系统就将相邻的扇区组合在一起 形成一个簇 然后再对簇进行管理 每个簇可以包括2 4 8 16 32或64个扇区 显然 簇是操作系
  • svg -> text文本水平、垂直居中。文本垂直对齐方式

  • Systemd 入门教程:实战篇

    本文转载至 http www ruanyifeng com blog 2016 03 systemd tutorial part two html 作者 阮一峰 日期 2016年3月 8日 上一篇文章 我介绍了 Systemd 的主要命令
  • 企业知识分享系统的设计与实现

    摘 要 随着信息技术和网络技术的飞速发展 人类已进入全新信息化时代 传统管理技术已无法高效 便捷地管理信息 为了迎合时代需求 优化管理效率 各种各样的管理系统应运而生 各行各业相继进入信息管理时代 企业知识分享系统就是信息时代变革中的产物之
  • 基于AI的4G/5G基站节能的智能解决方案

    随着移动通信网络建设规模逐年增加 通信设备对能源的需求与日俱增 移动通信网络的能耗在运营商的运营成本 OPEX Operating Expense 占比已高于15 经过5G试商用网络的测试验证 5G单站功耗是4G单站功耗的3 4倍 运营商面
  • 提示OpenGL版本过低怎么办

    OpenGL是一个可以加速2D和3D图形的图形库 在计算机显示技术中广泛使用 常用于游戏制作 建筑设计 医疗成像 科学数据可视化等领域 然而 当你尝试运行使用OpenGL的软件或游戏时 你可能会收到一个消息 OpenGL版本过低 请升级驱动
  • 易语言升级版火山软件开发平台现在很庞大了

    中文编程的魅力很吸引人 易语言时代就经常用它编编小程序 易语言最后是输出成vc6编译出来的效果一样 小而精 vc6毕竟是比较古老的技术 现在升级版火山软件开发平台已经能够比较耐用了 一个ide可以开发安卓和windows这2种应用 wind
  • BlueZ5.45 D-Bus总线 GATT API 分析

    笔者目前做linux系统下bluez蓝牙项目开发 发现网上关于bluez开发的资料很少 对于刚开始接触bluez蓝牙的开发人员来说是非常痛苦的 通过调试bluez源码自带的应用例子和文档说明 对BlueZ5 45 D Bus总线 GATT
  • 最大公约数GCD

    输入2个正整数A B 求A与B的最大公约数 Input2个数A B 中间用空格隔开 1 lt A B lt 10 9 Output输出A与B的最大公约数 Sample Input 30 105 Sample Output 15 includ
  • 对于长度为5位的一个01串,每一位都可能是0或1,一共有32种可能。

    对于长度为5位的一个01串 每一位都可能是0或1 一共有32种可能 它们的前几个是 00000 00001 00010 00011 00100 请按从小到大的顺序输出这32种01串 输入格式 本试题没有输入 输出格式 输出32行 按从小到大
  • Unity3D中三种调用其他脚本函数的方法

    第一种 被调用脚本函数为static类型 调用时直接用 脚本名 函数名 第二种 GameObject Find 脚本所在的物体的名字 SendMessage 函数名 能调用public和private类型函数 第三种 GameObject
  • 14-矩阵相乘及其运算法则

    矩阵与向量的乘法 在这一篇文章中我们就将基于上一篇重新审视矩阵的这个视点来理解矩阵的乘法 那么在这一篇 我们主要来看一下矩阵和向量的乘法 这里这个线性方程组是上一小节给大家举的模拟的一个非常简单的小型经济系统的例子 我们可以把这个经济系统其
  • 细说业务逻辑(后篇)

    细说业务逻辑 后篇 作者 EricZhang T2噬菌体 来源 博客园 时间 2009 11 01 阅读 295 次 原文链接 收藏 前篇 http kb cnblogs com page 50470 3 业务逻辑的架构模式及实现 Mart