精华内容
下载资源
问答
  • 五大领域的好处
    千次阅读
    2018-11-29 09:31:44

    项目是为完成某一独特的产品或服务所做的一次性努力。根 据这个定义,项目就具有了目标明确性、活动一次性及资源消耗性等特性。换句话说,具备前面三个主要特性的活动,都可以看作是项目。现实中的项目随处可见, 如设备消缺、会议组织、技术竞赛、结婚典礼以及家居装修等等,都可以看作是项目。在这些项目的实施过程中,都存在项目管理问题,不过,实际生活与工作中, 可能更多关注的事情本身,而对做好事情相关的组织、计划、控制等过程相对缺少关注,或者没有经验与能力加以关注。

      项目管理是在项目活动中运用知识、技能、工具和技术来实现项目要求。项目管理总体有五个过程:启动过程、计划过程、实施过程、执行过程、收尾过程等,包含了九大领域的知识:范围管理、时间管理、成本管理、质量管理、风险管理、人力资源管理、沟通管理、采购管理及系统管理的方法与工具。作为项目经理要全面掌握这些九个核心领域的知识,并重点把握系统管理的观念,避免进入某个细节,注意在五个不同阶段的重点。

     

      一、项目管理的三个约束条件

      任何项目都会在范围、时间及成本三个方面受到约束,这就是项目管理的三约束。项目管理,就是以科学的方法和工具,在范围、时间、成本三者之间寻找到一 个合适的平衡点,以便项目所有干系人都尽可能的满意。项目是一次性的,旨在产生独特的产品或服务,但不能孤立地看待和运行项目。这要求项目经理要用系统的 观念来对待项目,认清项目在更大的环境中所处的位置,这样在考虑项目范围、时间及成本时,就会有更为适当的协调原则。

      1.项目的范围约束

      项目的范围就是规定项目的任务是什么?作为项目经理,首先必须搞清楚项目的商业利润核心,明确把握项目发起人期望通过项目获得什么样的产品或服务。对于项目的范围约束,容易忽视项目的商业目标,而偏向技术目标,导致项目最终结果与项目干系人期望值之间的差异。

      因为项目的范围可能会随着项目的进展而发生变化,从而与时间和成本等约束条件之间产生冲突,因此面对项目的范围约束,主要是根据项目的商业利润核心做 好项目范围的变更管理。既要避免无原则的变更项目的范围,也要根据时间与成本的约束,在取得项目干系人的一致意见的情况下,合理的按程序变更项目的范围。

      2.项目的时间约束

      项目的时间约束就是规定项目需要多长时间完成,项目的进度应该怎样安排,项目的活动在时间上的要求,各活动在时间安排上的先后顺序。当进度与计划之间 发生差异时,如何重新调整项目的活动历时,以保证项目按期完成,或者通过调整项目的总体完成工期,以保证活动的时间与质量。

      在考虑时间约束时,一方面要研究因为项目范围的变化对项目时间的影响,另一方面要研究,因为项目历时的变化,对项目成本产生的影响。并及时跟踪项目的进展情况,通过对实际项目进展情况的分析,提供给项目干系人一个准确的报告。

      3.项目的成本约束

      项目的成本约束就是规定完成项目需要花多少钱。对项目成本的计量,一般用花费多少资金来衡量,但也可以根据项目的特点,采用特定的计量单位来表示。关 键是通过成本核算,能让项目干系人,了解在当前成本约束之下,所能完成的项目范围及时间要求。当项目的范围与时间发生变化时,会产生多大的成本变化,以决 定是否变更项目的范围,改变项目的进度,或者扩大项目的投资。

      在我们实际完成的许多项目中,多数只重视项目的进度,而不重视项目的成本管理。一般只是在项目结束时,才交给财务或计划管理部门的预算人员进行项目结 算。对内部消耗资源性的项目,往往不做项目的成本估算与分析,使得项目干系人根本认识不到项目所造成的资源浪费。因此,对内部开展的一些项目,也要进行成 本管理。

      由于项目是独特的,每个项目都具有很多不确定性的因素,项目资源使用之间存在竞争性,除了极小的项目,项目很难最终完全按照预期的范围、时间和成本三 大约束条件完成。因为项目干系人总是期望用最低的成本、最短的时间,来完成最大的项目范围。这三个期望之间是互相矛盾、互相制约的。项目范围的扩大,会导 致项目工期的延长或需要增加加班资源,会进一步导致项目成本的增加;同样,项目成本的减少,也会导致项目范围的限制。作为项目经理,就是要运用项目管理的 九大领域知识,在项目的五个过程组中,科学合理的分配各种资源,来尽可能的实现项目干系人的期望,使他们获得最大的满意度。

     

      二、项目管理的五个主要过程组

      一个项目的生命周期大概分成概念、开发、实施与收尾过程。在概念阶段主要是对成本进行分析,对项目的可行性进行研究,其结果是要拿出一份报告,并获得 批准与支持。实际工作中,我们只是有了一个新的想法与概念,就立即转入开发过程。在开发阶段,要有项目计划书、预算的成本以及工作分解计划。

      我们做事时,可能只是拿出一个简单的工作分解与大致的项目计划时间表,就结束了。在实施阶段,要有底层的工作包与确定的成本我们做事时,可能只是拿出 一个简单的工作分解与大致的项目计划时间表,就结束了。在实施阶段,要有底层的工作包与确定的成本估计,但我们没有,到了这一步,我们基本上就开始失去了 控制,没有明确的里程碑,我

      我们只是把一个阶段当成了一个项目。在收尾阶段,我们是经常讨论每个项目的教训,但对完成的工作的文档工作基本上没能及时跟上,同样与用户之间的交接也未能做好。

      项目管理的五个过程组:启动、计划、执行、控制与收尾,贯穿于项目的整个生命周期,对于项目的启动过程,特别要注意组织环境及项目干系人的分析;而在 后面的过程中,项目经理要抓好项目的控制,控制的理想结果就是在要求的时间、成本及质量限度内完成双方都满意的项目范围。

      1.项目的启动过程

      项目的启动过程就是一个新的项目识别与开始的过程。一定要认识这样一个概念,即在重要项目上的微小成功,比在不重要的项目上获得巨大成功更具意义与价 值。从这种意义上讲,项目的启动阶段显得尤其重要,这是决定是否投资,以及投资什么项目的关键阶段,此时的决策失误可能造成巨大的损失。重视项目启动过 程,是保证项目成功的首要步骤。

      启动涉及项目范围的知识领域,其输出结果有项目章程、任命项目经理、确定约束条件与假设条件等。启动过程的最主要内容是进行项目的可行性研究与分析, 这项活动要以商业目标为核心,而不是以技术为核心。无论是领导关注,还是项目宗旨,都应围绕明确的商业目标,以实现商业预期利润分析为重点,并要提供科学 合理的评价方法,以便未来能对其进行评估。

      2.项目的计划过程

      项目的计划过程是项目实施过程中非常重要的一个过程。通过对项目的范围、任务分解、资源分析等制定一个科学的计划,能使项目团队的工作有序的开展。也 因为有了计划,我们在实施过程中,才能有一个参照,并通过对计划的不断修订与完善,使后面的计划更符合实际,更能准确的指导项目工作。

      以前有一个错误的概念,认为计划应该准确,所谓准确,就是实际进展必须按计划来进行。实际并不是如此,计划是管理的一种手段,仅是通过这种方式,使项目的资源配置、时间分配更为科学合理而已,而计划在实际执行中是可以不断修改的。

      在项目的不同知识领域有不同的计划,应根据实际项目情况,编制不同的计划,其中项目计划、范围说明书、工作分解结构、活动清单、网络图、进度计划、资源计划、成本估计、质量计划、风险计划、沟通计划、采购计划等等,是项目计划过程常见的输出,应重点把握与运用。

      3.项目的实施过程

      项目的实施,一般指项目的主体内容执行过程,但实施包括项目的前期工作,因此不光要在具体实施过程中注意范围变更、记录项目信息,鼓励项目组成员努力完成项目,还要在开头与收尾过程中,强调实施的重点内容,如正式验收项目范围等。

      在项目实施中,重要的内容就是项目信息的沟通,即及时提交项目进展信息,以项目报告的方式定期通过项目进度,有利开展项目控制,对质量保证提供了手段。

      4.项目的控制过程

      项目管理的过程控制,是保证项目朝目标方向前进的重要过程,就是要及时发现偏差并采取纠正措施,使项目进展朝向目标方向。

      控制可以使实际进展符合计划,也可以修改计划使之更切合目前的现状。修改计划的前提是项目符合期望的目标。控制的重点有这么几个方面:范围变更、质量标准、状态报告及风险应对。基本上处理好以上四个方面的控制,项目的控制任务大体上就能完成了。

      5.项目的收尾过程

      一个项目通过一个正式而有效的收尾过程,不仅是对当前项目产生完整文档,对项目干系人的交待,更是以后项目工作的重要财富。在经历的很多项目中,更多重视项目的开始与过程,忽视了项目收尾工作,所以项目管理水平一直未能得到提高。

      另外要重视那一类未能实施成功的项目收尾工作,不成功项目的收尾工作比成功项目的收尾更难,也来得更重要,因为这样的项目的主要价值就是项目失败的教训,因此要通过收尾将这些教训提炼出来。

      项目收尾包括对最终产品进行验收,形成项目档案,吸取的教训等。另外,对项目干系人要做一个合理的安排,这也是容易忽视的地方,简单的打发回去不是最好的处理办法,更是对项目组成员的不负责任。

      项目收尾的形式,可以根据项目的大小自由决定,可以通过召开发布会、表彰会、公布绩效评估等手段来进行,形式是根据情况采用,但一定要明确,并能达到效果。如果能对项目进行收尾审计,则是再好不过的了,当然也有很多项目是无需审计的。

     

      三、项目管理的九大知识领域

      项目管理的九大知识领域是指作为项目经理必须具备与掌握的九大块重要知识与能力。其中核心的四大知识领域是范围、时间、成本与质量管理。在这些知识领 域中还涉及很多的管理工具和技术,以用来帮助项目经理与项目组成员完成项目的管理。如:网络图示法、关键路径法、头脑风暴法、挣值法等,不同的工具能帮助 我们完成不同的管理工作。另外,还有很多项目管理软件,如:MicrosoftProject、P3等,作为项目管理的工具,也可以很好的帮助我们解决在项目的各个过程中完成计划、跟踪、控制等管理过程。

      1.项目整体管理知识

      项目的整体管理,或者说是综合管理也不为错,它是综合运用其他八个领域的知识,合理集成与平衡各要素之间的关系,确保项目成功完成的关键。

      项目的整体管理包括三个主要过程:

      项目计划制定:即收集各种计划编制的结果,并形成统一协调项目计划文档。

      项目计划执行:通过执行项目计划的活动,来实施计划。

      整体变更控制:控制项目的变更。

      项目经理负责协调完成一个项目所需的人员、计划以及工作,统领全局,带领团队实现项目的目标;当项目目标之间或参与项目的人员之间出现冲突时,负责拍 板定夺;并负责及时向高层管理人员汇报项目进展信息。总而言之,项目经理主要负责项目的整体管理,这也是项目成功的关键。

      回顾以前负责的项目,觉得主要存在以下问题:

      未找到项目发起人,或者项目发起人不明确,常把自己当成项目发起人;

      项目交付成果定义不清,以致最后收尾时无法对照计划进行验收;

      缺少组织结构描述;

      对项目的控制未能规范化,尤其是项目范围的变更控制;

      风险管理未得到重视,只是在项目组内讨论,并停留在项目负责人的头脑中;

      缺乏项目干系人分析;

      没有规范的进度报告,项目进展报告随意性较大。

      要有效的开展项目管理,引用项目管理的知识体系与方法工具,先依样画葫芦,通过实践,进一步领会这些内容是必须的。

      2.项目范围管理知识

      项目范围的不确定,会导致项目范围的不断扩大,作为项目经理,在项目开始时,就要对项目范围拿出项目干系人都认可的、理解无歧意的范围说明文档——项目章程。然后为了保证项目的实施,明确项目组成员的工作责任,还必须分解项目范围,使之成为更小的项目任务包——工作分解结构(WBS)。

      最后还有就是要认识到项目本身不是孤立的,因此有时范围的变更也是必须的,关键是当变更发生时,如何加以控制。

      在以上讨论之前,最重要的是当面临项目时,或不知道具体做什么时,如何进行范围管理。对潜在项目的识别,有四个步骤:

      确定做一个什么样的项目;

      业务分析,找出重要的业务过程,分析其中最能从项目中得到好处的过程;

      形成项目可能的优势,确定范围、好处及约束;

      选择方案,分配资源。

      对于从多个项目中选择项目,或从多个方案中选择方案的情况,常见的四种方法:整体需要、分类、NPV及加权评分模型。

      3.项目的时间管理知识

      项目的时间管理,就是确保项目按期完成的过程。首先要制定项目的进度计划,然后是跟踪检查进度计划与实际完成情况之间的差异,及时调整资源、工作任务 等,以保证项目的进度实现。在跟踪过程中,要及时与项目干系人进行交流,以及时发现范围的偏差,而产生时间与进度上的差异,或项目组成员有意或无意识的虚 报了项目完成情况,导致进度的失控。

      具体包括以下内容:

      活动定义:从WBS分解而来;

      活动排序:明确活动之间的依赖关系;

      活动历时估算:估算每项活动的时间,可以PERT方法进行;

      利用PROJECT等工具软件,协助项目的时间管理;

      利用甘特图帮助跟踪项目进度;

      利用网络图及关键路径分析,协助确定完成日期上的重要性或调整工期对项目工期的影响,以及处理关注的焦点活动。

      需要注意一点,以前学习项目的时间管理工具及方法以后,就以为可以实现对项目的跟踪控制了,其实不然,这些工

      工具都是通过人来发生作用,活动也是由人来完成的,因此项目经理不能把太多心思花在工具上,而是学会利用工具来协调人与资源的矛盾冲突。

      4.项目的成本管理知识

      对于项目经理在成本管理方面,就是要努力减少和控制成本,满足项目干系人的期望。其过程包括:

      资源计划:即制定资源需求清单;

      成本估算:对所需资源进行成本估算;

      成本预算:将整体成本估算配置到各个单项工作,建立成本基准计划;

      成本控制:控制项目预算的变化,修正成本的估算,更新预算,纠正项目组成员的行动,进行完工估算与成本控制的分析。

      在成本管理中涉及很多财务管理的概念、术语、基础理论及方法与工具的使用,作为项目经理,对这些内容要熟悉,特别是挣值分析的相关术语及简称,如:BCWS、BCWP、ACWP、CV、SV、CPI、SPI等等,不光要了解这些术语的涵意,还要掌握他们的计算公式。

      5.项目人力资源管理知识

      项目的人力资源管理就是有效发挥每个参与项目的人员的作用的过程。项目的人力资源管理过程包括:

      组织计划编制:形成项目的组织结构图;

      获取相关人员:其中重点是业务相关人员;

      团队建设:明确每个项目干系人的责任,训练与提高其技能,实现团队的合作与沟通。

      因为与人发生关系,其中首先是要明确各自的责任,这一点计划编制时就要明确,可以通过项目管理软件帮助项目经理提高效率,并能及时发现任务分解的合理性,最后形成合理的任务分解表。

      同时,要通过有效的激励方法来帮助项目成员实施项目计划,提高效率。项目是通过团队共同努力实现的,注意充分发挥团队的作用,使团队成员各尽所能是项目经理的挑战。在处理过程中,争取做到对事不对人,通过有效的会议来帮助项目实现沟通、检查以及目标实现。

      6.项目的质量管理知识

      项目的质量,理解为项目满足客户明确或隐含的要求的一致性程度。注意这里包括明确的要求,也包括隐含的要求。这对IT项目来说,如何满足用户隐含的质量要求,可能是IT项目质量失败的重要原因。可能所开发的系统符合需求说明中的要求,却与用户实际的要求(包含隐含的需求中),相差很大,导致不一致,结果导致IT项目的失败。

      现代质量管理经过了一个发展过程,目前已建立起相对完善的质量体系,国际组织也有相关的质量文件,以评审普通的生产质量,如ISO2000系列质量标准;对软件的生产质量,也有一些评价模型,如SQFD模型、CMM软件成熟度模型等等。其中CMM成熟度模型分成五个层次:自发的、简单的、有组织的、被管理的及适应的,分别标识为不同的级别。

      对于项目管理需要制订质量计划,并应用质量保证的工具确保质量计划的实施。在质量控制的过程中,有许多现成的工具与方法,如帕累托分析、统计抽样和标 准差等。要提高项目的质量,必须在领导中形成质量意识,通过建立一个好的工作环境来提高质量,通过形成质量文化来改进质量,是全面提升项目质量管理的关键 因素之一。

      在以往所经历的项目中,项目的质量管理基本上没有得到重视,公司每年都在开展QC活动,该活动的目的就是改进质量,但活动成了科技创新活动,而更多的项目实施过程中,如何开展质量管理,却未能有所体现,这也是值得探讨的问题。

      7.项目的沟通管理知识

      项目的沟通管理非常重要,对项目经理而言,就如同前线指挥需要情报管理一样,这是使整个项目组掌握项目信息,实施其他管理手段的基础,所有的控制都有基于沟通基础之上的。

      在项目的开始,需要编制沟通计划,包括什么时间、将什么内容、以什么样的格式、通过什么样的方式、向谁传递。在项目的沟通中,可以采用书面报告、口头报告或非正式的交流,各种方式有利也有弊,关键看是否有利于沟通的效果。

      沟通的复杂程度随着对象的增加而快速增加,因此要通过适当的工具和手段,使面对面的沟通控制在一定范围之内,尽量减少因无效沟通而给项目管理带来的负责影响。

      在沟通中,会议是有效形式之一。很多业务员人员喜欢通过会议,以简单的形式化的语言描述项目的进展与项目中碰到的问题,而不喜欢技术化的图表与文档。

      8.项目的风险管理知识

      当因为未能做好风险管理,导致项目的风险发生时,项目干系人将难以一下子接受风险发生的事实以及风险所带来的损失,需要用更多的时间来调整

      整心理状态,才能恢复对项目的实施。

      项目的风险管理不仅是在项目进行过程中,有效避免风险的发生;而且能在风险发生时,帮助我们用正确的心态去面对,而不会手足无措。很多项目的失败,是 因为风险发生时,对项目干系心理上造成的伤害,导致失去主观判断能力,而作出错误的决策。从这种意义上讲,项目的风险计划的制定主要是为提高项目干系人的 风险意识,只要有了足够的风险意识,风险识别全面与否,在有些项目中可能重要性反而不是太明显。

      风险识别可以采用头脑风暴法、经验法则等方法,在识别这些风险因子之后,可以对这些因子加上权重,最后可以计算出项目成功的概率,并能据此决策项目是 否应该开展、继续或停止。识别风险因子之后,紧接着就是制定风险应对措施。根据风险发生的概率,产生的风险成本与收益,决定相应的应对策略,如风险处理、 风险接受、风险改善等等。

      实际工作中,可能识别到存在的风险,但却不能加以正确处理。风险就这样被层层传递。如因用户参与不够,导致需求不正确,进一步产生工期估计的失误,结果是计划的偏差,最后整个项目的结果产生偏差。因此,要注意从风险的源头抓起,防止风险的层层放大。

      9.项目的采购管理知识

      采购就是从外界获得产品或服务。对于IT项目而言,采购变得越来越重要。目前绝大多数的IT项目都离不开采购管理,而且很多项目的主要内容就是设备采购或咨询采购,对于企业而言,能否做好采购管理是保证项目成功的重点内容。

      有效采购管理包括以下过程:

      编制合理有效的采购计划:这是项目管理的一个重要过程,即确定项目的哪些需求可以通过采购得到更好的满足。在采购计划中,首先是决定是否需要采购、如何采购、采购什么、采购多少、何时采购等内容;

      编制询价计划:即编制报价邀请书RFQ或招标书;

      询价:进行实际询价;

      开标:评估并选择供应商;

      管理:对采购合同进行管理;

      收尾:对采购合同进行收尾。

      在整个过程中,容易忽视的两个过程,一是采购计划,二是合同收尾。采购计划的编制,是采购管理整体按需求进行的前提,如果这一步做不好,其他都是白费劲;而在采购的合同收尾过程中,最容易忘记或做不到的就是采购审计。至于供应商的选择等过程,在IT 项目中,往往会过分重视技术,而忽略管理与成本。其实,管理与成本决定合同能否按期保持履行的前提。在我公司的实际情况中,一般项目以设备为主要成本时, 往往就不再考虑其他内容,而仅是作为一般的设备采购,交会器材部门实施。因为不光没能做到项目管理,亦未做到采购管理,所以这类项目虽然也实施完成了,但 项目的实施质量总令人不太满意

    更多相关内容
  • 领域驱动设计DDD在战术建模上提供了一个元模型体系(如下图): 元模型往往用来在某一特定的领域定义一个基础的通用的语言,来讨论和描述该领域的问题及解决方法。可以将元模型想象成为某种形式语言,这样模型就是一...

    领域驱动设计DDD在战术建模上提供了一个元模型体系(如下图):

    在这里插入图片描述
    元模型往往用来在某一特定的领域定义一个基础的通用的语言,来讨论和描述该领域的问题及解决方法。可以将元模型想象成为某种形式语言,这样模型就是一篇用该语言描述的文章,其中元模型中的元素就是该语言的词汇,元素之间的关系就是该语言的语法。元模型的例子其实很多,例如交通指示标志就定义了一种非常简单的交通规则的元模型。DDD的元模型图也是用于描述如何去创建一个DDD的模型。

    DDD的战术阶段实际就是这样一个抽象过程。这个抽象过程由于元模型的存在实际是一定程度模式化的。这样的好处是并非只能技术人员参与建模,业务人员经过一定的培训也是完全可以理解的。

    DDD的战术建模包括如下内容:

    1. 实体-Entity
    2. 值对象-Value Objects
    3. 领域服务-Domain Services
    4. 领域事件-Domain Events
    5. 模块-Modules
    6. 聚合-Aggregate
    7. 资源库-Repository

    实体和值对象

    实体和值对象放在一起讲容易区分,概括而言,实体不仅需要知道它是什么?而且还需要知道它是哪个?而值对象只需要知道它是什么?先看定义:

    定义:

    • 实体:许多对象不是由它们的属性来定义,而是通过一系列的连续性(continuity)和标识(identity)来从根本上定义的。只要一个对象在生命周期中能够保持连续性,并且独立于它的属性(即使这些属性对系统用户非常重要),那它就是一个实体。
    • 值对象:当你只关心某个对象的属性时,该对象便可作为一个值对象。为其添加有意义的属性,并赋予它相应的行为。我们需要将值对象看成不变对象,不要给它任何身份标识,还应该尽量避免像实体对象一样的复杂性。

    对于实体Entity,实体核心是用唯一的标识符来定义,而不是通过属性来定义。即即使属性完全相同也可能是两个不同的对象。同时实体本身有状态的,实体又演进的生命周期,实体本身会体现出相关的业务行为,业务行为会实体属性或状态造成影响和改变。

    如果从值对象本身无状态,不可变,并且不分配具体的标识层面来看。那么值对象可以仅仅理解为实际的Entity对象的一个属性结合而已。该值对象附属在一个实际的实体对象上面。值对象本身不存在一个独立的生命周期,也一般不会产生独立的行为。

    初看还是很难理解,举几个例子:

    案例分析

    1. 营业厅会卖手机以及很多手机配件,在客户业务规则中,往往每一部手机都要单独管理,通过手机的SN号来识别。而手机配件是一种数量类型的实物,只关心其数量的变化,并不关心到每一个具体的手机配件。这种场景就是典型的实体和对象的案例。
    2. 地址是实体还是值对象。在电力公司服务软件中,一个地址对应于公司线路和服务的目的地。如果多个住所都申请了电力服务,那么这个公司需要知道这一点,因此地址是实体。我们也可以用另一种方法,在模型中将“住所”关联到运营服务,其中“住所”是一个包含地址属性的实体。此时,地址就是一个值对象。
    3. 体育场座位例子。当我们发放的门票上有座位号的时候,座位需要作为独立的实体,座位号是唯一的标识。而当先到先座模式下,我们只关心剩余座位数,那么座位号并不是唯一标识,这时候座位就可以作为一个值对象。这跟我们的业务需求有关。
      消息场景中,发件人、收件人是实体?还是值对象?这个在三个问题思考实体和值对象一文中有讨论。
    4. 值对象的常见例子包括数字,比如100和293.51;或者文本字符串,比如"hello world";或者日期时间;还有更加详细的对象,此如某人的全名,其中包含姓改、名字和头衔;再比如货币、颜色、电话号码和邮寄地址等。当然还有更加复杂的值对象。这种对象无状态,本身不产生行为,不存在生命周期演进。

    值对象的目的和使用

    实体对象相对容易理解,我们常见的类的都可以看成是实体对象。值对象在DDD中相对而言是难以理解并且容易误用的。

    为什么需要使用值对象,书中给了一个解释:

    使用不变的值对象使得我们做更少的职责假设

    个人理解这个还是基于BC的封闭性而言的,使用值对象在不同的BC中进行数据交换,可以避免不同BC对实体对象的状态变更而引发的数据依赖关系,实现最小化的集成。另外可以从目前流行的Stateless Service角度考虑值对象的价值。

    开发者因为习惯趋向于将关注点放在数据而不是领域上。在软件开发中,数据库依然占据着主导地位。我们首先考虑的是数据的属性(对应数据库的列)和关联关系(外键关联),而不是富有行为的领域概念。这样做的结果是将数据模型直接反映在对象模型上,导致产生贫血型的领域模型的实体。虽然在实体模型中加入getter和setter并不是什么大错,但这却不是DDD的做法。

    值类型用于度量和描述事物,DDD中建议应尽量使用值对象来建模而不是实体对象,因为值对象非常容易地对值对象进行创建、测试、使用、优化和维护。

    关于值对象,它拥有以下一些特征:

    1. 它度量或者描述了领城中的一件东西。
    2. 它可以作为不变量。
    3. 它将不同的相关的属性组合成一个概念整体(Conceptual Whole)
    4. 当度量和描述改变时,可以用另一个值对象予以替换。
    5. 它可以和其他值对象进行相等性比较。
    6. 它不会对协作对象造成副作用

    一个对象的方法可以设计成一个无副作用函数(Side-Effect-Free Function) 。这里的函数表示对某个对象的操作,它只用于产生输出, 而不会修改对象的状态。由于在函数执行的过程中没有状态改变,这样的函数操作也称为无副作用函数。对于不变的值对象而言,所有的方法都必须是无副作用函数,因为它们不能破坏值对象的不变性。

    最小化集成

    在所有的DDD项目中,通常存在多个限界上下文,这意味着我们需要找到合适的方法对这些上下文进行集成。当模型概念从上游上下文流入下游上下文中时, 尽量使用值对象来表示这些概念。这样的好处是可以达到最小化集成,即可以最小化下游模型中用于管理职责的属性数目。使用不变的值对象使得我们做更少的职责假设。

    领域服务

    领域中的服务表示一个无状态的操作,它用于实现特定于某个领域的任务。
    当某个揉作不适合放在聚合和值对象上时,最好的方式便是使用领域服务了。有时我们傾向于使用聚合根上的静态方法来实现这些这些操作,但是在 DDD中,这是一种坏味道。

    什么是领域服务(首先,什么不是领域服务)

    听到"服务"这个词时,我们自然地可能会想到一个分布式系统的远程调用场景。可能是一个SOA的服务,也有多种技术和方法可以实现SOA服务,例如远程过程调用(RPC)或者面向消息的中间件(MoM)。

    但这些都不是领域服务。

    另外也不要将领域服务与应用服务混杂在一起了。在应用服务中,我们并不会处理业务逻辑,但是领域服务却拾恰是处理业务逻辑的。简单来讲,应用服务是领域模型很自然的客户方,进而也是领域服务的客户方。

    虽然领域服务中有"服务"这个同,但它并不意昧着需要远程的、重量级的事务操作。

    领域模型中的服务是一种非常好的建模工具,现在我们已经知道领域服务不是什么了,那么它到底义是什么昵?

    有时,它不见得是一件东西……当领域中的某个操作过程或转换过程不是实体或值对象的职责时,此时我们便成该将该操作放在一个单独的接口中,即领域服务。请确保该领域服务和通用语言是一致的;并且保证它是无状态的。[Evans, pp. 104,106]

    那么在什么情况下,某个操作不属于实体或者值对象呢?书中罗列了以下几点:

    • 执行一个显著的业务操作过程。
    • 对领域对象进行转换。
    • 以多个领域对象作为输入进行计算,结果产生一个值对象。

    对于最后一点中的计算过程,它应该具有“显著的业务操作过程"的特点。这也是领域服务很常见的应用场景,它可能需要多个聚合作为输人。 当一个方法不便放在实体或值对象上时,使用领域服务便是最佳的解决方法。需要确保领域服务是无状态的,并且能够明确地表达限界上下文中的通用语言

    不过只要在真正必要是才应该使用领域服务,过度使用领域服务将会导致贫血领域模型,所有业务都位于领域服务中,而不是实体和值对象中了。

    用户权限认证的例子

    《实现领域驱动设计》书中给出了一个例子,对User进行认证的例子。例子中给出的需求是:

    • 系统必须对User进行认证,并且只有当Tenant处于激活状态时候才能对User进行认证。
    • 必须对密码进行加密,并且不能使用明文密码

    对以上的需求,我们可以把认证的方法写在User类或者Tenant类中,不过对于以上解决方案,似乎都给模型带来了太多的问题。对于后一种方案, 我们必须从以下回种解决办法中选择一种:

    1. 在Tenant中处理对密码的加密,然后将加密后的密码传给User。这种方法违背了单一职责原则
    2. 由于一个User必须保征对密码的加密,它可能已经知道了一些加密信息。如果是这样,我们可以在User上创建一个方法,该方法对明文密码进行认证。但是在这种方式下,认证过程变成了Tenant上的Facade。而实际的认证 功能全在User上。另外User上的认证方法必须声明为Protected,以防止外界 客户端对认证方法的直接调用。
    3. Tenant依赖于User对密码进行加密,然后将加密后的密码与原有密码进行匹配。这种方法似乎在对象协作之间增加了额外的步骤。此时,Tenant依然需 要知道认证细节。
    4. 让客户端对密码进行加密。然后将其传给Tenant,这样导致的问题在于客户端承载了它本不应该有的职责。

    以上这些方法都有问题,这时候选择通过领域服务会是一个简单而优雅的选择。

    UserDescriptor userDescriptor = 
              DomainRegistry
                .authenticationService()
                .authenticate(tenantID,userName,password);
    

    为领域服务创建一个迷你层

    一个方法是放入领域对象还是放入领域服务有时候会是一个比较困难的选择。我们可能希望在实体和值对象之上创建一个领域服务的迷你层,这样简化了分析的工作,但这样做可能会导致贫血领域模型这种反模式。

    对于有些系统来说,为领域服务创建一个不至于导致贫血领域模型的迷你层还是值得的。当然这取决于领城模型的特征。对于上面提到的身份与访问上下文来说,这样的做法是非常有用的。

    如果你决定为领域服务创建一个迷你层,需要注意这样的迷你层和应用层中的服务是不同的。在应用服务中,我们关心的是事务和安全,但是这些不应该出现在领域服务中。

    领域事件

    参考 DDD 领域驱动设计学习笔记(三)- 领域事件

    模块

    模块在技术上可以对应Java中的Package。在DDD中,模块表示了一个命名的容器,用于存放领域中内聚在一起的类。

    模块应该包含一組具有高内聚性的概念集合.这样做的好处是可以在不同的模块之间实现松耦合。否则,我们应该修改模型以重新划分这些概念。……由于模块名是UL的一部分,模块名应该反映出它们在领域中的概念。[Evans]

    模块的设计是基于领域模型的,要符合通用语言的表述。其次,模块的设计要符合高内聚低耦合的设计思想。设计模块时候,有几条简单原则如下:

    在这里插入图片描述

    模块和BC的关系

    模块与子域和限界上下文并不是一致的概念,模块也是一种独立的建模方法。对于何时应该对领域模型进行分离,何时将领域模型建模成一个整体,应该仔细地思考与对待。有时通用语言可以很好地帮助我们做出正确的选择。但是另外的时候,其中的术语将变得非常含糊。在这种情况下,我们并不清楚如何划分上下文边界。此时,我们可以首先将它们放在一起,使用模块来对模型进行划分,面不是限界上下文。

    但是,这并不意味着我们就应该限制对限界上下文的创建。我们应该通过通用语言的需求来划分模型边界。但限界上下文不是用来代替模块的。使用摸块的目的在于组织那些内聚在一起的领域对象,对于那些内聚性不强或者没有内聚性的领域对象来说,我们应该将它们划分在不同的模块中。

    参考
    DDD战术篇:领域模型的应用
    DDD理论学习系列(6)-- 实体
    DDD理论学习系列(13)-- 模块

    作者:njluz
    链接:https://www.jianshu.com/p/da51d16dbdc4
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    展开全文
  • 质量管理五大工具、七大手法知识点总结

    万次阅读 多人点赞 2018-11-13 17:03:22
    干货 | 质量管理五大工具、七大手法知识点总结,非常全面! 2017-09-21 17:01 来源:增城质监 ...

    干货 | 质量管理五大工具、七大手法知识点总结,非常全面!

    原标题:干货 | 质量管理五大工具、七大手法知识点总结,非常全面!

    质量管理五大工具、七大手法知识点总结,非常全面!

    五大工具

    APQP

    APQP(Advanced Product Quality Planning)即产品质量先期策划,是一种结构化的方法,用来确定和制定确保某产品使顾客满意所需的步骤。

    产品质量策划的目标是促进与所涉及的每一个人的联系,以确保所要求的步骤按时完成。有效的产品质量策划依赖于公司高层管理者对努力达到使顾客满意这一宗旨的承诺。

    产品质量策划有如下的益处:

    引导资源,使顾客满意;

    促进对所需更改的早期识别;

    避免晚期更改;

    以最低的成本及时提供优质产品。

    FMEA

    FMEA(Potential Failure Mode and Effects Analysis)即潜在的失效模式及后果分析,是在产品/过程/服务等的策划设计阶段,对构成产品的各子系统、零部件,对构成过程,服务的各个程序逐一进行分析,找出潜在的失效模式,分析其可能的后果,评估其风险,从而预先采取措施,减少失效模式的严重程序,降低其可能发生的概率,以有效地提高质量与可靠性,确保顾客满意的系统化活动。

    FMEA种类:

    按其应用领域常见FMEA有设计FMEA(DFMEA)和过程FMEA(PFMEA),其它还有系统FMEA,应用FMEA,采购FMEA,服务FMEA。

    MSA

    MSA(Measurement System Analysis)即MSA测量系统分析,它使用数理统计和图表的方法对测量系统的误差进行分析,以评估测量系统对于被测量的参数来说是否合适,并确定测量系统误差的主要成份。

    PPAP

    PPAP(Production part approval process) 即生产件批准程序 ,是对生产件的控制程序,也是对质量的一种管理方法。

    PPAP生产件提交保证书:主要有生产件尺寸检验报告、外观检验报告、功能检验报告,、材料检验报告、外加一些零件控制方法和供应商控制方法;

    制造型企业要求供应商在提交产品时做PPAP文件及首件,只有当PPAP文件全部合格后才能提交;当工程变更后还须提交报告。

    SPC

    SPC(Statistical Process Control)即统计过程控制,主要是指应用统计分析技术对生产过程进行适时监控,科学区分出生产过程中产品质量的随机波动与异常波动,从而对生产过程的异常趋势提出预警,以便生产管理人员及时采取措施,消除异常,恢复过程的稳定从而达到提高和控制质量的目的。

    SPC非常适用于重复性的生产过程,它能够帮助组织对过程作出可靠的评估,确定过程的统计控制界限判断过程是否失控和过程是否有能力;为过程提供一个早期报警系统,及时监控过程的情况,以防止废品的产生,减少对常规检验的依赖性,定时以观察以及系统的测量方法替代大量检测和验证工作。

    SPC实施意义:

    可以使企业:降低成本;降低不良率,减少返工和浪费;提高劳动生产率;提供核心竞争力;赢得广泛客户。

    实施SPC两个阶段 :

    分析阶段:运用控制图、直方图、过程能力分析等使过程处于统计稳态,使过程能力足够。

    监控阶段:运用控制图等监控过程 。

    SPC的产生:

    工业革命以后,随着生产力的进一步发展,大规模生产的形成,如何控制大批量产品质量成为一个突出问题,单纯依靠事后检验的质量控制方法已不能适应当时经济发展的要求,必须改进质量管理方式。于是,英、美等国开始着手研究用统计方法代替事后检验的质量控制方法。

    1924年,美国的休哈特博士提出将3Sigma原理运用于生产过程当中,并发表了著名的“控制图法”,对过程变量进行控制,为统计质量管理奠定了理论和方法基础。

    SPC的作用:

    ① 确保制程持续稳定、可预测。

    ② 提高产品质量、生产能力、降低成本。

    ③ 为制程分析提供依据。

    ④ 区分变差的特殊原因和普通原因,作为采取局部措施或对系统采取措施的指南。

    七大手法

    检查表

    检查表就是将需要检查的内容或项目一一列出,然后定期或不定期的逐项检查,并将问题点记录下来的方法,有时叫做查检表或点检表。 例如:点检表、诊断表、工作改善检查表、满意度调查表、考核表、审核表、5S活动检查表、工程异常分析表等。

    组成要素 :

    ① 确定检查的项目;

    ② 确定检查的频度;

    ③ 确定检查的人员。

    实施步骤 :

    ① 确定检查对象;

    ② 制定检查表;

    ③ 依检查表项目进行检查并记录;

    ④ 对检查出的问题要求责任单位及时改善;

    ⑤ 检查人员在规定的时间内对改善效果进行确认;

    ⑥ 定期总结,持续改进。

    层别法

    层别法就是将大量有关某一特定主题的观点、意见或想法按组分类,将收集到的大量的数据或资料按相互关系进行分组,加以层别。层别法一般和柏拉图、直方图等其它七大手法结合使用,也可单独使用。例如:抽样统计表、不良类别统计表、排行榜等。

    实施步骤:

    ① 确定研究的主题;

    ② 制作表格并收集数据;

    ③ 将收集的数据进行层别;

    ④ 比较分析,对这些数据进行分析,找出其内在的原因,确定改善项目。

    柏拉图

    柏拉图的使用要以层别法为前提,将层别法已确定的项目从大到小进行排列,再加上累积值的图形。它可以帮助我们找出关键的问题,抓住重要的少数及有用的多数,适用于记数值统计,有人称为ABC图,又因为柏拉图的排序识从大到小,故又称为排列图。

    分类 :

    ① 分析现象用柏拉图:与不良结果有关,用来发现主要问题。

    A 品质:不合格、故障、顾客抱怨、退货、维修等;

    B 成本:损失总数、费用等;

    C 交货期:存货短缺、付款违约、交货期拖延等;

    D 安全:发生事故、出现差错等。

    ② 分析原因用柏拉图:与过程因素有关,用来发现主要问题。

    A 操作者:班次、组别、年龄、经验、熟练情况等; B 机器:设备、工具、模具、仪器等;

    C 原材料:制造商、工厂、批次、种类等;

    D 作业方法:作业环境、工序先后、作业安排等。

    柏拉图的作用:

    ① 降低不良的依据;

    ② 决定改善目标,找出问题点;

    ③ 可以确认改善的效果。

    实施步骤:

    ① 收集数据,用层别法分类,计算各层别项目占整体项目的百分数;

    ② 把分好类的数据进行汇总,由多到少进行排列,并计算累计百分数;

    ③ 绘制横轴和纵轴刻度;

    ④ 绘制柱状图;

    ⑤ 绘制累积曲线;

    ⑥ 记录必要事项

    ⑦ 分析柏拉图

    ⑧ 要点:

    A 柏拉图有两个纵坐标,左侧纵坐标一般表示数量或金额,右侧纵坐标一般表示数量或金额的累积百分数;

    B 柏拉图的横坐标一般表示检查项目,按影响程度大小,从左到右依次排列;

    C 绘制柏拉图时,按各项目数量或金额出现的频数,对应左侧纵坐标画出直方形,将各项目出现的累计频率,对应右侧纵坐标描出点子,并将这些点子按顺序连接成线。

    应用要点及注意事项:

    ① 柏拉图要留存,把改善前与改善后的柏拉图排在一起,可以评估出改善效果;

    ② 分析柏拉图只要抓住前面的2~3项九可以了;

    ③ 柏拉图的分类项目不要定得太少,5~9项教合适,如果分类项目太多,超过9项,可划入其它,如果分类项目太少,少于4项,做柏拉图无实际意义;

    ④ 作成的柏拉图如果发现各项目分配比例差不多时,柏拉图就失去意义,与柏拉图法则不符,应从其它角度收集数据再作分析;

    ⑤ Y 柏拉图是管理改善的手段而非目的,如果数据项别已经清楚者,则无需浪费时间制作柏拉图;

    ⑥ 其它项目如果大于前面几项,则必须加以分析层别,检讨其中是否有原因;

    ⑦ 柏拉图分析主要目的是从获得情报显示问题重点而采取对策,但如果第一位的项目依靠现有条件很难解决时,或者即使解决但花费很大,得不偿失,那么可以避开第一位项目,而从第二位项目着手。

    因果图

    所谓因果图,又称特性要因图,主要用于分析品质特性与影响品质特性的可能原因之间的因果关系,通过把握现状、分析原因、寻找措施来促进问题的解决,是一种用于分析品质特性(结果)与可能影响特性的因素(原因)的一种工具。又称为鱼骨图。

    分类:

    ① 追求原因型:在于追求问题的原因,并寻找其影响,以因果图表示结果(特性)与原因(要因)间的关系;

    ② 追求对策型:追求问题点如何防止、目标如何达成,并以因果图表示期望效果与对策的关系。

    实施步骤:

    ① 成立因果图分析小组,3~6人为好,最好是各部门的代表;

    ② 确定问题点;

    ③ 画出干线主骨、中骨、小骨及确定重大原因(一般从5M1E即人Man、机Machine、料Material、法Method、测Measure、环Environment六个方面全面找出原因);

    ④ 与会人员热烈讨论,依据重大原因进行分析,找到中原因或小原因,绘至因果图中;

    ⑤ 因果图小组要形成共识,把最可能是问题根源的项目用红笔或特殊记号标识;

    ⑥ 记入必要事项

    应用要点及注意事项:

    ① 确定原因要集合全员的知识与经验,集思广益,以免疏漏;

    ② 原因解析愈细愈好,愈细则更能找出关键原因或解决问题的方法;

    ③ 有多少品质特性,就要绘制多少张因果图;

    ④ 如果分析出来的原因不能采取措施,说明问题还没有得到解决,要想改进有效果,原因必须要细分,直到能采取措施为止;

    ⑤ 在数据的基础上客观地评价每个因素的主要性;

    ⑥ 把重点放在解决问题上,并依5W2H的方法逐项列出,绘制因果图时,重点先放在“为什么会发生这种原因、结果”,分析后要提出对策时则放在“如何才能解决”;

    Why——为何要做?(对象)

    What——做什么?(目的)

    Where——在哪里做?(场所)

    When——什么时候做?(顺序)

    Who——谁来做?(人)

    How——用什么方法做?(手段)

    How much——花费多少?(费用)

    ⑦ 因果图应以现场所发生的问题来考虑;

    ⑧ 因果图绘制后,要形成共识再决定要因,并用红笔或特殊记号标出;

    ⑨ 因果图使用时要不断加以改进。

    散布图

    将因果关系所对应变化的数据分别描绘在X-Y轴坐标系上,以掌握两个变量之间是否相关及相关的程度如何,这种图形叫做“散布图”,也称为“相关图”。

    分类:

    ① 正相关:当变量X增大时,另一个变量Y也增大;

    ② 负相关:当变量X增大时,另一个变量Y却减小;

    ③ 不相关:变量X(或Y)变化时,另一个变量并不改变;

    ④ 曲线相关:变量X开始增大时,Y也随着增大,但达到某一值后,则当X值增大时,Y反而减小。;

    实施步骤:

    ① 确定要调查的两个变量,收集相关的最新数据,至少30组以上;

    ② 找出两个变量的最大值与最小值,将两个变量描入X轴与Y轴;

    ③ 将相应的两个变量,以点的形式标上坐标系;

    ④ 计入图名、制作者、制作时间等项目;

    ⑤ 判读散布图的相关性与相关程度。

    应用要点及注意事项:

    ① 两组变量的对应数至少在30组以上,最好50组至100组,数据太少时,容易造成误判;

    ② 通常横坐标用来表示原因或自变量,纵坐标表示效果或因变量;

    ③ 由于数据的获得常常因为5M1E的变化,导致数据的相关性受到影响,在这种情况下需要对数据获得的条件进行层别,否则散布图不能真实地反映两个变量之间的关系;

    ④ 当有异常点出现时,应立即查找原因,而不能把异常点删除;

    ⑤ 当散布图的相关性与技术经验不符时,应进一步检讨是否有什么原因造成假象。

    直方图

    直方图是针对某产品或过程的特性值,利用常态分布(也叫正态分布)的原理,把50个以上的数据进行分组,并算出每组出现的次数,再用类似的直方图形描绘在横轴上。

    实施步骤 :

    ① 收集同一类型的数据;

    ② 计算极差(全距)R=Xmax-Xmin;

    ③ 设定组数K:K=1+3.23logN

    ④ 确定测量最小单位,即小数位数为n时,最小单位为10-n;

    ⑤ 计算组距h,组距h=极差R/组数K;

    ⑥ 求出各组的上、下限值

    第一组下限值=X min-测量最小单位10-n/27

    第二组下限值(第一组上限值)=第一组下限值+组距h;

    ⑦ 计算各组的中心值,组中心值=(组下限值+组上限值)/2;

    ⑧ 制作频数表;

    ⑨ 按频数表画出直方图。

    直方图的常见形态与判定:

    ① 正常型:是正态分布,服从统计规律,过程正常;

    ② 缺齿型:不是正态分布,不服从统计规律;

    ③ 偏态型:不是正态分布,不服从统计规律;

    ④ 离岛型:不是正态分布,不服从统计规律;

    ⑤ 高原型:不是正态分布,不服从统计规律;

    ⑥ 双峰型:不是正态分布,不服从统计规律;

    ⑦ 不规则型:不是正态分布,不服从统计规律。

    控制图

    影响产品质量的因素很多,有静态因素也有动态因素,有没有一种方法能够即时监控产品的生产过程、及时发现质量隐患,以便改善生产过程,减少废品和次品的产出?

    控制图法就是这样一种以预防为主的质量控制方法,它利用现场收集到的质量特征值,绘制成控制图,通过观察图形来判断产品的生产过程的质量状况。控制图可以提供很多有用的信息,是质量管理的重要方法之一。

    控制图法的涵义:

    控制图又叫管理图,它是一种带控制界限的质量管理图表。运用控制图的目的之一就是,通过观察控制图上产品质量特性值的分布状况,分析和判断生产过程是否发生 了异常,一旦发现异常就要及时采取必要的措施加以消除,使生产过程恢复稳定状态。也可以应用控制图来使生产过程达到统计控制的状态。产品质量特性值的分布 是一种统计分布,因此,绘制控制图需要应用概率论的相关理论和知识。

    控制图是对生产过程质量的一种记录图形,图上有中心线和上下控制限,并有反映按时间顺序抽取的各样本统计量的数值点。中心线是所控制的统计量的平均值,上下控制限与中心线相距数倍标准差。多数的制造业应用三倍标准差控制限,如果有充分的证据也可以使用其它控制限。

    常用的控制图有计量值和记数值两大类,它们分别适用于不同的生产过程;每类又可细分为具体的控制图,如计量值控制图可具体分为均值——极差控制图、单值一移动极差控制图等。

    控制图的绘制:

    ① 控制图的基本式样如图所示,制作控制图一般要经过以下几个步骤:

    A 按规定的抽样间隔和样本大小抽取样本;

    B 测量样本的质量特性值,计算其统计量数值;

    C 在控制图上描点;

    D 判断生产过程是否有并行。

    ② 控制图为管理者提供了许多有用的生产过程信息时应注意以下几个问题:

    A 根据工序的质量情况,合理地选择管理点。管理点一般是指关键部位、关健尺寸、工艺本身有特殊要求、对下工存有影响的关键点,如可以选质量不稳定、出现不良品较多的部位为管理点;

    B 根据管理点上的质量问题,合理选择控制图的种类:

    C 使用控制图做工序管理时,应首先确定合理的控制界限

    D 控制图上的点有异常状态,应立即找出原因,采取措施后再进行生产,这是控制图发挥作用的首要前提;

    E 控制线不等于公差线,公差线是用来判断产品是否合格的,而控制线是用来判断工序质量是否发生变化的;

    F 控制图发生异常,要明确责任,及时解决或上报。

    现场抽样法:

    制作控制图时并不是每一次都计算控制限,那么最初控制线是怎样确定的呢?如果现在的生产条件和过去的差不多,可以遵循以往的经验数据,即延用以往稳定生产的控制限。下面介绍一种确定控制限的方法,即现场抽样法。

    其步骤如下:

    ① 随机抽取样品50件以上,测出样品的数据,计算控制界限,做控制图;

    ② 观察控制图是否在控制状态中,即稳定情况,如果点全部在控制界限内.而且点的排列无异常,则可以转入下一步;

    ③ 如果有异常状态,或虽未超出控制界限,但排列有异常,则需查明导致异常的原因,并采取妥善措施使之处在控制状态,然后再重新取数据计算控制界限,转入下一步;

    ④ 把上述所取数据作立方图,将立方图和标准界限(公差上限和下限)相比较,看是否在理想状态和较理想状态,如果达不到要求,就必须采取措施,使平均位移动或标准偏差减少,采取措施以后再重复上述步骤重新取数据,做控制界限,直到满足标准为止。

    怎样利用控制图判断异常现象:

    用控制图识 别生产过程的状态,主要是根据样本数据形成的样本点位置以及变化趋势进行分析和判断。

    失控状态主要表现为以下两种情况:

    样本点超出控制界限

    样本点在控制界限内,但排列异常。

    当数据点超越管理界限时,一般认为生产过程存在异常现象,此时就应该追究原因,并采取对策。排列异常主要指出现以下几种情况:

    A 连续七个以上的点全部偏离中心线上方或下方,这时应查看生产条件是否出现了变化。

    B 连续三个点中的两个点进入管理界限的附近区域(指从中心线开始到管理 界限的三分之二以上的区域),这时应注意生产的波动度是否过大。

    C 点相继出现向上或向下的趋势,表明工序特性在向上或向下发生着变化。

    D 点的排列状态呈周期性变化,这时可对作业时间进行层次处理,重新制作控制图,以便找出问题的原因。

    控制图对异常现象的揭示能力,将根据数据分组时各组数据的多少、样本的收集方法、层别的划分不同而不同。不应仅仅满足于对一份控制图的使用,而应变换各种各样的数据收取方法和使用方法,制作出各种类型的图表,这样才能收到更好的效果。

    值得注意的是:如果发现了超越管理界限的异常现象,却不去努力追究原因、采取对策,那么尽管控制图的效用很好,也只不过是空纸一张。

    文章引用: https://www.sohu.com/a/131162008_650366
    展开全文
  • DDD领域驱动设计详解

    万次阅读 多人点赞 2021-06-04 16:32:17
    DDD领域驱动设计1. 领域驱动设计1.1 什么是领域驱动设计1.2 为什么用领域驱动设计2. DDD核心知识体系2.1 DDD核心概念2.2 DDD战略战术设计2.2.1 DDD战略设计2.2.1 DDD战术设计3. DDD微服务架构模型3.1 基本架构3.1.1 ...

    1. 领域驱动概述

    1.1 领域驱动简介

    领域驱动设计是Eric Evans在2004年发表的Domain Driven Design(领域驱动设计,DDD)著作中提出的一种从系统分析到软件建模的一套方法论。以领域为核心驱动力的设计体系。

    从领域驱动定义来看,领域驱动设计-软件核心复杂性应对之道,从Eric 定义中可以看出,领域驱动设计是为了解决复杂的软件设计,而且只是解决软件复杂性的一种方式,并不是唯一选择。另外不是所有的业务服务都合适做DDD架构,DDD适合产品化,可持续迭代,业务逻辑足够复杂的业务系统,对于系统初期业务逻辑相对比较简单的应用,传统MVC架构更具有优势,可以减少一部分认知成本与开发成本。而且领域驱动设计并不是万金油,只是解决复杂软件的一种方案,领域驱动设计本身只提供了理论思想,具体的落地方案一定是结合具体的业务场景实现的。目前市面上也有很多依据领域驱动思想落地的开源框架可以参考。

    从领域驱动对应关系来看,一方面目前很多建设中台的时候大多采用DDD思想落地,DDD很多思想比如领域划分,领域事件,领域服务,边界上下文划分,充血模型,代码防腐,统一语义等等可以很好的帮助实现中台的落地,但是中台落地DDD并不是唯一选择。另一方面对于DDD的这些思想,与DDD的关系更多是聚合关系,而不是组合关系,也就是在具体应用开发中,即使采用传统的MVC架构,这些思想依然可以很好的发挥其作用。

    1.2 领域驱动优点

    DDD最大的好处是:接触到需求第一步就是考虑领域模型,而不是将其切割成数据和行为,然后数据用数据库实现,行为使用服务实现,最后造成需求的首肢分离。DDD让你首先考虑的是业务语言,而不是数据。DDD强调业务抽象和面向对象编程,而不是过程式业务逻辑实现。重点不同导致编程世界观不同。

    1.面向对象设计,数据行为绑定,告别贫血模型。
    2.优先考虑领域模型,而不是切割数据和行为。
    3.业务语义显性化,准确传达业务规则。
    4.代码即设计,通过领域设计即可很清晰的实现代码。
    5.它通过边界划分将复杂业务领域简单化,帮我们设计出清晰的领域和应用边界,可以很容易地实现业务和技术统一的架构演进。

    领域驱动设计,又称"软件核心复杂性应对之道"。是一套基于对象思维的业务建模设计思想,相对于 CRUD 系统有更高的灵活性,是业务人员处理复杂问题的有效手段。

    通用语言:“一个团队,一种语言”,将模型作为语言的支柱。确保团队在内部的所有交流中,代码中,画图,写东西,特别是讲话的时候都要使用这种语言。例如账号,转账,透支策略,这些都是非常重要的领域概念,如果这些命名都和我们日常讨论以及PRD中的描述保持一致,将会极大提升代码的可读性,减少认知成本。说到这,稍微吐槽一下我们有些工程师的英语水平,有些神翻译让一些核心领域概念变得面目全非。
    显性化:就是将隐式的业务逻辑从一推if-else里面抽取出来,用通用语言去命名、去写代码、去扩展,让其变成显示概念,比如"透支策略"这个重要的业务概念,按照事务脚本的写法,其含义完全淹没在代码逻辑中没有突显出来,看代码的人自然也是一脸懵逼,而领域模型里面将其用策略模式抽象出来,不仅提高了代码的可读性,可扩展性也好了很多。

    在这里插入图片描述

    1.3 领域驱动解决复杂度方式

    首先, 典型的DDD实现了业务复杂度和技术复杂度的隔离,通过分层架构隔离了关注点,举个例子,在传统的DDD四层架构中,DDD划分出了领域层、仓储层、基础设施层、接口层;

    在领域层中,存放业务逻辑的关注点,即所谓的领域行为;在应用层中,DDD暴露出了 业务用例级别 (Use Case)的服务接口,粘合业务逻辑与技术实现;在基础设施层中,DDD集中放置了支撑业务逻辑的技术实现,如:MQ消息发送、对缓存的操作等;在仓储层中,DDD放置了和领域状态相关的逻辑,打通了领域状态持久化与存储设施之间的联系。

    除了划分不同分层外,DDD还提出了一个建设性的概念: “限界上下文(Bounded Context)”,通过限界上下文对业务流程分而治之,切分为不同的子系统,在每个子系统中利用DDD的分层架构/六边形架构等思想分别进行逻辑分层。通过这样的分治之后,DDD帮我们将业务复杂度隔离到了每个细分的领域内部,而且DDD本身的分治思想,也帮助我们隔离了业务需求和技术需求的关注点。
    在这里插入图片描述这是一个典型的领域驱动设计分层架构,蓝色区域的内容与业务逻辑有关,而灰色区域的内容则与技术实现有关。这二者泾渭分明,最后汇合在应用层。
    应用层确定了业务逻辑与技术实现的边界,通过直接依赖或者依赖注入(DI,Dependency Injection)的方式将二者结合起来。充分体现了DDD能够隔离技术复杂度与业务复杂度的特点。

    1.4 领域驱动疑问

    对于领域驱动设计与传统架构设计,不同的人有不同的见解,也可以理解,这里梳理领域驱动设计也不是认为传统架构有什么问题,具体采用什么样的架构设计一定是根据现有架构并结合当前实际的业务场景所决定的,任何撇开业务场景谈架构都是耍流氓,就像撇开剂量谈药性一样荒诞。

    其次,领域驱动设计全称叫领域驱动设计软件核心复杂性应对之道,是为了更好的解决复杂软件的架构设计,但是这并不意味着领域驱动设计就是万金油,可以解决所有的问题。面对复杂的业务也会存在复杂的聚合,也会存在性能问题,也需要做幂等,也需要高可用,高性能,高并发等等,会与传统架构一样存在这些问题,不同的架构设计工具解决不同的问题,与领域驱动也并不冲突。

    不管是领域驱动设计还是传统三层架构都是面向对象设计,很多地方认为传统是面向数据,面向过程,数据也是对象,过程也是对象,只不过领域驱动更加贴合业务,以业务为核心展开的设计开发,对于聚合问题,业务的复杂必然带来聚合复杂,也是正常现象,不是说使用了DDD就变得不复杂了,对于性能问题,与DDD完全两个概念,领域驱动解决的是软件核心复杂性应对之道,是为了更好的应对复杂业务,使技术实现与业务更好的分离,使外部调用与内部系统相隔离,采用充血,聚合,代码防腐,领域事件,领域服务。对于性能的问题采用相应性能对应的技术手段去解决,而不应该把问题归咎于领域驱动设计。

    2. 领域驱动核心知识

    2.1 领域知识概念

    DDD的核心知识体系主要包括领域、子域、核心域、支撑域、通用域、限界上下文、实体、值对象、聚合、聚合根等概念。
    在这里插入图片描述

    2.2 领域战略战术设计

    DDD有战略设计和战术设计之分。战略设计主要从高层"俯视"我们的软件系统,帮助我们精准地划分领域以及处理各个领域之间的关系;而战术设计则从技术实现的层面教会我们如何具体地实施DDD。

    战略建模-Strategic Modeling
    限界上下文(Bounded Context)
    上下文映射图(Context Mapping)

    战术建模-Tactical Modeling:
    聚合-Aggregate
    实体-Entity
    值对象-Value Objects
    资源库-Repository
    领域服务-Domain Services
    领域事件-Domain Events
    模块-Modules

    在这里插入图片描述在这里插入图片描述

    3. 领域驱动战略设计

    3.1 战略设计概述

    需要指出的是,DDD绝非一套单纯的技术工具集,但是我所看到的很多程序员却的确是这么认为的,并且也是怀揣着这样的想法来使用DDD的。过于拘泥于技术上的实现将导致DDD-Lite。简单来讲,DDD-Lite将导致劣质的领域对象,因为我们忽略了DDD战略建模所带来的好处。
    DDD的战略设计主要包括领域/子域、通用语言、限界上下文和架构风格等概念。

    3.2 领域与子域

    在这里插入图片描述

    3.3 限界上下文

    在这里插入图片描述

    3.4 领域场景分析

    在这里插入图片描述

    3.5 四色建模法

    在这里插入图片描述

    3.6 事件风暴结果图

    在这里插入图片描述

    3.7 限界上下文依赖结果图

    在这里插入图片描述

    4. 领域驱动战术设计

    4.1 战术设计概述

    领域驱动设计,整体包括战略和战术两部分,其中战略部分的落地需要团队合作、开发过程、流程制度等一系列支持,实施阻力相对较大。相反,战术部分,是一组面向业务的设计模式,是基于技术的一种思维方式,相对开发人员来说比较接地气,是提升个人格局比较好的切入点。

    战略设计为我们提供一种高层视野来审视我们的软件系统,而战术设计则将战略设计进行具体化和细节化,它主要关注的是技术层面的实施,也是对我们程序员来得最实在的地方。

    战术模式包含若干构造块模式,以便能够构建有效的领域模型。
    战术模式严重依赖于领域模型和通用语言,通过技术模式将领域模型和通用语言中的概念映射到代码实现中。随着模型的进化,代码实现也会进行重构,以更好的体现模型概念。当然,从技术重构角度也会发现一些隐含领域知识(概念),这些新的发现也会对领域模型产生影响。

    战术模式和通用语言一样,都工作在特定限界上下文内,其应用边界受限界上下文的保护。

    4.2 战术模式

    战术模式的作用是管理复杂性并确保领域模型中行为的清晰明确。可以使用这些模式来捕获和传递领域中的概念、关系、规则。

    每个构造块模式都具有单一职责:
    1.代表领域中的概念。如实体、值对象、领域服务、领域事件、模块等;
    2.用于管理对象的生命周期。如聚合、工厂、仓库等;
    3.用于集成或跟踪。领域事件、事件溯源等。

    在这里插入图片描述

    4.3 领域建模模式

    他们表述实现与模型间的关系,将分析模型绑定到代码实现模型。主要用于在代码中表述模型元素的模式。

    1.实体
    实体表述的是领域中的概念,它是由身份而不是属性来定义的。
    实体的身份标识在生命周期中保持不变,但其属性会发生变化。实体以身份标识作为唯一凭证,沿着时间轴,记录了实体所有变更事件。
    实体的一个实例是产品,一旦产品被生成好,其唯一身份就不会发生变化,但是其描述信息、价格等可以被多次修改。

    2.值对象
    值对象代表仅通过数据区分的领域元素和概念。用作模型中元素的描述,它不具有唯一标识。
    值对象不需要唯一标识,是因为它总是与另一个对象相关联,是在一个特定上下文中被解析的。通常,其生命周期会依附于它的关联对象(在这里,主要是实体对象)。
    值对象会当做不变对象来设计,在完成创建后,其状态就不能改变了。
    值对象比较好的例子就是现金,你无需关系货币的身份,只关心它的价值。如果有人用一张五美元钞票交换你的五张一美元钞票,也不会改变五美元本身。

    3.领域服务

    在模型中,领域服务封装了不能自然建模为值对象和实体的逻辑、流程和概念。
    它本身不具有身份和状态。它的职责是使用实体和值对象编排业务逻辑。
    领域服务的一个好例子是运输成本计算器,只要给出一组拖运货物和重量,它就能计算运输成本。

    4.模块

    模块主要用于组织和封装相关概念(实体、值对象、领域服务、领域事件等),这样可以简化对较大模型的理解。
    应用模块可以在领域模型中促成低耦合和搞内聚的设计。
    模块作用于单个领域,用于分解模型规模。子域用于限定领域模型适用范围(有界上下文)。

    4.4 对象生命周期模式

    相对来说,之前提到的模式重点在于表达领域概念。而对象生命周期模式,有点侧重于技术,用于表示领域对象的创建和持久化。

    1.聚合
    实体和值对象会相互协作,形成复杂的关联关系。我们需要在满足不变条件的前提下,将其拆分为一个个概念上的整体。通常,面对复杂的对象关系,在执行领域对象操作时,难以保证一致性和并发性。领域驱动设计由聚合模式来确保操作的一致性和事务的并发边界。大模型会通过不变性条件来划分,并组成概念化整体的实体和对象组,这个概念化整体便是聚合。

    聚合根之间的关系应该通过保持对另一个聚合根 ID 的引用,而非对对象本身的引用来实现。这一原则有助于保持聚合之间的边界并避免加载不必要的对象。

    不变性,是在领域模型中强制实现一致性的规则。无论何时对实体或聚合进行变更都要应用该业务规则。聚合外部的对象只能引用另一个聚合的聚合根,聚合中对象的任何变更都需要通过聚合根来完成。聚合根封装聚合数据并公开行为以对其进行修改。
    在这里插入图片描述
    2.工厂
    如果实体或值对象的创建过程非常复杂,可以将其委托给工厂。工厂会确保在领域对象使用之前就满足所有的不变条件。
    如果领域对象很简单并且不具有特殊的不变条件,可以使用构造函数代替工厂。当从持久化存储中重建领域对象时,也可以使用工厂。
    在这里插入图片描述
    3.仓库

    仓库主要用于持久化一个聚合。将聚合作为原子单元进行处理,因此,仓库操作的最小单元就是聚合,每个聚合会对应一个仓库。
    仓库是用来检索和存储聚合的机制,是对基础框架的一种抽象。
    其他模式。在这里插入图片描述

    4.4 其他模式

    1.领域事件
    领域事件表示问题空间中发生了一些业务人员关心的事情。主要用于表示领域概念。

    使用领域事件主要有以下两种场景:
    1.记录模型的变更历史;
    2.作为跨聚合通信方式。

    2.事件溯源

    传统的仅快照式持久化的一个替代项便是事件溯源。作为实体状态存储的替代,可以存储引发该状态的系列事件。存储所有的事件会提高业务的分析能力,不仅可以得知实体当前状态,还可以得知过去任意时点的状态。
    在这里插入图片描述

    4.5 总结

    实体
            由唯一标识符定义
            标识符在整个生命周期保存不变
            基于标识符进行相等性检查
            通过方法对属性进行更新
            
    值对象
            描述问题域中的概念和特征
            不具备身份
            不变对象
            
    领域服务
            处理无法放置在实体或值对象中的领域逻辑
            无唯一标识
            无状态服务
            
    模块
            分解、组织和提高领域模型的可读性
            命名空间,降低耦合,提供模型高内聚性
            定义领域对象组间的边界
            封装比较独立的概念,是比聚合、实体等更高层次的抽象
            
    聚合
            将大对象图分解成小的领域对象群,降低技术实现的复杂性
            表示领域概念,不仅仅是领域对象集合
            确定领域一致性边界,确保领域的可靠性
            控制并发边界
            
    工厂
            将对象的使用和构造分离
            封装复杂实体和值对象的创建逻辑
            保障复杂实体和值对象的业务完整性
            
    仓库
            是聚合根在内存中的集合接口
            提供聚合根的检索和持久化需求
            将领域层与基础实施层解耦
            通常不用于报告需求
            
    领域事件
            业务人员所关心的事件,是通用语言的一部分
            记录聚合根的所有变更
            处理跨聚合的通信需求
            
    事件溯源
            使用历史事件记录替换快照存储
            提供对历史状态的查询
    

    5. 领域驱动架构模型

    5.1 领域驱动基本架构

    5.1.1 分层架构

    在这里插入图片描述

    5.1.2 六边形理论

    在这里插入图片描述

    5.1.3 CQRS架构设计

    在这里插入图片描述

    5.2 领域驱动分层架构

    在这里插入图片描述

    1.用户接口层:面向前端用户提供服务和数据适配。这一层聚集了接口和数据适配相关的功能。
    2.应用层:实现服务组合与编排,主要适应业务流程快速变化的需求。这一层聚集了应用服务和时间订阅相关的功能。
    3.领域层:实现领域模型的核心业务逻辑。这一层聚集了领域模型的聚合、聚合根、实体、值对象、领域服务和领域事件,通过个领域对象的协同和组合形成领域模型的核心业务能力。
    4.基础设施层:它贯穿所有层,为各层提供基础资源服务。这一层聚集了各种底层资源相关的服务和能力。
    

    5.3 服务调用

    在这里插入图片描述

    5.4 服务封装与组合

    在这里插入图片描述

    5.5 领域架构对应关系

    在这里插入图片描述

    6. 领域驱动落地框架

    6.1 leave-sample

    中台架构与实现 DDD和微服务,清晰地提供了从战略设计到战术设计以及代码落地。
    leave-sample地址:https://gitee.com/serpmelon/leave-sample

    6.2 dddbook

    阿里技术专家详解DDD系列,例子精炼,项目代码结构与rdfa相似,极具参考价值。
    dddbook地址:https://developer.aliyun.com/article/719251

    6.3 Xtoon

    xtoon-boot是基于领域驱动设计(DDD)并支持SaaS平台的单体应用开发脚手架。重点研究如何应用。xtoon-boot提供了完整落地方案和企业级手脚架;
    gitee地址:https://gitee.com/xtoon/xtoon-boot
    github地址:https://github.com/xtoon/xtoon-boot

    6.4 DDD Lite

    DDD 领域驱动设计微服务简化版,简洁、高效、值得重点研究,主要问题是持久化采用的JPA,担心技术人员不熟悉,理论篇。
    gitee地址:https://gitee.com/litao851025/geekhalo-ddd

    快速入门:https://segmentfault.com/a/1190000018464713
    快速构建新闻系统:https://segmentfault.com/a/1190000018254111

    6.5 ruoyi_cloud

    若依快速开发平台,以该项目建立对阳光智采和rdfa的技术框架基准线。
    gitee地址:https://gitee.com/y_project/RuoYi-Cloud

    6.6 Cola框架

    cola框架是阿里大佬张建飞(Frank) 基于DDD构建的平台应用框架。“让COLA真正成为应用架构的最佳实践,帮助广大的业务技术同学,脱离酱缸代码的泥潭!”

    csdn地址:https://blog.csdn.net/significantfrank/article/details/110934799

    6.7 Axon Framework

    Axon Framework 是用来帮助开发人员构建基于命令查询责任分类(Command Query Responsibility Segregation: CQRS)设计模式的可伸缩、可扩展和可维护应用程序的框架。你只需要把工作重心放在业务逻辑的设计上。通过一些 Annotation ,Axon 使得你的代码和测试分离。

    https://www.oschina.net/p/axon
    https://www.jianshu.com/p/15484ed1fbde

    7. 领域驱动实践

    7.1 贫血模型和充血模型

    1.贫血模型概念
    贫血模型,所谓的贫血模型是在定义对象时,指定以对象的属性信息,却没有对象的行为信息,比如,定义Employee对象会包含id,name,age,sex,role,phone等信息,最后再通过添加一些对象属性的get/set方法来赋值取值操作。
    这些贫血对象在设计之初就被定义为只能包含数据,不能加入领域逻辑;所有的业务逻辑是放在所谓的业务层(xxxService, xxxManager对象中),需要使用这些模型来传递数据。

    2.充血模型概念
    充血模型,在定义对象时不但包含对象的属性信息,还包括对象的行为信息。所以充血模型是一种有行为的模型,模型中状态的改变只能通过模型上的行为来触发,同时所有的约束及业务逻辑都收敛在模型上。

    3.贫血模型和充血模型的区别
    贫血模型是事务脚本模式,贫血模型相对简单,模型上只有数据没有行为,业务逻辑由xxxService、xxxManger等类来承载,相对来说比较直接,针对简单的业务,贫血模型可以快速的完成交付,但后期的维护成本比较高,很容易变成我们所说的面条代码。
    充血模型是领域模型模式,充血模型的实现相对比较复杂,但所有逻辑都由各自的对象来负责,职责比较清晰,方便后期的迭代与维护。充血模型更加符合现实中的对象,因为一个员工在现实世界里不只有姓名,年龄,电话等,还可以工作,吃饭,睡觉等行为,只有属性信息的对象不是一个完整的对象。
    面向对象设计主张将数据和行为绑定在一起也就是充血模型,而贫血领域模型则更像是一种面向过程设计,很多人认为这些贫血领域对象是真正的对象,从而彻底误解了面向对象设计的涵义。
    贫血领域模型的根本问题是,它引入了领域模型设计的所有成本,却没有带来任何好处。最主要的成本是将对象映射到数据库中,从而产生了一个O/R(对象关系)映射层。只有当你充分使用了面向对象设计来组织复杂的业务逻辑后,这一成本才能够被抵消。如果将所有行为都写入到Service对象,那最终你会得到一组事务处理脚本,从而错过了领域模型带来的好处。而且当业务足够复杂时, 你将会得到一堆爆炸的事务处理脚本。

    4.贫血模型与充血模型案例验证
    员工贫血模型

    @Data
    public class Person {
        /**
         * 姓名
         */
        private String name;
    
        /**
         * 年龄
         */
        private Integer age;
    
        /**
         * 生日
         */
        private Date birthday;
    
        /**
         * 当前状态
         */
        private Stauts stauts;
    }
    
    public class PersonServiceImpl implements PersonService {
        public void sleep(Person person) {
            person.setStauts(SleepStatus.get());
        }
    	public void setAgeByBirth(Person person) {
            Date birthday = person.getBirthday();
            if (currentDate.before(birthday)) {
                throw new IllegalArgumentException("The birthday is before Now,It's unbelievable");
            }
            int yearNow = cal.get(Calendar.YEAR);
            int dayBirth = bir.get(Calendar.DAY_OF_MONTH);
            /*大概计算, 忽略月份等,年龄是当前年减去出生年*/
            int age = yearNow - yearBirth;
            person.setAge(age);
        }
    }
    
    public class WorkServiceImpl implements WorkService{
        public void code(Person person) {
            person.setStauts(CodeStatus.get());
        }
    }
    
    

    这一段代码就是贫血对象的处理过程,Person类, 通过PersonService、WorkingService去控制Person的行为,第一眼看起来像是没什么问题,但是真正去思考整个流程。WorkingService, PersonService到底是什么样的存在?与真实世界逻辑相比, 过于抽象。基于贫血模型的传统开发模式,将数据与业务逻辑分离,违反了 OOP 的封装特性,实际上是一种面向过程的编程风格。但是,现在几乎所有的 Web 项目,都是基于这种贫血模型的开发模式,甚至连 Java Spring 框架的官方 demo,都是按照这种开发模式来编写的。
    面向过程编程风格有种种弊端,比如,数据和操作分离之后,数据本身的操作就不受限制了。任何代码都可以随意修改数据。

    员工充血模型

    @Data
    public class Person extends Entity {
        /**
         * 姓名
         */
        private String name;
    
        /**
         * 年龄
         */
        private Integer age;
    
        /**
         * 生日
         */
        private Date birthday;
    
        /**
         * 当前状态
         */
        private Stauts stauts;
    
        public void code() {
            this.setStauts(CodeStatus.get());
        }
        public void sleep() {
            this.setStauts(SleepStatus.get());
        } 
        public void setAgeByBirth() {
            Date birthday = this.getBirthday();
            Calendar currentDate = Calendar.getInstance();
            if (currentDate.before(birthday)) {
                throw new IllegalArgumentException("The birthday is before Now,It's unbelievable");
            }
            int yearNow = currentDate.get(Calendar.YEAR);
            int yearBirth = birthday.getYear();
            /*粗略计算, 忽略月份等,年龄是当前年减去出生年*/
            int age = yearNow - yearBirth;
            this.setAge(age);
        }       
    }
    
    

    贫血模型和充血模型的区别

    /**
     * 贫血模型
     */
    public class Client {
    
        @Resource
        private PersonService personService;
    
        @Resource
        private WorkService workService;
    
        public void test() {
            Person person = new Person();
            personService.setAgeByBirth(person);
            workService.code(person);
            personService.sleep(person);
        }
    }
    /**
     * 充血模型
     */
    public class Client {
    
        public void test() {
            Person person = new Person();
            person.setAgeByBirth();
            person.code();
            person.sleep();
        }
    }
    

    上面两段代码很明显第二段的认知成本更低, 这在满是Service,Manage 的系统下更为明显,Person的行为交由自己去管理, 而不是交给各种Service去管理。

    7.2 DDD实现银行转账案例

    银行转账事务脚本实现在事务脚本的实现中,关于在两个账号之间转账的领域业务逻辑都被写在了MoneyTransferService的实现里面了,而Account仅仅是getters和setters的数据结构,也就是我们说的贫血模型:

    public class MoneyTransferServiceTransactionScriptImpl implements MoneyTransferService {
        private AccountDao accountDao;
        private BankingTransactionRepository bankingTransactionRepository;
        //...
    
        @Override
        public BankingTransaction transfer(
                String fromAccountId, String toAccountId, double amount) {
            Account fromAccount = accountDao.findById(fromAccountId);
            Account toAccount = accountDao.findById(toAccountId);
            //. . .
            double newBalance = fromAccount.getBalance() - amount;
            switch (fromAccount.getOverdraftPolicy()) {
                case NEVER:
                    if (newBalance < 0) {
                        throw new DebitException("Insufficient funds");
                    }
                    break;
                case ALLOWED:
                    if (newBalance < -limit) {
                        throw new DebitException(
                                "Overdraft limit (of " + limit + ") exceeded: " + newBalance);
                    }
                    break;
            }
            fromAccount.setBalance(newBalance);
            toAccount.setBalance(toAccount.getBalance() + amount);
            BankingTransaction moneyTransferTransaction =
                    new MoneyTranferTransaction(fromAccountId, toAccountId, amount);
            bankingTransactionRepository.addTransaction(moneyTransferTransaction);
            return moneyTransferTransaction;
        }
    }
    

    上面的代码大家看起来应该比较眼熟,因为目前大部分系统都是这么写的。其实我们是有办法做的更优雅的,这种优雅的方式就是领域建模,唯有掌握了这种优雅你才能实现从工程师向应用架构的转型。同样的业务逻辑,接下来就让我们看一下用DDD是怎么做的。银行转账领域模型实现如果用DDD的方式实现,Account实体除了账号属性之外,还包含了行为和业务逻辑,比如debit( )和credit( )方法。

    // @Entity
    public class Account {
        // @Id
        private String id;
        private double balance;
        private OverdraftPolicy overdraftPolicy;
    
        //. . .
        public double balance() {
            return balance;
        }
    
        public void debit(double amount) {
            this.overdraftPolicy.preDebit(this, amount);
            this.balance = this.balance - amount;
            this.overdraftPolicy.postDebit(this, amount);
        }
    
        public void credit(double amount) {
            this.balance = this.balance + amount;
        }
    }
    

    而且透支策略OverdraftPolicy也不仅仅是一个Enum了,而是被抽象成包含了业务规则并采用了策略模式的对象.

    public interface OverdraftPolicy {
        void preDebit(Account account, double amount);
    
        void postDebit(Account account, double amount);
    }
    
    public class NoOverdraftAllowed implements OverdraftPolicy {
        public void preDebit(Account account, double amount) {
            double newBalance = account.balance() - amount;
            if (newBalance < 0) {
                throw new DebitException("Insufficient funds");
            }
        }
    
        public void postDebit(Account account, double amount) {
        }
    }
    
    public class LimitedOverdraft implements OverdraftPolicy {
        private double limit;
        //...
        public void preDebit(Account account, double amount) {
            double newBalance = account.balance() - amount;
            if (newBalance < -limit) {
                throw new DebitException(
                        "Overdraft limit (of " + limit + ") exceeded: " + newBalance);
            }
        }
    
        public void postDebit(Account account, double amount) {
        }
    }
    
    //而Domain Service只需要调用Domain Entity对象完成业务逻辑即可。
    public class MoneyTransferServiceDomainModelImpl implements MoneyTransferService {
        private AccountRepository accountRepository;
        private BankingTransactionRepository bankingTransactionRepository;
        //...
    
        @Override
        public BankingTransaction transfer(
                String fromAccountId, String toAccountId, double amount) {
            Account fromAccount = accountRepository.findById(fromAccountId);
            Account toAccount = accountRepository.findById(toAccountId);
            //. . .
            fromAccount.debit(amount);
            toAccount.credit(amount);
            BankingTransaction moneyTransferTransaction =
                    new MoneyTranferTransaction(fromAccountId, toAccountId, amount);
            bankingTransactionRepository.addTransaction(moneyTransferTransaction);
            return moneyTransferTransaction;
        }
    }
    

    通过上面的DDD重构后,原来在事务脚本中的逻辑,被分散到Domain Service,Domain Entity和OverdraftPolicy三个满足SOLID的对象中。

    展开全文
  • 区块链的发展速度是非常快的,当你不注意的时候,区块链技术的应用已经在各领域展开,不但能够解决各领域存在的一些问题,而且对日常生活产生很的影响,给社会生产带来的好处也是多方面的: 首先、去中心化的...
  • 作为项目经理,就是要运用项目管理的 九大领域知识,在项目的个过程组中,科学合理的分配各种资源,来尽可能的实现项目干系人的期望,使他们获得最大的满意度。   4、项目管理的个主要过程组 一个项目的...
  • 数据分析应用领域有哪些

    千次阅读 2020-09-11 16:49:02
    在这个“数据分析应用领域”文章中,我将带您进入各个行业领域,在这里我将解释数据分析如何使它们发生革命性变化。  数据分析应用  数据分析应用程序的主要目标是通过分析大量数据来帮助公司做出更具...
  • 大数据仍未攻克的五大世界性难题

    千次阅读 2019-05-14 10:33:58
    在今天的文章中,我们将探讨个此类难题 ——看看如何才能将其解决。 如果大数据能够在传统领域之外进一步解决世界性难题,结果会怎么样?到目前为止,IBM、谷歌以及惠普等巨头级企业已经开始对这类高难度挑战发 起...
  • 面向对象五大基本原则详解

    千次阅读 2018-12-06 17:27:36
    面向对象五大基本原则单一职责原则计算器实例加法类AddJiSuanQi减法类SubJiSuanQi开放封闭原则(OCP)开放封闭原则示例(书店售书)类图代码实现第一个办法:第二个办法:第三个办法:代码实现归纳变化:扩展接口再...
  • 计算机网络应用领域

    千次阅读 2021-06-17 02:43:46
    描述计算机网络应用领域一、计算机网络在现代企业中的应用计算机网络的发展和应用改变了传统企业的管理模式和经营模式。在现代企业中企业信息网络得到了广泛的应用。它是一种专门用于企业内部信息管理的计算机网络,...
  • 二、系统老化的原因三、高质量代码的标准四、DDD基础概念4.1实体、值对象4.2贫血模型4.3仓库和工厂4.4防腐层4.5基础设计层4.6领域服务4.7聚合、DDD优点六、DDD四层架构规范, 一、什么是DDD? 领域驱动设计,是一...
  • 领域驱动(自己理解)

    千次阅读 2022-03-12 16:25:20
    一般过程:通过产品同学所写出的prd,利用领域模型的概念与业务相结合,完善出xmind,现在包括层:adapter、domain、app、client、infrastructure,其中最重要的就是我们的domain层,下面我们会一层一层的进行描述...
  • 零售业一直是许多创新的中心。...在所有IT解决方案中,物联网(IoT)已经成为一项非常强大的潜在技术,在本文中,我们将介绍在零售领域有效利用物联网的5种方法。 工业传感器、连网机器、店内分析...
  • 浅谈领域特定语言

    千次阅读 2021-07-16 15:43:29
    这些领域专家不是计算机科班出身,但是他们对自己的领域研究非常深入,他们非常期待能有一门面向领域的编程语言来帮助他们屏蔽计算机底层的复杂度,聚焦自己的领域,高效的进行编程。 在这样的背景下,.
  • 领域驱动设计战术模式:领域事件

    千次阅读 2019-08-27 23:30:59
    该文章为战术模式的第篇,重心讲解领域事件模式。 在建模时,有时会遇到一些业务逻辑的概念,它放在实体或值对象中都不太合适。这就是可能需要创建领域服务的一个信号。 使用领域事件来捕获发生在领域中的一些事情...
  • 浅析 DDD 领域驱动设计

    千次阅读 多人点赞 2021-08-22 10:31:44
    最近公司一场有关于领域驱动设计的技术分享会,引起了我的注意,主要讲解了服务的划分,Restful API的设计,如何将抽象具有统一业务的范畴的Model,使其模块化,同时能够提炼组合多个模块,使得业务能够独立服务化,...
  • 来源:华泰证券稳增长、促转型,把握新基建浪潮中的七大产业机遇七大领域:5G、数据中心、云计算、工业互联网、物联网、人工智能、传 统基础设施数字化改造新基建担负着不一样的历史使命。传统基...
  • 关于《学习书法的六大好处》优秀PowerPoint作品下载; 学习书法的六大好处PPT内容简介: 一、可以培养: 通过观察、分析点、横、竖、撇、捺、折的形状特点,书写方法,形式效果等,来完成每个字的书写过程。...
  • 船舶领域研究综述(截至2018)

    千次阅读 多人点赞 2018-03-01 09:54:15
    写在前面:本文是基于Rafal Szlapczynski, Joanna Szlapczynska在《Ocean ...该篇论文对截至2018年的船舶领域研究和应用进行了系统的综述。整理这篇文章的目的旨在对船舶领域的研究以及其应用方面进行系统的认识和...
  • DDD领域驱动设计:战略设计,战术设计,问题空间,解决空间,事件风暴,通用语言,限界上下文,上席文映射,问题域,领域,贫血模型,充血模型,领域模型,问题空间,解决空间,问题域,子域,核心子域,通用子域,...
  • Facebook三大愿景和五大核心价值

    万次阅读 2017-09-05 10:57:00
    文章讲的是Facebook三大愿景和五大核心价值,Facebook2月2日启动IPO(首次公开招股),计划融资50亿美元。该公司创始人、CEO马克·扎克伯格发表公开信,点明Facebook的三大愿景和五大核心价值。  以下为公开信全文: ...
  • 问题:被人诟病的「U」 「CRUD」中的「U」指的是「更新」操作。通常在我们的系统中「U」作为一种通用的方法可以更新资源的任何字段,然后使用新版本覆盖掉旧版本。 并且现在由于「REST」的流行,大多数的「API」都...
  • java有哪些技术领域

    万次阅读 2018-12-07 23:10:36
    五大优点:解耦、异步、横向扩展、安全可靠、顺序保证。常见的有activeMQ(支持多语言,实现jms1.1),RabbitMQ(支持更多语言,基于AMQP规范),kafka(高吞吐量,分布式,分区,O(1)磁盘顺序提供消息持久化) 2、...
  • 3大领域,4大方向,做好数据分析岗位的职业规划

    万次阅读 多人点赞 2018-03-15 11:09:05
    你进入哪个行业,很程度会决定你初期的技能树和技能点。譬如金融领域的风控模型、营销领域的生命周期、广告领域的点击率预估等,各有各的特色。如果是一位应届生,不妨多了解自己感兴趣的领域,和专业相...
  • 领域驱动设计 比较经典的书籍

    千次阅读 2019-12-02 20:11:03
    实现领域驱动设计作者:Vaughn Vernon推荐理由:《实现领域驱动设计》分别从战略和战术层面详尽地 讨论了如何实现DDD,其中包含了大量的最佳实践、设计准则和对一些问题的折中性讨论。豆瓣链接:https://boo...
  • 常用编程语言的特点以及应用 编程语言有很多种,以下就是对一些常用的编程语言的简单介绍和特点以及他们的一些应用领域。希望对你能有所帮助。
  • DDD领域驱动设计

    万次阅读 2018-08-06 00:35:10
    2004年Eric Evans 发表Domain-Driven Design –Tackling Complexity in the Heart of Software (领域驱动设计),简称Evans DDD。Evans DDD是一套综合软件系统分析和设计的面向对象建模方法。 领域驱动设计分为两...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 73,906
精华内容 29,562
热门标签
关键字:

五大领域的好处

友情链接: Time-frequency-toolbox.zip