CodeArt入门教程(二)

4.第一个示例的编码工作

  使用CA编码项目的核心结构是:由多个子系统组成多个不同的服务来提供项目的各种功能。请不要将这里提到的子系统与大家在别的项目实施方法里的概念混为一谈,CA里的子系统概念是完全不一样的,下面我们详细阐述这一点。

  同一事物在不同领域里的本质特征是不尽相同的,例如书在销售领域的关注点是价格、好评度、热销情况等。但在阅读领域里,书更多的关注点是页码、每页内容、段落注释等特征。因此,要想用常规的方法在不同领域重用同一个事物模型是非常困难的。CA为了解决这类问题将整个项目切分为多个子系统,每个子系统关注各自领域内的特征。这些子系统是真正实现业务逻辑的地方,子系统之间会存在一定的依赖关系,但是这种依赖关系是良性的,不会影响系统的重用性。也就是说,每个子系统都可以单独拿出来引用到别的项目子系统中扩展重用。开发人员可以根据需要将多个子系统组装在一起构成一个新的服务,这项服务适用于某一个特定领域,例如:

  文章子系统 + 汽车子系统 = 提供汽车文集的服务(汽车门户站点)

  相册子系统 + 用户子系统 = 提供用户管理个人相册的服务(社交项目)

  销售子系统 + 书籍子系统 = 书籍贸易(电商站点)

  从层次结构上来讲,服务属于应用层,直接对表现层负责。子系统里的领域对象及业务代码则属于领域模型层。应用层调用领域模型提供的领域方法以便完成业务需求。

  一个项目无论规模多么庞大都可以划分成多个规模量为1的子系统,由于这些子系统的代码量足够少,所以可维护性极高。与传统开发的模式相比,CA里的子系统特点如下:

  1) 子系统不是抽象的概念而是真实存在的代码集合。在.Net平台里一个子系统体现为一个程序集。

  2) 子系统内部仅关注于领域模型的建立,没有任何数据存储的代码。数据的存储由基础设施层里的数据仓储提供。这意味着你可以随时改变存储的机制:切换数据库类型、改变表结构、分布式部署数据库等持久化操作都不会影响到领域模型的改变。

  3) 子系统不仅仅用于一个项目,它可以被任意项目使用。以.Net平台为例,子系统有自己所在的解决方案。当其他项目要使用该子系统时,可以以项目引用、程序集引用等方式重用子系统,但绝对不是复制粘贴源代码到新项目里。子系统的源代码只有一份,升级子系统会让所有使用它的项目收益。

  4) 多个子系统可以集成工作,一个子系统里的领域模型是可以被其他子系统扩展的。这里说的扩展是指在不破坏原有代码的情况下,以继承、组合等方式扩充领域模型的能力。与这种方式相比,很多传统开发模式里所谓的“二次开发”就是把以前做过的代码、设计过的数据库表复制到新项目里,再更改源代码和表设计以满足新的需求,这根本就不是扩展而是重写。

  5) 子系统不能直接用于表现层,它们工作的场所是在应用层的服务里。你可以使用任意技术搭建服务。在.Net平台下可以部署在IIS里,也可以使用专用于CA的服务器端应用程序部署项目的服务。

  有了CA开发项目的结构说明和之前分析原始需求的结果,我们可以继续展开会议系统的编码工作了。

  根据前文所述,我们要先为“菜单”、“功能”、“用户”、“角色”等事物创建一个服务,服务会提供各种接口以供表现层调用,例如:创建菜单、新增功能描述等服务接口。请注意,把“菜单”、“功能”、“用户”、“角色”这些事物放在同一个服务里未必正确,我们会在后续的开发工作里基于各种原则将服务分离,创建多个服务、多个子系统。但是在眼前我们不必过多考虑这一点,大胆的去做吧。

  为服务命名是我们要考虑的第一件事。大家不要忽略命名的重要性,为服务命名、为子系统命名、为领域对象、领域属性、领域方法命名都是需要你认真对待的工作。经过一番思考后,我们认为“菜单”、“功能”、“用户”、“角色”等事物是一个项目里几乎必备的事物,是一切的源头。所以我们引用门户(Portal)这个词作为服务的名称,表示系统的入口,因此服务的全称为PortalService。

  以.Net平台为例,我们为门户服务建立解决方案PortalService的结构如下图:

  1) 解决方案文件夹Framework里引用的是CA提供的部分类库,在后续教程里会详细说明这些库的用法。在这里我们只用知道引用的这几个库是构建服务必不可缺的。

  2) 解决方案文件夹Subsystems表示服务需要用到的子系统,目前服务没有引用任何子系统,稍后我们会创建。

  3) portal.services.codeart.cn是托管至IIS的门户服务站点,你也可以使用其他技术部署服务,在这里我们以站点为例。

  4) PortalService.Application是门户服务的应用程序集,在这个程序集里主要使用子系统提供的应用命令来完成服务的调用,后面会有详细的说明。

  5) PortalServiceTest是单元测试程序集。

  创建完门户服务解决方案后,我们需要为其添加子系统。正确的划分子系统是使用CA的一项重要工作。你可以从以下几个角度去分析如何找出子系统:

  1) 在已知的事物里,哪些事物是最独立的?独立是指构建该事物的模型不会依赖于其他事物的模型。由于菜单、角色都会涉及到功能的分配,它们的领域模型与功能肯定会有某种依赖关系,所以我们认为菜单和角色这两个事物不不够独立。那么“功能”呢?描述系统的功能只需要一个简单的名称和描述即可,不会依赖任何其他事物而存在,所以”功能“足够独立。我们以“功能”为突破口找出潜在的子系统。

  2) 为独立的事物正名。只要是确定要为其建立模型的事物,我们都需要考虑它的名称是否合理。因为我们得到的事物是从现实世界里表面需求分析而来的,这样的事物并非真正贴切程序里的领域模型,在程序世界里有其独有的描述方式。“功能” 这个名称比较含糊,能代表的概念很多,不适用于程序命名。另外,我们在谈及到角色的时候,不是角色有哪些功能而是角色拥有哪些权限。所以,将“功能”正名为“权限”是一个不错的主意。我们统一语言后,会将之前分析到的需求更改为“可以为角色分配权限”、“可以为菜单设置哪些权限能够使用它”。

  3) 确定了独立事物的名称后,我们就能以此为基础假设要建立一个与该事物相关的子系统。在这个例子里也就是“权限子系统”。目前,该子系统需要提供哪些应用上的帮助我们还比较模糊,但是可以确定的是权限子系统需要提供创建权限、修改权限、删除权限等操作。权限子系统里面一定会有权限的领域模型。

  4) 事实上分析到第3步就可以编码完成权限子系统的第一个版本了,但是由于我们提供的是使用CA的教程,不可能完全演绎出真实项目迭代实施的每个细节,真要如此需要写一本独立的书籍了,也许以后我会抽时间去著作完成,但是在这里我们会浓缩下项目实施的过程。提前告知各位正确的设计方式。“权限子系统”这个想法很好,从概念上讲几乎无懈可击,但是从务实的角度来考虑会有些问题。如果我们为一个领域模型去创建一个子系统,这样使用起来会比较麻烦。你试想一下,如果有“菜单子系统”、“角色子系统”、“权限子系统”,当我们要在服务里创建一个角色时,这个服务必须引用“角色子系统”和“权限子系统”才能完成工作,如果对象引用链比较多,你有可能需要引用的子系统数量远超过预,例如:用户子系统会引用账户子系统、账户子系统会引用权限子系统和角色子系统、用户子系统还会引用地理位置子系统用以表示用户所在地。这时候服务要使用用户子系统就不得不多引用4个额外的项目,不仅麻烦也不利于维护更新。关于如果切断引用链,让子系统更加的独立的话题后面会有更详细的说明,这里我们只用知道尽量不要为一个事物单独创建子系统。

