新普金娱乐网址


清理低端人口之偷: 城乡其次最先样式的历史和现状

数学及时就是是自个儿的少女时代啊

同一缕阳光:DDD(领域让设计)应针对实际业务场景,如何聚焦 Domain Model(领域模型)?

  • 十月 16, 2018
  • 地理
  • 没有评论

       
日前,上海市披露2018强中学业水平试实行意见。合格考:语文、数学,书面笔试,时间90分钟,满分100分开;外语,书面笔试(不带有听力,90分钟,满分80瓜分)+听说测试(含听力,采用人机对话方式,30分钟,满分20分);思想政治、历史、地理、物理、化学、生命科学6科均书面笔试,均60分钟,满分均100区划;(以上9科合格线以卷面成绩的标准分值划定)信息科技,上机考试,60分钟;物理、化学、生命科学另设技能操作测试,15分钟(以上4门按测评标准评判成绩是否合格)。等级考试:思想政治、历史、地理、物理、化学、生命科学6科,均书面笔试,均60分钟,满分均100分叉,成绩为阶段见,按取得该次考试有效成绩的考生(即缺考或不得分的考生除了)总数的对应比例划分等级,位次由高至低为
A+、A、B+、B、B_、C+、C、C_、D+、D、E共五等11层,分别约占5%、10%、10%、10%、10%、10%、10%、10%、10%、10%、5%。

描绘在前面

图片 1

  阅读目录:

  • 题目源于是呀?
  • 《领域让设计-软件基本复杂性应针对的志》分层概念
  • Repository(仓储)职责所在?
  • Domain
    Model(领域模型)重新规划
  • Domain
    Service(领域服务)的入
  • MessageManager.Domain.Tests
    的加入
  • Application
    Layer(应用层)的协调?
  • Unit Of
    Work(工作单元)工作范围以及贯彻?
  • 本发布
  • 后记

  以达到等同篇《我的“第一软”,就如此没有了:DDD(领域让设计)理论做实施》博文被,简单介绍了世界让设计的一些理念,并简要就因领域让设计之现实性项目 MessageManager,本人以筹划
MessageManager 项目事先,并无扣留了 Eric
Evans 的《Domain-Driven Design
–Tackling Complexity in the Heart of Software》和 Martin Fowler
的《Patterns of Enterprise Application
Architecture》,《企业应用架构模式》这本书在阅读,关于世界让设计,主要学习来是花园中之
netfocus、dax.net、以及清培兄的有些博文(小弟先在此谢过各位大神的无私奉献),还有即使是解道中的园地让设计专题,当然还有一部分自搜索引擎的片资料,再添加自己之片段酌定和了解,也就算改为了属自己之“领域让设计”。

  MessageManager
项目是对准友好所理解领域让设计的验证,如果您仔细看罢上同样首博文,你晤面发现 MessageManager
其实只是小圈子让设计之“外壳”,就比如我们种植黄瓜,首先使加进一个气,以便黄瓜的长,MessageManager
项目即相当给之架子,核心之事物“黄瓜”并无存在,当时在筹划完 MessageManager
项目之时节,其实已经发现题目的存在,所以于博文最后留下了脚两单问题:

  • Domain
    Model(领域模型):领域模型到底该怎么规划?你见面看到,MessageManager
    项目面临的 User 和 Message
    领域模型是可怜贫血的,没有包含其他的业务逻辑,现在网上广大有关 DDD
    示例项目大部分啊有这种情况,当然项目自身并未事情,只是简单的“CURD”操作,但是只要是有的大型项目的复杂性工作逻辑,该怎么去实现?或者说,领域模型就什么样的业务逻辑?什么才是当真的事情逻辑?这个题材大重点,后续探讨。
  • Application(应用层):应用层作为协调服务层,当遇到复杂的作业逻辑时,到底哪落实,而休设该变为
    BLL(业务逻辑层)?认清本质很要紧,后续探讨。

  另外再贴有园友们于达到同样篇的问题评论:

图片 2

图片 3

图片 4

  关于以上的题目,本篇博文只是做一些解读,希望可以针对那些迷恋于世界让设计之爱侣等有启迪,写得生不当之处,也接指出。

       
以上不惮其烦,只是为验证学考之复杂,何况,后面还有再复杂的高考在齐着考生。1977年12月,40年前的非常冬天,其实是一个社会之春季,570万考生中,有27万3母人幸运地过进了高等学校大的门路。如今,高等教育已经推广,但高考在社会稳步的传统观念里依然不一般,它依然是多多益善人口之人生大门槛。不过,从光复人之角度看,高考检验之只是是人生阶段性表现还是就,在大部考生20年度左右底年华里,用同一张试卷定义整个人生,是挺可怀疑的。未来是为此来要的,人生之怪就在于各一刻都浸透了不为人知与顶可能。好于我们正处在更好之期,这为是一个拣多元化的社会,高考只是人生之平等扇门,还有很多门等在若打开。高考也未是如淘汰谁,它只是提供个人向上的某一个精选。条条大路通罗马,其他选择可能还符合您的上进亦弗克。一个丁的勤奋努力,完全比同涂鸦高考重要得多。

题目源于是啊?

