架构那点事系列二 - 大话3D

简介:        近几年,架构领域兴起了很多新型架构思想。DDD成为继OOD之后又一个被人津津乐道的设计风格。.这里结合自己工作实践,和大家分享一下自己的DDD实践观,首先向大家推荐一篇关于DDD的文章(http://msdn.microsoft.com/en-us/magazine/hh547108.aspx.看看微软的卓越工作,从DataTable到EntityObject. - Ne

       近几年,架构领域兴起了很多新型架构思想。DDD成为继OOD之后又一个被人津津乐道的设计风格。.这里结合自己工作实践,和大家分享一下自己的DDD实践观,首先向大家推荐一篇关于DDD的文章(http://msdn.microsoft.com/en-us/magazine/hh547108.aspx.看看微软的卓越工作,从DataTable到EntityObject. - Net 4.0来了,随之为我们带来了EntityFramework)。这里,我们抛开语言特性,从本质上分析一下DDD的诸多实践要点。

       首先,我们需要知道DDD和OOD有何不同?在此之前,我们先从模型上进行下对比。对象模型,我们都知道它封装了数据(属性)和行为(方法和事件)。而领域模型则是驻足在某领域内的对象模型。相应地,它的行为是用于表达业务规则和特定的业务逻辑。更重要的是,每个实体都可能处于某一状态,并且与一组动态的验证规则相绑定;领域模型表述的是领域中各个类及其之间的关系。类关系是多样的,比如组合、聚合、继承、实现等,而数据模型不是一对多,就是多对多。从领域驱动设计的角度看,数据库只不过是存储实体的一个外部机制,是属于技术层面的东西。数据模型主要用于描述领域模型对象的持久化方式,应该是先有领域模型,才有数据模型,领域模型需要通过某种映射而产生相应的数据模型(数据依赖于实体,是实体的状态,离开实体的数据是毫无意义)。

       ok,有了基本认识后,我们再来看一下领域驱动设计所倡导的分层。如图:

     

     基础结构层:不解释了。注意,这部分不会涉及任何业务逻辑。传统的数据访问层,也被放在了该层当中,因为数据的读写是业务无关的;
  领域层:包含了领域对象(实体、值对象)、领域服务以及它们之间的关系。这部分内容的具体表现形式就是领域模型。领域驱动设计提倡富领域模型,即尽量将业务逻辑归属到领域对象上,实在无法归属的部分则以领域服务的形式进行定义。
  应用层:该层不包含任何领域逻辑,但它会对任务进行协调,并可以维护应用程序的状态.因此,它更注重流程性的东西。在某些领域驱动设计的实践中,也会将其称为“工作流层”。
  表现层:这个好理解,跟三层里的表现层意思差不多,但请注意,“Web服务”虽然是服务,但它是表现层的东西.
  从上图还可以看到,表现层与应用层之间是通过数据传输对象(DTO)进行交互的,数据传输对象是没有行为的对象,存在的目的只是为了对领域对象进行数据封装,实现层与层之间的数据传递。为何不能直接将领域对象用于数据传递?因为领域对象更注重领域,而DTO更注重数据。不仅如此,由于“富领域模型”的特点,这样做会直接将领域对象的行为暴露给表现层。

        通过上面的回忆,这里大致总结出了DDD实践中需要注意的要点,如下:

       (1).构建领域对象

       DDD喜欢使用rich poco/pojo。当然,它"富裕"的程度要远远大于之前我们所熟悉的ActionForm。除此之外,某些领域模型可以提供用于创建新实例的公共工厂方法(在高并发多构造参数模型下,我会选择使用Builder模式构建)。如果模型类通常是独立的并且实际上不是层次结构的一部分,或者用于创建该类的步骤只是与客户端相关,则可以使用普通的构造函数。但是,在使用聚合根这样的复杂对象时,还需要我们实例化其它抽象级别DO。 DDD 引入了工厂对象的方式,这种方式可将客户端的需求与内部的对象及其关系和规则分离开来。最后,工厂还需要验证输入数据。为此,可使用前提条件(如Assert,Validate,Precondition等开源组件)来保证代码的清晰和高可读性。还可以使用后置条件来确保返回的实例处于有效状态,在.net中,常见的有Code Contracts,Data Annotations与VAB(Enterprise Library Validation Application Block)企业库验证应用程序块 等out-of-box technologies。Java中可以考虑比较流行的DBC框架。

       (2).识别聚合根.

       聚合根是一个通过组合其它实体而得到的实体。聚合根中的对象与外部没有直接的关联,也就是不存在这样的用例—不经过根对象而直接使用这些对象。换句话来说,聚合根负责维护处于有效状态的子对象并持久化这些对象。更通俗的讲,一个聚合是由一些列相联的Entity和Value Object组成(满足某些不变性规则),一个聚合有一个聚合根,聚合根是Entity,整个聚合被看成是一个数据修改的单元,也就是说整个聚合内的所有对象要么同时被保存,要么都不能保存,否则无法确保聚合内的对象的数据一致性。聚合内的所有实体和值对象应该总是一起被取出来一起被保存,因为一个聚合是一个数据持久化的单元。同时,需要注意两点:a.聚合不要设计的过大,过大的聚合很难确保不变性,从而很难确保数据的强一致性;b.聚合与聚合之间不要通过引用的方式来关联,而应该通过ID关联,这样具有更好的性能和可伸缩性。

      (3).仓储&领域服务

      仓储应理解为一个在内存中维护一系列聚合根的集合。仓储提供的接口应该总是接受聚合根或返回聚合根,不能返回聚合内的其他Entity或Value Object。不要把仓储理解为DAO,仓储属于领域模型的一部分,代表了领域模型向外提供接口的一部分,而DAO是表示数据库向上层提供的接口表示。仓储的目的也不是为了支持界面查询,不要为仓储设计一些是为了提供显示数据的接口,仓储提供的所有接口应该仅为领域模型使用。基本的仓储接口只需要三个:Add,Remove,GetById,其他的扩展接口可以根据业务需要扩展接口声明。

      领域服务表示领域模型中的一些业务操作,这些操作通常由多个聚合根或仓储或其他领域服务相互协作完成。领域服务表示领域模型中的一些业务操作,这些操作通常由多个聚合根或仓储或其他领域服务相互协作完成,那么需要为这些操作建立领域服务。首先根据各个聚合的ID获取到操作的相关聚合根,然后调用聚合根完成整个业务操作;比如资金转帐,这是经典的领域服务的例子;再比如在调用某个聚合根做一个数据更新之前需要先判断一些业务规则,但是这些判断规则不能在该聚合根内做,因为这样做可能会导致聚合根依赖于外部的领域服务或仓储,此时,应该交给领域服务来完成规则校验和聚合根数据更新的整个过程。

参考资料:

1.http://www.infoq.com/cn/articles/ddd-in-practice

2.http://msdn.microsoft.com/en-us/magazine/hh547108.aspx

3.http://msdn.microsoft.com/en-us/library/aa697427(v=VS.80).aspx

4.http://www.cnblogs.com/daxnet/archive/2010/07/07/1772581.html

5.http://www.methodsandtools.com/archive/archive.php?id=97p2

6.http://incubator.apache.org/isis/index.html

7.http://www.slideshare.net/jboner/scalability-availability-stability-patterns

目录
相关文章
|
数据可视化
基于WebGL架构的3D可视化平台—三维设备管理(ThingJS实现楼宇设备管理3D可视化)
国内高层建筑不断兴建,它的特点是高度高、层数多、体量大。面积可达几万平方米到几十万平方米。这些建筑都是一个个庞然大物,高高的耸立在地面上,这是它的外观,而随之带来的内部的建筑设备也是大量的。为了提高设备利用率,合理地使用能源,加强对建筑设备状态的监视等,自然地就提出了楼宇自动化控制系统。
2304 0
|
数据可视化
基于WebGL架构的3D可视化平台—新风系统演示
新风系统是根据在密闭的室内一侧用专用设备向室内送新风,再从另一侧由专用设备向室外排出,在室内会形成“新风流动场”,从而满足室内新风换气的需要。实施方案是:采用高风压、大流量风机、依靠机械强力由一侧向室内送风,由另一侧用专门设计的排风风机向室外排出的方式强迫在系统内形成新风流动场。
1189 0
|
数据可视化
基于WebGL架构的3D可视化平台—实现汽车行走路线演示
  小车行走路线演示New VS Old 刚接触ThingJS的时候,写的一个小车开进小区的演示,今天又看了教程中有movePath这个方法就重新写了一遍,其中也遇到了一些问题,尤其突出的问题就是小车过弯的尴尬表现。
1969 0
|
4天前
|
敏捷开发 监控 数据管理
构建高效微服务架构的五大关键策略
【4月更文挑战第20天】在当今软件开发领域,微服务架构已经成为一种流行的设计模式,它允许开发团队以灵活、可扩展的方式构建应用程序。本文将探讨构建高效微服务架构的五大关键策略,包括服务划分、通信机制、数据管理、安全性考虑以及监控与日志。这些策略对于确保系统的可靠性、可维护性和性能至关重要。
|
16天前
|
API 数据库 开发者
构建高效可靠的微服务架构:后端开发的新范式
【4月更文挑战第8天】 随着现代软件开发的复杂性日益增加,传统的单体应用架构面临着可扩展性、维护性和敏捷性的挑战。为了解决这些问题,微服务架构应运而生,并迅速成为后端开发领域的一股清流。本文将深入探讨微服务架构的设计原则、实施策略及其带来的优势与挑战,为后端开发者提供一种全新视角,以实现更加灵活、高效和稳定的系统构建。
20 0
|
4天前
|
消息中间件 监控 持续交付
构建高效微服务架构:后端开发的进阶之路
【4月更文挑战第20天】 随着现代软件开发的复杂性日益增加,传统的单体应用已难以满足快速迭代和灵活部署的需求。微服务架构作为一种新兴的分布式系统设计方式,以其独立部署、易于扩展和维护的特点,成为解决这一问题的关键。本文将深入探讨微服务的核心概念、设计原则以及在后端开发实践中如何构建一个高效的微服务架构。我们将从服务划分、通信机制、数据一致性、服务发现与注册等方面入手,提供一系列实用的策略和建议,帮助开发者优化后端系统的性能和可维护性。
|
15天前
|
Kubernetes 安全 Java
构建高效微服务架构:从理论到实践
【4月更文挑战第9天】 在当今快速迭代与竞争激烈的软件市场中,微服务架构以其灵活性、可扩展性及容错性,成为众多企业转型的首选。本文将深入探讨如何从零开始构建一个高效的微服务系统,覆盖从概念理解、设计原则、技术选型到部署维护的各个阶段。通过实际案例分析与最佳实践分享,旨在为后端工程师提供一套全面的微服务构建指南,帮助读者在面对复杂系统设计时能够做出明智的决策,并提升系统的可靠性与维护效率。
|
1天前
|
监控 API 持续交付
构建高效微服务架构:后端开发的新趋势
【4月更文挑战第23天】 随着现代软件开发实践的不断演进,微服务架构已经成为企业追求敏捷、可扩展和弹性解决方案的首选。本文深入探讨了如何构建一个高效的微服务架构,涵盖了关键的设计原则、技术选型以及实践建议。通过分析微服务的独立性、分布式特性和容错机制,我们将揭示如何利用容器化、服务网格和API网关等技术手段,来优化后端系统的可维护性和性能。文章旨在为后端开发人员提供一套全面的指南,以应对不断变化的业务需求和技术挑战。
|
6天前
|
机器学习/深度学习 运维 Prometheus
探索微服务架构下的系统监控策略
【4月更文挑战第18天】在当今快速迭代和持续部署盛行的软件工程实践中,微服务架构因其灵活性和可扩展性受到企业青睐。然而,随着服务的细粒度拆分和网络通信的增加,传统的监控手段已不再适用。本文将探讨在微服务环境中实施有效系统监控的策略,包括日志聚合、性能指标收集、分布式追踪以及异常检测等关键技术实践,旨在为读者提供构建稳定、可靠且易于维护的微服务系统的参考指南。
12 0