第二部分:模型驱动的构造块
先截一张图来说明下这部分的大致内容
通过Layered Architecture将系统划分为用户界面层,应用层,领域层,基础设施层,从而将模型隔离在领域层中。用户界面层或者说表示层用于展示系统用户所能看到的界面等,应用层用于调用领域层的对象来解决一些业务问题,显示一些任务状态等,应用层不应包含业务逻辑。领域层是真正反映业务实质的层,应包含业务规则与业务知识,是软件的核心。
MVC模式就是一种将应用层与领域层分开的一种设计模式。
与model-drive design对应的一种模式叫做smart-ui,smart-ui是在用户界面中嵌入业务逻辑,功能模块之间没有任何关系,也没有任何抽象。但smart-ui也有自己的优点:
<!--[if !supportLists]-->1. <!--[endif]-->可以实现快速开发;
<!--[if !supportLists]-->2. <!--[endif]-->对开发人员要求低;
<!--[if !supportLists]-->3. <!--[endif]-->模块或者说界面之间彼此独立;
Entity,Value Object,Service是表示模型的三种模式。Entity是表示某种具有连续性和标识的事物,比如某个人,某张订单,某个铲平。Value Object则是表示某种事物的某种状态的属性,比如颜色,字符串等。Service则表示领域中的一些动作或者操作。
模型之间的关联需要通过以下三种方法使之更易于控制:
<!--[if !supportLists]-->1. <!--[endif]-->规定一个遍历方向;
<!--[if !supportLists]-->2. <!--[endif]-->添加限定符,以便有效地减少多重关联;
<!--[if !supportLists]-->3. <!--[endif]-->消除不必要的关联;
Entity和Value Object这两个还比较好理解,对于Service这个模式刚看到时还以为是现在工作中经常写的domainService这种接口呢。其实不然!(现在工作中的Service还承担了后面会讲到的Repository模式的职责,所以在命名上喜欢用domain+Service,其实职责应该分开)
有一些重要的领域操作既不是Entity,也不是Value Object,这些操作从本质上讲是一些活动或动作,而不是事物。Service应该以一个活动命名而不是以一个Entity命名。它的参数和结果应该是领域对象,就是说Service是定义了为用户做什么。
好的Service应具备以下3种特征:
<!--[if !supportLists]-->1. <!--[endif]-->与领域概念相关的操作不是Entity或者Value Object的一个自然的部分。
<!--[if !supportLists]-->2. <!--[endif]-->接口是根据领域模型的其他元素定义的。
<!--[if !supportLists]-->3. <!--[endif]-->操作是无状态的。
对于Service,举例来说,对于电子商务型的系统,创建订单就是一个Service里面的一个方法,这个操作会涉及到订单的创建,支付,商品的库存扣减。这里面会设计到多个领域,订单,订单项,账户,商品等信息的创建以及更新等,单独放在哪一个Entity中都不合适。对于这一类Service,就是将领域的一些潜在功能组织起来以执行某种任务的脚本。
Service可以分布于各个层中(应用层,领域层,基础设施层)。