编程知识 购物 网址 新闻 笑话 | 软件 日历 阅读 图书馆 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
   -> 领域驱动设计 -> CodeArt入门教程(二) -> 正文阅读

[领域驱动设计]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的教程,不可能完全演绎出真实项目迭代实施的每个细节,真要如此需要写一本独立的书籍了,也许以后我会抽时间去著作完成,但是在这里我们会浓缩下项目实施的过程,提前告知各位正确的设计方式。从第5点开始后面的内容都是我们在实际工作中反复提炼后得到的经验与教训。同样的,大家在领域实战的时候也会不可避免的犯设计上的错误,请无须担心,大胆的去尝试吧。
  5) “权限子系统”这个想法很好,从概念上讲几乎无懈可击,但是从务实的角度来考虑会有些问题。如果我们为一个领域模型去创建一个子系统,这样使用起来会比较麻烦。你试想一下,如果有“菜单子系统”、“角色子系统”、“权限子系统”,当我们要在服务里创建一个角色时,这个服务必须引用“角色子系统”和“权限子系统”才能完成工作,如果对象引用链比较多,你有可能需要引用的子系统数量远超过预期。例如:用户子系统会引用账户子系统、账户子系统会引用权限子系统和角色子系统、用户子系统还会引用地理位置子系统用以表示用户所在地。这时候服务要使用用户子系统就不得不多引用4个额外的项目,不仅麻烦也不利于维护更新。关于如何切断引用链,让子系统更加的独立的话题后面会有更详细的说明,这里我们只用知道尽量不要为一个事物单独创建子系统。
  6) 因此,我们需要将内聚性比较高的事物合并在一个子系统里。找出与权限模型紧密相联的事物,再结合子系统应该提供的职责去综合考虑是否将其他事物也纳入到权限子系统中。很明显,角色是与权限是密不可分的,角色不可能脱离权限独立存在,那样的话角色就没有意义了,我们使用角色的目的就是为了识别用户身份,所谓“身份”在程序里的体现就是拥有哪些权限。所以角色可以加入到权限子系统中。那么菜单呢?菜单的确依赖于权限模型,但是这种依赖关系不代表菜单一定要和权限在同一个子系统里。权限子系统的主要职责是提供身份识别,这和菜单自身没有任何关系。所以我们不必将菜单放入到权限子系统里而是考虑稍后建立“菜单子系统”再由“菜单子系统”引用“权限子系统”集成工作。
  7) 明确了权限、角色、菜单这三者所属子系统的关系后,我们再来分析“用户”应该被划分至哪个子系统。首先,用户这一事物足够的模糊也足够的复杂。说它模糊是因为在会议系统实施的前期我们还无法深刻的认识到用户会有哪些具体的行为,我们仅知道用户可以登录系统,可以创建会议,与会人可以参加会议、会议主持人可以管理会议,但是这些仅仅只是整个项目需求的冰山一角,用户可以参与的功能实在太多了。之所以说它复杂也正是因为用户涉及到的功能众多,为了向那些已知或未知的功能提供用户不同维度的信息以便功能能正常的使用,我们有可能会频繁的修改用户模型。因此,用户模型的可变化性是非常强的。如果把用户模型放入权限子系统,那么一旦用户模型改变就会引起权限子系统的代码改动。我们希望子系统尽可能的稳定,变化率足够的小。另外,用户只是使用角色、权限等模型来证明自己的身份,角色、权限并没有依赖于用户。换句话说,用户模型引用了角色和权限模型,但是角色和权限模型并没有引用用户模型。用户模型的任何变化都不会影响到权限和角色模型的改变。所以,用户和权限子系统里其它模型的内聚性非常低,我们不应该把内聚性低的事物放在同一个程序集里。
未完待续。。。。。。
  领域驱动设计 最新文章
领域驱动设计的基础知识总结
海西 · 云交付 DevOps实践落地方案
多服务器终端交互利器
《静儿的服务治理私房菜》服务治理和架构
服务治理概述
美团.点评服务治理框架
ASP.NET Zero
1.领域驱动简介.2.领域.子域.限界上下文.3.
东麓庄园系统开发
东麓庄园系统开发
上一篇文章      下一篇文章      查看所有文章
加:2017-06-30 21:39:51  更:2017-06-30 21:39:53 
 
360图书馆 软件开发资料 购物精选 新闻资讯 Chinese Culture 龙发科技 开发 中国文化 阅读网 日历 万年历 2020年8日历
2020-8-15 0:16:11
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  编程知识