实体

 

具有身份和连贯性的领域概念

唯一、唯一标识和可变性,这也是区分与值对象的特征

 

上下文依赖

不同的上下文中 , 同一实体的概念也会发生变化 , 甚至在某一上下文中为实体 , 在另一上下文却为值对象 , 实体主要与身份有关 - 专注于"谁"而非"什么"

一个示例就是资金概念 , 在一个银行业应用程序中 , 一位顾客可能会在他的银行放入1000元 , 当他某一天取出这1000元时 , 相较于他存进去的钱 , 可能会收到不同的钞票或硬币 , 不过这并不重要 , 因为在银行业应用程序中资金是不重要的是没有身份的 , 顾客只关心资金的价值 , 所以在此上下文中资金无疑是值对象。但是在另外一个领域中 , 比如涉及到钞票印刷或钞票的可追溯性行业 , 个体钞票或硬币的身份就会是一个重要的概念了 , 在此上下文中钞票就会是一个具有唯一身份标识的实体

 

适当将行为推入到值对象和领域服务中

保持实体专注于身份这一职责很重要 , 这会避免它们变得臃肿 , 比如地址值对象 , 不应该将地址设置这类行为放在实体上 , 直接在实体中实现新行为会很容易 , 不过在实体身份有关的逻辑中混入实际不属于该实体的逻辑 , 这会样实体的表述性降低 , 领域概念模糊 , 更会变得非常臃肿

 

验证并强制不变性

除了身份之外 , 实体的一个主要实现需求就是确保他们是自验证并总是有效的 , 当一个实体被构造出来后 , 他的状态应该总是正确 。 比如在订单下单领域 , 收货地址要保持有效 , 规则便是省市区街道等等不为空 , 所以在构造时必须一个个验证 , 否则便抛出异常。实体还要负责强制实现一种更为基础的条件:不变条件。不变条件就是关于实体的实际情况 , 他们会强制特定特性的值必须落在特定范围 , 以便成为被建模实体的精确表示 , 比如下单领域 , 其中一个不变条件就是总价这个状态(属性) , 总价 = 单价 * 数量 - 优惠金额 +运费 , 这就是总价的不变条件 , 不变条件不是说非得是特定的值 , 而是说 , 必须按照业务的不变规则来 , 比如上面说的下单 , 总价的规则是不会变的(如果发生变化 , 那属于业务变化了 , 肯定是得改代码 , 不用计较) , 从这一点也能看出充血模型对比贫血模型的巨大优势

 

适当将行为推入到值对象和领域服务中

保持实体专注于身份这一职责很重要 , 这会避免它们变得臃肿 , 比如地址值对象 , 不应该将地址设置这类行为放在实体上 , 直接在实体中实现新行为会很容易 , 不过在实体身份有关的逻辑中混入实际不属于该实体的逻辑 , 这会样实体的表述性降低 , 领域概念模糊 , 更会变得非常臃肿

 

专注行为 , 而非数据

实体应该是面向行为的 , 这意味着实体的接口应该公开传递领域行为的表述性方法 , 而不是公开状态。 更主要的是 , 这与"告知而非询问"这个OOP原则相关 , 对象应该告诉客户端他们能做什么不能做什么。而不是公开属性并将其留给客户端来判对象是否属于特定状态,这样相当于领域逻辑被剥离,仅仅将这个对象当作数据的容器使用。一旦出现逻辑被剥离到客户端的情况,那时候你就不能保证逻辑被重复的次数(因为你不能保证客户端只会有一个), 这会增加实体状态被系统其他部分以不提供为何被更新说明的方式进行更新的风险 , 导致领域概念不清晰

 

posted @ 2016-10-20 09:40  韬韬韬你羞得无礼  Views(289)  Comments(0Edit  收藏  举报