时间: 2024-11-12 00:28:24

CodeArt入门教程(二)的相关文章

C语言快速入门教程(二)

C语言快速入门教程(二) C语言的基本语法 本节学习路线图: 引言: C语言,顾名思义就是一门语言,可以类比一下英语; 你要说出一个英语的句子需要:  单词  +  语法!  将单词按照一定的语法拼凑起来就成了一个英语句子了; C语言同样是这样,只不过单词可以理解为一些固定的知识点,而语法可以理解为算法(可以理解为解决问题的方法) 在这一节中我们就对固定知识点中的语言描述与数据存储进行解析! 1.C语言的基本元素 1.1  标识符 什么是标识符? 答:在C语言中,符号常量,变量,数组,函数等都需

DataVeryLite入门教程(二) Entity篇

DataVeryLite 是基于.net 4.0的数据库持久化ORM框架. 目前支持的数据库有Sqlserver,Mysql,Oracle,Db2,PostgreSql,Sqlite和Access. 最好先阅读DataVeryLite入门教程(一) 配置篇,然后再阅读本篇.如果你觉得麻烦也可以跳过. Entity是ORM中的核心对象之一,一个继承Entity的对象对应于数据库中的一个表. Entity提供丰富的API对表中的单条数据进行操作. 比如根据id或其他条件,加载,删除,插入,更新和部分

