.NET领域驱动设计―看DDD是如何运用设计模式颠覆传统架构
|
阅读目录:
1】开篇介绍这篇文章不会太长,但是绝对让你对DDD有一个比较直观的认可; 这篇文章所讲到的内容虽然不多但是不太容易被领悟(因为多数人对DDD的理解还是存在很大误区的;),当然也不是多么神奇的东西,只不过是本人最近一直研究DDD的成果一个小小的心得与大家分享一下;本文讲的这些设计方式本身就存在着很大优势,你会发现它与传统三层架构最明显的区别,这也是最有经典优势的地方,最有价值的地方;
网上很多的DDD文章有的还很不错,但是本人也是从对DDD一窍不通再到目前对DDD有一个整体的了解,觉得最大的问题是让能没有接触DDD的朋友能最贴切的体会到DDD到底哪里好,而不是一上来就大片的理论还一些UML模型图;其实完整的示例也只有这两点最有价值了,因为它是DDD所强调的中心; 2】.简单了解缘由(本文的前期事宜)开始本文下面的章节之前先来了解一下我们将要做什么设计,我假设您没有时间阅读“[置顶].NET领域驱动设计―实践(穿过迷雾走向光明)”一文,比较文章也有点长了,所以这里简单介绍一下连续性的内容; 这篇文章我们将运用两个常规的框架设计方法来对核心的业务进行细粒度的分解设计,在以往这点很难实现,所以我为什么要说框架的设计思想,因为我们对设计模式的运用主要在框架、组件这些非业务需求性的基础设施上;那么这里我们将用这些强大的武器来对最难对付的业务扩展性的设计; 本文全部的业务其实是一个简单的学习考试系统的背景,我们下面将要运用强大的设计能力来对【Employee】聚合进行细粒度的设计、配置;之前的设计已经全部结束,数据持久化也设计完成,就剩下编码阶段;编码的最大挑战就在于前期的相关接口的设计,这里是细粒度的接口设计,不是简单的分分层; 图1:
(查看大图) 上图中我用红圈标记出我们下面要扩展的【Employee】聚合,在将模型落实到代码后我们将要通过规约模式来将【Employee】的验证对象化,然后通过设计模式的策略模式将规则策略化,再通过Configuraion Manager来管理所有的业务规则的配置,这个时候IOC就派上用场了,一切都很顺手;传统三层你是无法做到的; 请看下面【Employee】实体类代码: /*==============================================================================
* Author:深度训练
* Create time: 2013-07-08
* Blog Address:http://www.cnblogs.com/wangiqngpei557/
* Author Description:特定领域软件工程实践;
* ==============================================================================*/
namespace Domain.DomainModel.ExaminationModule.Aggregates.EmployeeAgg
{
using System;
using System.Collections.Generic;
using Domain.DomainModel.ApproveModule.Aggregates.ParentMesAgg;
using Domain.DomainModel.ExaminationModule.Aggregates.FieldExaminationAgg;
using Domain.Seedwork;
public partial class Employee : EntityObject
{
public Employee()
{
this.ParentMessage = new HashSet<ParentMessage>();
this.TeacherCheckGroup = new HashSet<TeacherCheckGroup>();
}
public string EID { get; set; }
public string EName { get; set; }
public Nullable<Employee_Marry> IsMarry { get; set; }
public Nullable<int> Age { get; set; }
public string UserName { get; set; }
public string PassWord { get; set; }
public Nullable<Employee_Switch> SWitch { get; set; }
public Nullable<Employee_Role> EmpRole { get; set; }
public Nullable<Employee_Sex> Sex { get; set; }
public virtual ICollection<ParentMessage> ParentMessage { get; set; }
public virtual ICollection<TeacherCheckGroup> TeacherCheckGroup { get; set; }
public void ReSwitch()
{
if (this.SWitch.Value == Employee_Switch.IsFalse)
this.SWitch = Employee_Switch.IsTure;
else
this.SWitch = Employee_Switch.IsFalse;
}
public void Reinitial()
{
PassWord = "000000";
}
}
}
【Employee】聚合跟一般的聚合没多大区别,比较简单的结构,为了看起来完整一点,我加入了两个初始化的行为;ReSwitch是用来启用、关闭当前账户; Reinitial是初始化当前【Employee】的初始默认密码,完全是演示而用; 那么我们下面要做什么呢?在以【Employee】为聚合根里面我们聚合了【ParentMessage】家长留言、【TeacherCheckGroup】站考,两个集合,其实这是用来做导航属性的;实体框架需要这些信息做实体导航使用,在设计的时候你需要权衡你需要多少这样的关联; 现在经过我们对需求的深入分析之后可能会存在这样的变动情况: 【Parent家长】向【Employee教师】【留言】后,教师需要对留言内容做出反馈,比如要【及时的回复】,对于不同的【留言级别】需要给出不同的处理; 这个需求很简单,但是它里面透露出来的是什么?设计的扩展性,这个扩展性在哪里?对于不同的【留言级别】需要给出不同的【处理】,很显然是一个可能随时会变化的点; 【Employee_Priority】代码: /*==============================================================================
* Author:深度训练
* Create time: 2013-07-08
* Blog Address:http://www.cnblogs.com/wangiqngpei557/
* Author Description:特定领域软件工程实践;
* ==============================================================================*/
namespace Domain.DomainModel.ApproveModule.Aggregates.ParentMesAgg
{
using Domain.DomainModel.ExaminationModule.Aggregates.EmployeeAgg;
using System;
public partial class ParentMessage
{
public string PMID { get; set; }
public string PID { get; set; }
public string EID { get; set; }
public string Content { get; set; }
public Nullable<Message_Priority> Priority { get; set; }
public Nullable<System.DateTime> Datetime { get; set; }
public virtual Employee Employee { get; set; }
public virtual Parent Parent { get; set; }
}
}
有一个Priority属性,是标记该留言的紧急情况,看代码: /*==============================================================================
* Author:深度训练
* Create time: 2013-07-08
* Blog Address:http://www.cnblogs.com/wangiqngpei557/
* Author Description:特定领域软件工程实践;
* ==============================================================================*/
namespace Domain.DomainModel.ExaminationModule.Aggregates.EmployeeAgg
{
using System;
public enum Message_Priority : int
{
Normal = 1,Pressing = 2
}
}
有两种级别,Normal表示普通的,Pressing表示紧急的,对于紧急的肯定是需要先处理的,而且处理的逻辑或多或少有点不同;在DDD中所有的业务逻辑都要在DomainModel Layer 中处理,这是原则;所有的逻辑都不是直接使用,比如在登录的时候我们通常是验证用户名密码是否真确,但是通常还会有很多其他的条件,比如说当前用户是否是高级会员、是否欠费等等,这些都是在聚合规约工厂中统一获取的,这就便于我们将变化的点抽到专门的地方进行设计;
(编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |

