<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>avidmouse</title>
    <description></description>
    <link>http://avidmouse.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>DDD(Domain-Driven Design)的推理过程</title>
        <author>avidmouse</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://avidmouse.javaeye.com">avidmouse</a>&nbsp;
          链接：<a href="http://avidmouse.javaeye.com/blog/179788" style="color:red;">http://avidmouse.javaeye.com/blog/179788</a>&nbsp;
          发表时间: 2008年04月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          DDD quickly的翻译者之一，孙向晖总结的DDD的中心思想是：关注精简的业务模型及实现的匹配。看了之后，五体投地，总结的太精辟了。<br /><br />	我们知道，软件开发通常被应用到真实世界中已经存在的自动化流程，或者给真实的业务问题提供解决方案，即要自动化的业务流程或者可以用软件解决的现实问题。既然要解决现实问题，唯物辩证思想给我们指了条光明大道：分析问题，解决问题。<br />	毛主席告诉我们说：没有调查，就没有发言权。软件开发也是如此，我们的软件是要为某一领域服务的，如果我们不了解这个领域，那么我们的所有软件开发方面的技巧，都有如神兵（神奇的兵器），没有高手使用，作用等同于废铜烂铁。所以，软件开发的第一步，是找到高手（领域专家）。第二步，和领域专家交流。问题来了，怎么经行有效的沟通？<br />	鸡同鸭讲，算有效的沟通吗？我觉得不算，答对了，嘿嘿。如果鸡鸭讲同一种语言，问题自然迎刃而解，我们把这种语言叫通用语言（Ubiquitous Language），这里我们简称为“鸟语”。鸟语的制定，大致情况应该是这样：鸡看着蚯蚓说鸭说：蚯蚓咯咯，i'm love in it;鸭说：我明白了，你们把这个动物叫蚯蚓咯咯，对吧？鸡：咯咯是语气助词；鸭：就是叫蚯蚓，对吧？鸡：对。和领域专家沟通，大致也是这样一个情况。<br />	我们的最终产品是软件，如果领域专家，软件开发人员，模型，软件，都讲同一种语言，那么，软件也一定是领域专家想要的样子。这里，反馈是非常重要的，通过反馈，可以确保通用语言的语义一致性。<br />	领域专家、软件开发人员是人，模型、软件是沟通方式。先说模型，模型是对现实世界的抽象和描述，也是交流的主要形式（如果领域专家能深入程序代码，并指出错误，那软件开发从业者，也该考虑改行了）。DDD的模型建立，是比较困难的，因为模型既要能够描述领域，又要能够映射到程序，而且还能和领域专家交流。为之奈何？？？圣人说过：软件的问题，无非是加个层的事。那么分层吧，也该没错。<br />	<br />用户界面/展现层     负责向用户展现信息以及解释用户命令。<br />应用层              很薄的一层，用来协调应用的活动。它不包含业务逻辑。它不保留业务对象的状态，但它保有应用任务的进度状态。<br />领域层              本层包含关于领域的信息。这是业务软件的核心所在。在这里保留业务对象的状态，对业务对象和它们状态的持久化被委托给了基础设施层。<br />基础设施层          本层作为其他层的支撑库存在。它提供了层间的通信，实现对业务对象的持久化，包含对用户界面层的支撑库等作用。<br /><br />	领域层的主导地位不言而喻，而我们建立领域层的方法是紧密关联领域建模和设计，于是，领域里的名词在模型中得到表现，一般表现为实体，为了防止实体泛滥，实体相关的名词，表现为值对象。实体和值对象是关联关系。领域里的动词，表现为实体方法。跨越多个实体的动词，表现为服务。当模型大到超出人脑一个线程能够处理的程度，应该分模块了，免得内存溢出（脑溢血？）。<br />	简单总是让人痴迷，易经就是最好的例子。那么，怎样保持模型的简单呢？高聚合，低耦合，永远是面向对象的最高追求，也是保持简单的不二法则。家长制是不错的办法，即所谓齐家，具体方法是：是一个家族（一个领域对象），其所以的族人，都由家长统一管理（生杀予夺），从外看，一个家族就如同一个人。用软件的术语，叫做聚合，定义是：是针对数据变化可以考虑成一个单元的一组相关的对象。<br />	有得必有失，我们的辩证唯物思想如是说。我们得到高聚合，低耦合，我们的代价是：实体可能变得比较重，比较复杂（不是所有的家族都是一家三口的小家庭）。怎么解决这个问题呢？工厂模式，这个大家最熟悉的设计模式，自认而然的浮现在了我们眼前，工厂很好的解决了实体的创建问题。如果好容易创建出来，用完就扔掉，那是败家子的作风，不是我们实事求是，勤俭节约、勤劳勇敢（此处省去1w赞美词）的程序员的作风。我们会把这些珍贵、昂贵的实体放入容器存起来，用的时候再拿出来（容器有大小，当然放的东西不能无限多，这就涉及到容器的具体策略）。勤俭节约、谦虚谨慎，是计算机也认同的道德标准。<br />	人非圣贤，当我们对领域不断深入，或者通过和领域专家交流，肯定会发现以前的理解有谬误，这时，无情的重构吧！重构是痛苦的，尤其在时间紧、任务急的情况下，但，生存还是死亡，这是个问题，而这个问题在中国，有标准答案的：好死不如赖活着。为了赖活的更好，重构的痛苦是可以接受的，痛并快乐着，诚如斯言。<br />	很久很久以前（大概石器时代到猛犸象灭绝），猎杀猛犸象，需要整个部落的人协同作战，各司其职。大型项目正如猛犸象，甚至比猛犸象更凶恶，更庞大，个人英雄主义在这里是没有市场的，我们需要多个团队协同作战，各司其职。各司其职，意味着将一个系统界定为多个模型，每个模型拥有独立的上下文，或者同一个模型里的分为多个模块，由不同的团队完成。并行的优点是效率高，适合团队开发，可缺点是难以保持统一的模型，如果引入持续集成，可以将混乱保持在一个可以容忍的范围，当然，这是技术层面上讲的。实际开发中，只有每个开发人员对整个系统有统一完整的认识，才能正本清源，避免不必要的混乱。如果有一个描述各个上下文之间的关系的文档，帮助大家理解系统，岂不美哉？这个文档，就叫上下文映射吧。上下文间的关系，无非共享内核、客户-供应商、顺从者、无关几种关系。<br />	如果所创建的新应用需要和遗留软件或者其他独立应用相交互，考虑到扩展性、可维护性，最好封装交互，加一个交互层（无非是加个层的事），这个层有个直观好听的名字：“防崩溃层”。当同一个防崩溃层被多个子系统需要时，应该考虑把这个层做成开放主机服务，DRY原则。<br />	矛盾分主次，系统内的各个模型也有主次之分，核心域当然需要重点照顾，其他的普通子域，可以考虑购买现成方案、外包、使用已有模型、锻炼新人等方式。<br />	推理完毕，打完收工。<br /><br />	说白了，DDD就是面向对象思想：高聚合、低耦合的扩展和升华，并在此基础上，定义了相应的开发过程。
          <br/><br/>
          <span style="color:red;">
            <a href="http://avidmouse.javaeye.com/blog/179788#comments" style="color:red;">已有 <strong>0</strong> 人发表留言，猛击-&gt;&gt;<strong>这里</strong>&lt;&lt;-参与讨论</a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 06 Apr 2008 08:48:11 +0800</pubDate>
        <link>http://avidmouse.javaeye.com/blog/179788</link>
        <guid>http://avidmouse.javaeye.com/blog/179788</guid>
      </item>
  </channel>
</rss>