Spring Cloud 入门教程(二): 配置管理

使用Config Server,您可以在所有环境中管理应用程序的外部属性.客户端和服务器上的概念映射与Spring Environment和PropertySource抽象相同,因此它们与Spring应用程序非常契合,但可以与任何以任何语言运行的应用程序一起使用.随着应用程序通过从开发人员到测试和生产的部署流程,您可以管理这些环境之间的配置,并确定应用程序具有迁移时需要运行的一切.服务器存储后端的默认实现使用git,因此它轻松支持标签版本的配置环境,以及可以访问用于管理内容的各种工具.很容易添加

jQuery 入门教程(二): 基本语法

学习jQuery之前需要你有下面几个方面的基本知识 HTML CSS JavaScript jQuery 的基本语法 $(selector).action() $ 符合定义这是一个jQuery语句 (selector) 用来选择某个HTML元素,其语法和CSS的selector语法一样. action() 定义操作该HTML元素的方法. 比如: $(this).hide() – 隐藏当前元素. $("p").hide() – 隐藏所以 <p> 元素. $(".te

Git的入门教程&lt;二&gt;

Git 的入门教程<二> 4> git远程仓库的使用 我们在使用git进行代码管理的时候,协同办公,需要一个24小时不间断的隐形同事,此时,如果在局域网内,则直接开一台局域网内的24小时开机运行的机器就可以,但是如果在homework的时候就需要这个24小时运行的机器拥有独立的外网IP,这样消耗就比较大,幸好,网上有一个github,提供给我们一个免费的仓库,让我们可以在同事之前推送代码,下面介绍github的使用. 4.1 github的使用 首先 登录github的官网: https

BootStrap入门教程 (二)

上讲回顾:Bootstrap的手脚架(Scaffolding)提供了固定(fixed)和流式(fluid)两种布局,它同时建立了一个宽达940px和12列的格网系统. 基于手脚架(Scaffolding)之上,Bootstrap的基础CSS(Base CSS)提供了一系列的基础Html页面要素,旨在为用户提供新鲜.一致的页面外观和感觉.本文将主要深入讲解排版(Typography),表格(Table),表单(Forms),按钮(Buttons)这四个方面的内容. 排版 (Typography),

PySide——Python图形化界面入门教程(二)

PySide——Python图形化界面入门教程(二) ——交互Widget和布局容器 ——Interactive Widgets and Layout Containers 原文链接:http://pythoncentral.io/pyside-pyqt-tutorial-interactive-widgets-and-layout-containers/ 上一个教程中,我们了解了一些QWidget提供的功能,还有一个特殊的子类QLabel.更进一步的,我们完成了一个用来说明简单Python/Q

无废话ExtJs 入门教程二[Hello World]

无废话ExtJs 入门教程二[Hello World] extjs技术交流,欢迎加群(201926085) 我们在学校里学习任何一门语言都是从"Hello World"开始,这里我们也不例外. 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&

无废话ExtJs 入门教程二十一[继承:Extend]

无废话ExtJs 入门教程二十一[继承:Extend] extjs技术交流,欢迎加群(201926085) 在开发中,我们在使用视图组件时,经常要设置宽度,高度,标题等属性.而这些属性可以通过“继承”定义在我们定义的新组件中,从而达到重用的目地. 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-

Elasticsearch入门教程(二):Elasticsearch核心概念

原文:Elasticsearch入门教程(二):Elasticsearch核心概念 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/vbirdbest/article/details/79200022 基本概念介绍 Elasticsearch是一个基于Lucene构建的开源.分布式.RESTful的搜索引擎,能够实现近实时(NRT)搜索,稳定.可靠.安装方便.Elasticsearch 不