图片 5

  出现上述问题之案由是什么?需求略?设计不客观?准确的来说,应该都非是,我觉得题材的来自是从来不真正去解领域让设计,或者说并未真的用世界让设计之意去设计或落实,领域让设计的定义网上一样找一异常堆,你看了几首文章以后呢能写出来之类的篇章,为什么?因为还是泛泛之谈,诸如:领域模型是小圈子让之中坚;领域让基本分为四层(用户层、应用层、领域层与基础层);领域涵盖实体、值对象和劳动;还有有凑合和聚合根之类的定义等等,文中也会见被你列有片有关这些概念的代码实现,让你瞬间觉得原来领域让设计是这般的高大上。

  但倘若拿这些概念去实践吧?却从来无是那么回事,现在使用领域让设计去付出之信用社实际是最为少了,原因有为数不少种,下面大致列出有些:

  • 开发成本太胜,换句话说,就是要运用世界让设计开,需要请高级程序员、高级架构师和建模专家,一般这种开发人员薪资还比较高,老板确实舍得啊?
  • 开发周期长,花在求分析的流年比丰富,甚至比程序实现还要长,这个对业主来说是异常的,开发周期长,一般会意味着企业之净利润降低,公司赢利下滑,老板的钱管就是瘪了,老板会甘愿为?
  • 付出考虑转变问题,使用世界让设计开发,需要企业里的程序员懂得领域让设计,要指向面向对象(OO)设计出早晚之明亮,现实情况是,大部分的程序员虽然用的是面向对象语言(比如
    Java、C#),却做着面向过程的从事(类似 C
    语言函数式的支出)。现在吃商家之程序员使用领域让设计开,就哼于原先是为此手一直用,现在受你下筷子用,你会习惯也?这得同种植变化,很多程序员会很无惯,这为是小圈子让设计执行难的重要性原因。
  • 关于世界让设计实践经验实在太少,大家脑子被只有模模糊糊的定义,却未曾确切的履,像
    dax.net
    这样失去完几单总体基于领域让设计类之良神实在极端少了,很多还是像本人同,理解一些概念后,放出一个简练的示范
    Demo,然后便从未然后了。

  Eric Evans 于2004年提出 DDD(领域让设计)的见解,距今已十年了,推广也停滞不前,确实值得我们程序员去反省。

  扯得发接触多矣,回到这个可标题:问题之来源是什么?答案可能会不叫而中意,就是没有真的了解领域让设计。这就是说若或会咨询:那实在的领域让设计是啊?这个自家思念才发
Eric Evans
可以答应,但为决不管世界让设计看得这般绝对,领域让设计仅是如出一辙种点,具体的兑现而用实际的道,正而有句古话:师受上家,修行在个人。每个人起每个人之具体悟道,但再次转移为毫无遗忘了师出同门。

  还有少数不怕是,有对象指出简单的政工逻辑是反映不出天地让设计的,关于这或多或少率先我是较倾向的,但一旦去用一些特大型业务场景去做领域让设计的示范,我个人觉得为非绝现实,毕竟时间成本不过胜了。我个人觉得小之工作场景和异常的作业场景都可行使世界让设计实现,只是工作逻辑的复杂度不同,还有即使是适用度也差,小之业务场景用脚本驱动模式去落实,可能会见比较世界让设计区实现重复简便、快速,但是只是凡是业务场景(不论大小),必然蕴含业务逻辑(CRUD
除外),那呢尽管可使用世界让设计去支付,还是那句话,只是不太相符,但做示范示例还是好的。

  业务逻辑的复杂度主要反映于世界模型中,复杂性的事务逻辑,领域模型也即愈繁杂,但同简单性的世界模型实质是如出一辙的。关于如何真正明白领域让设计?这同沾自己个人觉得方法尽管是“迭代”,惟有不断的错过实践,不断的错过体会,才能够确实的失理解领域让设计,就如
MessageManager
项目,每一样软稍体会我就是会当这么做不成立,那就算推倒重建,可能这么做而无客观,那就推倒重重建。。。

  闲话少说,来拘禁这同一不好的“迭代”:

       
2018年的高考大纲也揭示了。同40年前比较,现在的高考,有矣再度胜似之信度、效度,其立德树人、服务选才、引导教学的主干力量发挥得更好,必备知识、关键力量、学科素养、核心价值之考试内容更完美,基础性、综合性、应用性、创新性的试验正式再次宏观。

《领域让设计-软件基本复杂性应本着之志》分层概念

  横流:这同节点是本人后长的,真是造化,在自身勾勒就首博客的当儿,正好有号非知名的爱人,发消息说他张自家前的均等篇博文,我当温柔遭遇跪求《领域让设计-软件基本复杂性应本着之道》这本开,因为网上没有得打。正好他来
Word
版,虽然内容有点错别字,但是真诚感谢这号非红的对象。大致阅读了下目录结构,确实是自家思念要之,接下去会认真的拜读,有真相书之口舌当然再好,下面是选自即仍开之旁概念。

图片 6

  在面向对象的次中,用户界面(UI)、数据库与另支持代码,经常为直写及工作对象吃错过。在UI和数据库脚本的作为中嵌入额外的业务逻辑。出现这种场面是以由短期的观点看,它是要是系统运行起来的最容易的方法。当与世界有关的代码和大量之外代码乱在一道时,就颇不便阅读并了解了。对UI的简约改动就会见改变工作逻辑。改变工作规则可能得小心地跟踪UI代码、数据库代码或者其他的主次元素。实现均等的模子驱动对象变得不切实际,而且自动化测试呢难以使用。如果当次的每个行为被连了独具的技巧与逻辑,那么她要十分简短,否则会难以掌握。

  将一个错综复杂的程序开展层次分。为各国一样重合进行统筹,每层还是内聚的同时只有因让她的下层。采用标准的架模式来就与上层之涣散关联。将有所和天地模型相关的代码都汇集在同样重叠,并且用其与用户界面层、应用层和底蕴结构层的代码分离。世界对象好拿重要放在表达领域模型上,不待关注她自己的示、存储和管理采用任务等情节。这样一旦模型发展得够长与鲜明,足以挑动实质的业务知识并实现它。

用户界面层(表示层) 负责向用户显示信息,并且解析用户命令。外部的执行者有时可能会是其他的计算机系统,不一定非是人。
应用层 定义软件可以完成的工作,并且指挥具有丰富含义的领域对象来解决问题。这个层所负责的任务对业务影响深远,对跟其他系统的应用层进行交互非常必要这个层要保持简练。它不包括处理业务规则或知识,只是给下一层中相互协作的领域对象协调任务、委托工作。在这个层次中不反映业务情况的状态,但反映用户或程序的任务进度的状态
领域层(模型层) 负责表示业务概念、业务状况的信息以及业务规则。尽管保存这些内容的技术细节由基础结构层来完成,反映业务状况的状态在该层中被控制和使用。这一层是业务软件的核心。
基础结构层 为上层提供通用的技术能力:应用的消息发送、领域持久化,为用户界面绘制窗口等。通过架构框架,基础结构层还可以支持这四层之间的交互模式。

  一个目标所代表的东西是一个负有连续性和标识的概念(可以跟该事物经历的不同的状态,甚至可以叫该事物跨越不同之贯彻),还是就是一个就此来讲述事物之某种状态的特性?这即是实体和价值对象极其中心的分。明确地选用这点儿种模式受到之等同栽来定义对象,可以假设对象的意义又清,并得以带我们组织出一个状的统筹。

  另外,领域中还存不少底端,如果因此行止或者操作来讲述其会比用对象来描述更加分明。尽管与面向对象建模理念稍有矛盾,但这些不过是因此劳动来讲述,而未是用以此操作的职责强加到一点实体或值对象身上。服务用来呢客户要提供劳务。在软件的技术层中就是出许多劳动。服务为会见当圈子中冒出,它们用于对软件要做到的一部分动进行建模,但是和状态无关。有时我们不能不于目标模型中釆取一些投降的办法——这是不可避免的,例如使用关系数据库进行仓储时便会现出这种情形。本章将会见让闹部分规则,当遇到这种复杂气象常常,遵守这些规则可使我们保持正确的大方向。

  最后,我们对模块(Module)的座谈得辅助了解这样的看法:每个规划决策都当是基于对世界的正确理解来做出。高内聚、低关联这种考虑往往给视作是不错之技术标准,它们于概念本身也是适用的。在范驱动的宏图中,模块是范的均等有,它们当能够体现来天地受到的定义。

       
虽然针对高考的批评不绝于耳,虽然高考是一致种植不周到的挑选,但是,今天,我们尽可从容看待高考。不必如40年前那样欢呼雀跃,也不要心急着“棒杀”,它还有有的意思以及理由。(17.12.21《教育》)

Repository(仓储)职责所在?

  言归正题。

  Repository(仓储)的定义可以参考:http://www.cnblogs.com/dudu/archive/2011/05/25/repository_pattern.html,我个人于赞成
dudu 的喻:Repository
是一个独门的叠,在于领域层及数码映射层(数据访问层)之间。它的是为世界层备感不顶数码访问层的存,它提供一个类似集合的接口提供被世界层进行领域对象的访。Repository
是仓库管理员,领域层需要什么事物就需要报仓库管理员,由仓库管理员将东西用给其,并不需要知道东西实际在哪。

  关于 Repository
的定义,在《企业应用架构模式》书中呢时有发生征:和谐领域以及数据映射层,利用类似于聚集的接口来拜访领域对象。开中拿
Repository 翻译啊资源库,其实是同仓储是一个意,关于 Repository 这同样节点的内容,我大概阅读了两三篇才知晓了片情节(这仍开于抽象难知晓,需要多读几整个,然后因自己之解进行推敲酝酿),文中也深受出了一个演示:查找一个口所当的机关(Java),以便让深化对
Repository 的明。

  我们先行看一下 Repository
的概念前半句:协调领域和数据映射层,也即是 dudu
所说之在领域层及数目映射层之间,理解当下等同点十分重大,非常重要。然后我们还来拘禁
MessageManager 项目遭到有关 Repository
的使(实现无问题),在哪用也?根据定义我们应该使错过世界层去找寻 Repository 的采取,但是咱当
MessageManager.Domain 项目面临找找不顶有关 Repository
的半毛应用,却以 MessageManager.Application
项目受到找到了:

  1 /**
  2 * author:xishuai
  3 * address:https://www.github.com/yuezhongxin/MessageManager
  4 **/
  5 
  6 using System;
  7 using System.Collections.Generic;
  8 using AutoMapper;
  9 using MessageManager.Application.DTO;
 10 using MessageManager.Domain;
 11 using MessageManager.Domain.DomainModel;
 12 using MessageManager.Domain.Repositories;
 13 
 14 namespace MessageManager.Application.Implementation
 15 {
 16     /// <summary>
 17     /// Message管理应用层接口实现
 18     /// </summary>
 19     public class MessageServiceImpl : ApplicationService, IMessageService
 20     {
 21         #region Private Fields
 22         private readonly IMessageRepository messageRepository;
 23         private readonly IUserRepository userRepository;
 24         #endregion
 25 
 26         #region Ctor
 27         /// <summary>
 28         /// 初始化一个<c>MessageServiceImpl</c>类型的实例。
 29         /// </summary>
 30         /// <param name="context">用来初始化<c>MessageServiceImpl</c>类型的仓储上下文实例。</param>
 31         /// <param name="messageRepository">“消息”仓储实例。</param>
 32         /// <param name="userRepository">“用户”仓储实例。</param>
 33         public MessageServiceImpl(IRepositoryContext context,
 34             IMessageRepository messageRepository,
 35             IUserRepository userRepository)
 36             :base(context)
 37         {
 38             this.messageRepository = messageRepository;
 39             this.userRepository = userRepository;
 40         }
 41         #endregion
 42 
 43         #region IMessageService Members
 44         /// <summary>
 45         /// 通过发送方获取消息列表
 46         /// </summary>
 47         /// <param name="userDTO">发送方</param>
 48         /// <returns>消息列表</returns>
 49         public IEnumerable<MessageDTO> GetMessagesBySendUser(UserDTO sendUserDTO)
 50         {
 51             //User user = userRepository.GetUserByName(sendUserDTO.Name);
 52             var messages = messageRepository.GetMessagesBySendUser(Mapper.Map<UserDTO, User>(sendUserDTO));
 53             if (messages == null)
 54                 return null;
 55             var ret = new List<MessageDTO>();
 56             foreach (var message in messages)
 57             {
 58                 ret.Add(Mapper.Map<Message, MessageDTO>(message));
 59             }
 60             return ret;
 61         }
 62         /// <summary>
 63         /// 通过接受方获取消息列表
 64         /// </summary>
 65         /// <param name="userDTO">接受方</param>
 66         /// <returns>消息列表</returns>
 67         public IEnumerable<MessageDTO> GetMessagesByReceiveUser(UserDTO receiveUserDTO)
 68         {
 69             //User user = userRepository.GetUserByName(receiveUserDTO.Name);
 70             var messages = messageRepository.GetMessagesByReceiveUser(Mapper.Map<UserDTO, User>(receiveUserDTO));
 71             if (messages == null)
 72                 return null;
 73             var ret = new List<MessageDTO>();
 74             foreach (var message in messages)
 75             {
 76                 ret.Add(Mapper.Map<Message, MessageDTO>(message));
 77             }
 78             return ret;
 79         }
 80         /// <summary>
 81         /// 删除消息
 82         /// </summary>
 83         /// <param name="messageDTO"></param>
 84         /// <returns></returns>
 85         public bool DeleteMessage(MessageDTO messageDTO)
 86         {
 87             messageRepository.Remove(Mapper.Map<MessageDTO, Message>(messageDTO));
 88             return messageRepository.Context.Commit();
 89         }
 90         /// <summary>
 91         /// 发送消息
 92         /// </summary>
 93         /// <param name="messageDTO"></param>
 94         /// <returns></returns>
 95         public bool SendMessage(MessageDTO messageDTO)
 96         {
 97             Message message = Mapper.Map<MessageDTO, Message>(messageDTO);
 98             message.FromUserID = userRepository.GetUserByName(messageDTO.FromUserName).ID;
 99             message.ToUserID = userRepository.GetUserByName(messageDTO.ToUserName).ID;
100             messageRepository.Add(message);
101             return messageRepository.Context.Commit();
102         }
103         /// <summary>
104         /// 查看消息
105         /// </summary>
106         /// <param name="ID"></param>
107         /// <returns></returns>
108         public MessageDTO ShowMessage(string ID, string isRead)
109         {
110             Message message = messageRepository.GetByKey(ID);
111             if (isRead == "1")
112             {
113                 message.IsRead = true;
114                 messageRepository.Update(message);
115                 messageRepository.Context.Commit();
116             }
117             return Mapper.Map<Message, MessageDTO>(message);
118         }
119         #endregion
120     }
121 }

本着,你都意识了 Repository
的踪迹,Repository
应用在应用层,这样就是造成应用层和基础层(我把数据持久化放在基础层了)通信,忽略了最要的世界层,领域层在里面由及之用意最为多吗就算是传递一个老大贫血的天地模型,然后经
Repository
进行“CRUD”,这样的结果是,应用层不成为所谓的
BLL(常说之事体逻辑层)才怪,另外,因为业务逻辑都位于应用层了,领域模型也易得更贫血。

  以上剖析可以答应上平等首被遗留的题材:应用层作为协调服务层,当遇复杂的业务逻辑时,到底哪实现,而不苟其成为
BLL(业务逻辑层)?其实关于率先个问题(领域模型如何统筹不贫血)也是可开展解答的,这个后一样节点出说明,关于这无异于名目繁多题材的招自己道就是是
Repository
设计,出现了惨重和驳斥偏移,以致被尚未拿设计重点作在工作逻辑上,在这与豪门说声抱歉。

  关于“应用层中之事务逻辑”,比如下面就段代码:

 1         /// <summary>
 2         /// 查看消息
 3         /// </summary>
 4         /// <param name="ID"></param>
 5         /// <returns></returns>
 6         public MessageDTO ShowMessage(string ID, string isRead)
 7         {
 8             Message message = messageRepository.GetByKey(ID);
 9             if (isRead == "1")
10             {
11                 message.IsRead = true;
12                 messageRepository.Update(message);
13                 messageRepository.Context.Commit();
14             }
15             return Mapper.Map<Message, MessageDTO>(message);
16         }

  对,你都圈出来了,查看消息,要因阅读人,然后判断是否已经读,如果是读人是收件人,并且信息是不念状态,要管这个消息置为曾经读状态,业务逻辑没什么问题,但是也放错了职(应用层),应该在领域层中(领域模型),其实这都是
Repository
惹的重伤,因为应用层根本没和领域层通信,关于世界模型的计划下节点有教学。

  看了上述之情,是休是有点:拨开浓雾,见晴天的觉得?不知晓乃发无发生?反正我是发生,关于
Repository
我们重了解的死一点,先押一下继半句的定义:行使类似于聚集的接口来走访领域对象。赶巧而
dudu 理解的如此:Repository
是堆栈管理员,领域层需要什么事物就待报仓库管理员,由仓库管理员将东西用给它们,并不需要知道东西实际在哪。可以这么懂也 Repository
就像一个询问集合,只提供查询给世界层,但是咱发现于实际利用被 Repository
也提供了持久化操作,这或多或少审给 Repository
有点莫名其妙了,关于这无异沾我觉着 CQRS(Command Query Responsibility
Segregation)模式可以非常好的解决,翻译为令查询的天职分开,顾名思义,就是命令(持久化)和询问职责进行分离,因为自己从不对准
CQRS
进行了研究,也未曾看到过具体的言传身教,所以就边就未多说,但是自己以为这是同领域让设计的周全结合,后面来会可研究下。

  说了那基本上,那
Repository(仓储)职责到底是什么?可以这么对:Repository,请服务好
Domain,而且只限服务被外(防止小三),他要什么您若让啊,为什么?因为他是公大爷,跟在他来肉吃。

图片 7

Domain Model(领域模型)重新规划

  领域模型是世界让设计的核心,这或多或少凡毋容置疑的,那世界模型中的骨干是呀?或者说实现之是什么?答案是业务逻辑,那事情逻辑又是呀?或者说什么样的“业务逻辑”才能够叫真正含义及之业务逻辑,关于此问题,在齐同一篇中遗留如下:

世界模型到底该怎么统筹?你晤面看出,MessageManager
项目遭到的 User 和 Message
领域模型是大贫血的,没有包含其他的业务逻辑,现在网上广大关于 DDD
示例项目多数乎存这种情形,当然项目自己没有工作,只是简单的“CRUD”操作,但是只要是局部大型项目的纷繁工作逻辑,该怎么去贯彻?或者说,领域模
型完成什么样的事务逻辑?什么才是真正的事情逻辑?这个题目特别重点,后续探讨。

  什么才是当真的事情逻辑?CRUD
?持久化?还是像“GetUserByName、GetMessageByID”之类的查询,我个人感觉这些都非是真的含义及的工作逻辑(注意,是个人感觉),因为每个品种会有“CRUD”、持久化,并无只有限于某一样种业务场景,像“GetUserByName、GetMessageByID”之类的查询才是询问,了解了面
Repository 的发,你晤面发现这些查询工作相应是 Repository
做的,他是吗世界模型服务之。

  说了那么多,那什么才是实在意义及之作业逻辑?本身个人感觉改变世界模型状态或行为的事体逻辑,才会称之为真正意义上的政工逻辑(注意,是个人感觉),比如自己当
Repository
节点中说罢之一个演示:读取信息,要根据目前读人以及手上信息之状态来安当前消息的状态,如果手上读书人为收件人和当前消息呢无念状态,就如将当下信息状态设置为曾读,以前这个工作逻辑的落实是以应用层中:

 1         /// <summary>
 2         /// 查看消息
 3         /// </summary>
 4         /// <param name="ID"></param>
 5         /// <returns></returns>
 6         public MessageDTO ShowMessage(string ID, string isRead)
 7         {
 8             Message message = messageRepository.GetByKey(ID);
 9             if (isRead == "1")
10             {
11                 message.IsRead = true;
12                 messageRepository.Update(message);
13                 messageRepository.Context.Commit();
14             }
15             return Mapper.Map<Message, MessageDTO>(message);
16         }

  这种实现方式尽管会见管应用层变为所谓的
BLL(业务逻辑层)了,正确的方法实现该在 Domain
Model(领域模型)中,如下:

 1         /// <summary>
 2         /// 阅读消息
 3         /// </summary>
 4         /// <param name="CurrentUser"></param>
 5         public void ReadMessage(User CurrentUser)
 6         {
 7             if (!this.IsRead && CurrentUser.ID.Equals(ToUserID))
 8             {
 9                 this.IsRead = true;
10             }
11         }

  因为 MessageManager
这个类型之作业场景非常简单,很多还是粗略的 CRUD
操作,可以抽离出真的事情逻辑实在太少,除了上面阅读消息,还有就是是于殡葬信息的时候,要基于发送用户称以及接受用户称,来安装信息的出殡用户与承受用户之
ID 值,这个操作以前我们也是当应用层中实现之,如下:

 1         /// <summary>
 2         /// 发送消息
 3         /// </summary>
 4         /// <param name="messageDTO"></param>
 5         /// <returns></returns>
 6         public bool SendMessage(MessageDTO messageDTO)
 7         {
 8             Message message = Mapper.Map<MessageDTO, Message>(messageDTO);
 9             message.FromUserID = userRepository.GetUserByName(messageDTO.FromUserName).ID;
10             message.ToUserID = userRepository.GetUserByName(messageDTO.ToUserName).ID;
11             messageRepository.Add(message);
12             return messageRepository.Context.Commit();
13         }

  改善在 Domain
Model(领域模型)中之兑现,如下:

 1         /// <summary>
 2         /// 加载用户
 3         /// </summary>
 4         /// <param name="sendUser"></param>
 5         /// <param name="receiveUser"></param>
 6         public void LoadUserName(User sendUser,User receiveUser)
 7         {
 8             this.FromUserID = sendUser.ID;
 9             this.ToUserID = receiveUser.ID;
10         }

  因为简单的 CRUD
操作不见面发生变化,而这些事情逻辑会经常发生变化,比如为消息受到加载用户信息,可能现在加载的是
ID
值,以后或会见补充加另的用户价值,比如:用户地理位置等等,这样咱们设去修改领域模型就好了,应用层一点且非需改,如果还是事先的贯彻方式,你晤面发现我们是要要修改应用层的,领域模型才是一个空壳。

Domain Service(领域服务)的进入

  关于 Domain
Service(领域服务)的定义,可以参照:http://www.cnblogs.com/netfocus/archive/2011/10/10/2204949.html#content_15,netfocus
兄关于世界服务讲解的可怜透,以下摘自个人觉得好的片段:

  • 世界面临之有的定义不顶符合建模为对象,即归类到实体对象要值对象,因为其本质上就是是有操作,一些动作,而无是物。这些操作还是动作往往会涉嫌到大半只领域对象,并且需要协调这些世界对象共同完成这个操作还是动作。如果强行以这些操作职责分配为其它一个对象,则让分配的目标就是是肩负部分未拖欠担的任务,从而会导致对象的职责不显著充分糊涂。但是依据类的面向对象语言规定外性质或作为都得放在对象中。所以我们需要摸索相同种新的模式来代表这种跨多独对象的操作,DDD认为服务是一个不胜自然之范式用来对号入座这种超越多单目标的操作,所以就算出矣世界服务这个模式。
  • 自身认为模型(实体)与劳动(场景)是针对性天地的同样种划分,模型关注世界的民用行为,场景关注世界的群体行为,模型关注世界的静态结构,场景关注世界的动态功能。这吗切合了切实中冒出的各种场面,有动有静,有单独有合作。
  • 世界服务还有一个死重大之效用就是好避领域逻辑泄露及应用层。

  另外还有一个用于说明应用层服务、领域服务、基础服务的任务分配的小示例:

  应用层服务

  1. 博输入(如一个XML请求);
  2. 出殡信息被世界层服务,要求该落实转帐的事务逻辑;
  3. 领域层服务处理成,则调用基础层服务发送Email通知;

  领域层服务

  1. 取源帐号以及目标帐号,分别通报源帐号和对象帐号进行扣除金额和长金额之操作;
  2. 提供返回结果于应用层;

  基础层服务

  1. 照应用层的伸手,发送Email通知;

  通过上述示范,可以挺清楚的明白应用层服务、领域服务、基础服务之任务,关于这些概念的明亮,我深信 netfocus
兄是通过多实践得出的,因为未执行看这些概念和实行了之后再拘留这些概念,完全是见仁见智之感觉到。

  言归正传,为什么而入 Domain
Service(领域服务)?领域服务在我们前面筹 MessageManager
项目之时段并从未,其实自己脑海中直接是有这概念,因为 Repository
的职责混乱,所以最后领域模型变得这么鸡肋,领域服务也即从未有过在,那为何现在若在世界服务吗?因为
Repository
的天职分开,使得世界模型变成重中之重,因为应用层不跟 Repository
通信,应用层又未能够直接与天地模型通信,所以才见面来天地服务的投入,也非得有世界服务之入。通过地方概念的掌握,你可能会见指向世界服务之来意来必然的了解,首先领域服务没有状态,只有行为,他同
Repository
一样,也是吧世界模型服务之,只不过他如一个外交官一样,需要跟应用层打交道,用来协调领域模型和应用层,而 Repository
只是一个女佣,只是服务让世界模型。

  概念理解的大都了,我们来拘禁一下切实可行的落实,以下是
MessageDomainService 领域服务被之均等段代码:

1         public Message ShowMessage(string ID,User CurrentUser)
2         {
3             Message message = messageRepository.GetByKey(ID);
4             message.ReadMessage(userRepository.GetUser(new User { Name = CurrentUser.Name }));
5             messageRepository.Update(message);
6             messageRepository.Context.Commit();
7             return message;
8         }

  这段代码表示查看消息,可以看来实际领域服务做的工作就是做事流程的操纵,注意是办事流程处理,并无是业务流程,业务流程
ReadMessage
是天地模型去做到的,领域模型的打算只是是协调。还闹个谜就是,你会见到在领域服务被以及了
Repository,在我们事先的授课中,Repository
不是才服务为世界模型呢?其实换个角度来拘禁,领域服务呢得以作为是世界模型的平种植表现,Repository
现在首要提供的凡查询集合和持久化,领域模型不得以自身操作,那这些工作只有领域服务去就,关于这或多或少,就可以看出 Repository
的利用有点不顶合理,不亮用 CQRS
模式会无会见是任何一样种植状况。

  另外,你会看出就同段子代码:messageRepository.Context.Commit();,这个是
Unit Of
Work(工作单元)的业务提交,这个工作是小圈子服务一旦举行的为?关于这或多或少是发局部疑问,在下面节点受到产生解读。

MessageManager.Domain.Tests 的加入

  关于单元测试可以参见:http://www.cnblogs.com/xishuai/p/3728576.html,MessageManager.Domain.Tests
单元测试在事先的 MessageManager
项目遭到并没添加,不是无思量添加,而是增补加了不要紧意思,为什么?因为之前的园地模型那么贫血,只是有性与字段,那加加单元测试有什么意思?能测出来呀东西?当把工作聚焦在圈子模型上的时刻,对世界的单元测试将会晤异常的发必要。

  来拘禁 DomainTest
单元测试的局部代码:

 1 using MessageManager.Domain.DomainModel;
 2 using MessageManager.Domain.DomainService;
 3 using MessageManager.Repositories;
 4 using MessageManager.Repositories.EntityFramework;
 5 using NUnit.Framework;
 6 using System;
 7 using System.Collections.Generic;
 8 using System.Linq;
 9 using System.Text;
10 
11 namespace MessageManager.Domain.Tests
12 {
13     [TestFixture]
14     public class DomainTest
15     {
16         [Test]
17         public void UserDomainService()
18         {
19             IUserDomainService userDomainService = new UserDomainService(
20                 new UserRepository(new EntityFrameworkRepositoryContext()));
21             List<User> users = new List<User>();
22             users.Add(new User { Name = "小菜" });
23             users.Add(new User { Name = "大神" });
24             userDomainService.AddUser(users);
25             //userDomainService.ExistUser();
26             //var user = userDomainService.GetUserByName("小菜");
27             //if (user != null)
28             //{
29             //    Console.WriteLine(user.Name);
30             //}
31         }
32     }
33 }

  其实上面我贴的单元测试的代码有些不客观,你见面盼只是测试的持久化操作,这些当是基础层就的干活,应该由基础层的单元测试进行测试的,那世界层的单元测试测试的是啊东西?应该是天地模型中的业务逻辑,比如
ReadMessage 内之操作:

1         [Test]
2         public void MessageServiceTest()
3         {
4             IMessageDomainService messageDomainService = new MessageDomainService(
5                 new MessageRepository(new EntityFrameworkRepositoryContext()),
6                 new UserRepository(new EntityFrameworkRepositoryContext()));
7             Message message = messageDomainService.ShowMessage("ID", new User { Name = "小菜" });
8             Console.WriteLine(message.IsRead);
9         }

Application Layer(应用层)的协调?

Application
Layer(应用层):定义软件可以成功的办事,并且指挥具有丰富意义的世界对象来化解问题。这个层所负责之任务对业务影响深远,对和其它系统的应用层进行互动非常必要之层要保持简练。它不包处理业务规则或文化,只是于下一样重叠中相互协作的小圈子对象协调任务、委托工作。在此层次中不反映工作情况的状态,但反映用户要程序的职责进度的状态。

  以上是《领域让设计-软件基本复杂性应本着之志》书被关于应用层给有底概念,应用层是格外薄的同等交汇,如果你的应用层很“厚”,那您的应用层设计虽决然起了问题。关于 Application
Layer(应用层)的动,正而 Eric Evans
所说:不包处理业务规则或知识,只是被下一样叠中相互协作的园地对象协调任务、委托工作。重点就是:未分包业务逻辑,协调任务。

  如果以好之知情去设计应用层,很可能会见如自己平拿她变成工作逻辑层,所以于筹划过程中一定要是谨记上面两点。不带有业务逻辑很好理解,前提是要是理解啊才是真的的政工逻辑(上面来说明),后面同样句协调任务而是啊意思吧?在验证遭到后还有一样词:在是层次中莫反映工作情况的状态,但反映用户要程序的职责进度的状态。也就算是办事流程的操纵,比如一个养工艺流程,应用层的打算就是比如是此生产流程的控制器,具体生产什么它不欲管住,它而可以配零件然后进行结合展示被用户,仅此而已,画了一致布置示意图,以便大家的了解:

图片 8

  另外,应用层因为要针对性表现层及天地层开展任务协调,这当中会干到数量的对象转换,也就是是
DTO(数据传对象),有关 DTO 的定义以及 AutoMapper
的采用可参见:http://www.cnblogs.com/xishuai/tag/DTO\_AutoMapper,这些干活儿是于应用层中进行拍卖的,就比如生产流程,组装了产品晚,需要针对那个进行包装才能够开展亮:

 1         /// 对应用层服务进行初始化。
 2         /// </summary>
 3         /// <remarks>包含的初始化任务有:
 4         /// 1. AutoMapper框架的初始化</remarks>
 5         public static void Initialize()
 6         {
 7             Mapper.CreateMap<UserDTO, User>();
 8             Mapper.CreateMap<MessageDTO, Message>();
 9             Mapper.CreateMap<User, UserDTO>();
10             Mapper.CreateMap<Message, MessageDTO>()
11                 .ForMember(dest => dest.Status, opt => opt.ResolveUsing<CustomResolver>());
12         }
13         public class CustomResolver : ValueResolver<Message, string>
14         {
15             protected override string ResolveCore(Message source)
16             {
17                 if (source.IsRead)
18                 {
19                     return "已读";
20                 }
21                 else
22                 {
23                     return "未读";
24                 }
25             }
26         }

Unit Of Work(工作单元)工作范围及落实?

  关于 Unit Of
Work(工作单元)的定义可以参照:http://www.cnblogs.com/xishuai/p/3750154.html。

Unit Of
Work:维护让工作工作影响的靶子列表,并协调变化之写入和出现问题的解决。即管理对象的
CRUD 操作,以及对应的事体和产出问题相当。Unit of Work
是因此来解决世界模型存储和改变工作,而这些数据层业务并无属世界模型本身装有的。

  工作单元的概念在《企业应用架构模式》中吗发说明,定义如下:维护为工作工作影响的对象列表,并协调变化之写入和产出问题的缓解。概念的懂得并没什么问题,我怀念发挥的凡办事单元的劳作范围以及如何贯彻?先说生工作范围,我们看下自己曾经画的平等摆放工作单元的流程图:
图片 9

点击查阅大图

  从示意图中可见到,工作单元的限量是制止
Repository 的,也就是说工作单元是力不从心跨 Repository
提交业务的,只能于同一个囤积内管理业务的一致性,就如我们下的
using(MessageManagerDbContext context = new MessageManagerDbContext())
一样,只是局限为这个 using
块,我已经于天地层的单元测试中召开如下测试:

 1         [Test]
 2         public void DomainServiceTest()
 3         {
 4             IUserDomainService userDomainService = new UserDomainService(
 5                 new UserRepository(new EntityFrameworkRepositoryContext()));
 6             IMessageDomainService messageDomainService = new MessageDomainService(
 7                 new MessageRepository(new EntityFrameworkRepositoryContext()),
 8                 new UserRepository(new EntityFrameworkRepositoryContext()));
 9             List<User> users = new List<User>();
10             users.Add(new User { Name = "小菜" });
11             users.Add(new User { Name = "大神" });
12             userDomainService.AddUser(users);
13             messageDomainService.DeleteMessage(null);
14         }

  我以 MessageDomainService
中付出业务,因为事先 UserDomainService
已经上加了用户,但是并从未长用户成功,工作单元中之 Committed 值为
false,其实关于工作单元范围的题材,我现在连不曾强烈的想法,现在是受制在蕴藏中,那提交的工作操作就务须在领域服务遭遇,也就是是:messageRepository.Context.Commit();,但是又见面看这样聊不客观,工作单元应该是贯穿整个项目的,并不一定局限在某个一样囤中,而且工作之处理液应该置身应用层中,因为当时是他的干活,协调工作流的处理。

  如果这种想是不错吧,实现起来实在来几难度,因为本
ORM(对象关系映射)使用的凡
EntityFramework,所以工作单元的实现是格外简单的,也即是运用 SaveChanges()
方法来交给业务,我以《企业应用架构模式》中视工作单元的实现,书中列有了一个简约的例证,还只有是汇聚的管住,如果未采取部分
ORM 工具,实现起来就不但是 SaveChanges()
一段代码的转业了,太局限为技术了,确实是个问题。

  这等同节点的情节只是提出有问号,并未产生化解之办法,希望后面可以追究下。

本子发布

  MessageManager
项目解决方案目录:

图片 10

  • GitHub
    开源地址:https://github.com/yuezhongxin/MessageManager
  • ASP.NET MVC
    发布地方:http://www.xishuaiblog.com:8081/
  • ASP.NET WebAPI
    发布地方:http://www.xishuaiblog.com:8082/api/Message/GetMessagesBySendUser/小菜

  注:ASP.NET WebAPI
暂只有含有:获取发送放消息列表和收获接收方消息列表。

  调用示例:

  • GetMessagesBySendUser(获取发送方):http://www.xishuaiblog.com:8082/api/Message/GetMessagesBySendUser/用户名
  • GetMessagesByReceiveUser(获取接受方):http://www.xishuaiblog.com:8082/api/Message/GetMessagesByReceiveUser/用户名

  WebAPI 客户端调用可以参照
MessageManager.WebAPI.Tests 单元测试项目面临之演示调用代码。

  注:因为 GitHub 中对 MessageManager
项目进展了翻新,如果想看上一版本,下载地址:http://pan.baidu.com/s/1gd9WmUB,可以和水土保持版本对照下,方便学习。

  另外,《领域让设计.软件基本复杂性应本着之道》Word
版本,下载地址:http://pan.baidu.com/s/1bnndOcR

后记

图片 11

  这首博文不知不觉写点儿天了(周末),左手吗发出硌不那么巧了,如果又写下来,大家吧该骂我了(看得极度费事),那即便做一下总吧:

  关于世界模型的规划,我个人感觉是天地让设计被极为难之部分,你晤面见到眼前本身当 MessageManager
项目遭到才出个别个点子,一部分由是工作场景最简单,另一样片因或者是自我计划的非客观,复杂性业务场景的圈子模型是基本上个类之间协调处理,并会见出一些设计模式的入,是一对一复杂的。

  需要留意的一点凡是,本篇以上内容连无是叙
Domain
Model(领域模型)到底哪实现?而是如何聚焦领域模型?只有聚焦在天地模型上,才会将世界模型设计的再度合理,这吗多亏下同样步用追究的内容。

  或者那么句话,真正掌握与用
DDD(领域让设计)的唯一方式,个人感觉还是“迭代”:不断的失去执行,不断的失体会。不客观那就是推倒重建,再未成立那就推倒重重建。。。

  如果您觉得本篇文章对而富有助,请点击右侧下“推荐”,^_^

  参考资料:

  • http://www.cnblogs.com/dudu/archive/2011/05/25/repository_pattern.html
  • http://www.cnblogs.com/1-2-3/category/109191.html
  • http://www.jdon.com/ddd.html
  • http://www.cnblogs.com/daxnet/archive/2009/03/31/1686984.html
  • http://www.cnblogs.com/netfocus/archive/2011/10/10/2204949.html
  • http://www.oschina.net/question/12_21641

相关文章

No Comments, Be The First!
近期评论
    分类目录
    功能
    网站地图xml地图