本人是ABP初学者,在看英文文档和@tkb至简ABP框架理论研究总结(典藏版)时,发现大神@tkb至简中少了对Value Objects的翻译,看文档是新的,大神没时间把,小弟给补充上。  

介绍

  “用于描述领域的某个方面而本身没有概念标识的对象称为 a VALUE OBJECT”(Eric Evans)

  对于实体是相反的,实体有它们的表示(id),一个值对象没有标识。如果两个实体的标识不相同,即使它们所有的其他实体属性是一样的,它们也被称为不同的对象/实体。想象一下,两个不同的人拥有相同的名字、姓氏和年龄,但是他们拥有不同的身份证号,他们就是不同的人。但是,对于一个地址(它是一个经典的值对象)类,如果两个地址是相同的国家、城市、街道号码...等等,也被称为同样的地址。

  在领域驱动模型中(DDD),值对象是领域对象的另一种类型,它能包含业务逻辑,它是领域必不可少的一部分。

值对象基类

  在ABP中,可以很简单的就创建值对象类型ABP有一个ValueObject<T>基类,继承它就可以了。示例,地址 值对象 类型:

    public class Address : ValueObject<Address>
{
public Guid CityId { get; private set; } //引用城市实体. public string Street { get; private set; } public int Number { get; private set; } public Address(Guid cityId, string street, int number)
{
CityId = cityId;
Street = street;
Number = number;
}
}

  假设两个值对象所有的属性都是一致的,值对象基类的重写equality操作(和其他相关操作和方法)来比较两个值对象。 那么,所有这些测试都通过:

var address1 = new Address(new Guid("21C67A65-ED5A-4512-AA29-66308FAAB5AF"), "Baris Manco Street", );
var address2 = new Address(new Guid("21C67A65-ED5A-4512-AA29-66308FAAB5AF"), "Baris Manco Street", ); Assert.Equal(address1, address2);
Assert.Equal(address1.GetHashCode(), address2.GetHashCode());
Assert.True(address1 == address2);
Assert.False(address1 != address2);

  即使它们在内存中,是不同的对象。在我们的领域中也是相同的。

最佳实践

  在这里有一些对于值对象最佳的实践

  • 如果没有一个充分的理由设计值对象是易变的话,那最好设计一个值对象是不可变的(像地址这样的)。
  • 从整体概念上讲,属性组成一个值对象。例如,在一个人类实体属性中,不应该独立城市ID、街道和编号。同时,它使人类实体更加简单。

ABP文档翻译--值对象的更多相关文章

  1. ABP框架 - 值对象

    文档目录 本节内容: 简介 值对象基类 最佳实践 简介 “一个表示领域的一个描述性方面的没有概念上的身份对象,称为值对象.“(Eric Evans). 与一个有身份(Id)实体相反,一个值对象没有身份 ...

  2. ABP官方文档翻译 3.2 值对象

    值对象 介绍 值对象基类 最佳实践 介绍 "展现领域描述性层面且没有概念性身份的对象称之为值对象."(Eric Evans). 和实体相反,实体有身份标示(Id),值对象没有身份标 ...

  3. [2017-09-04]Abp系列——为什么值对象必须设计成不可变的

    本系列目录:Abp介绍和经验分享-目录 这篇是之前翻备忘录发现漏了的,前阵子刚好同事又提及过这个问题,这里补上. 本文重点在于理解什么是值对象的不可变性. Abp的ValueObject以及EF的Co ...

  4. [Abp vNext 源码分析] - 5. DDD 的领域层支持(仓储、实体、值对象)

    一.简要介绍 ABP vNext 框架本身就是围绕着 DDD 理念进行设计的,所以在 DDD 里面我们能够见到的实体.仓储.值对象.领域服务,ABP vNext 框架都为我们进行了实现,这些基础设施都 ...

  5. ABP(现代ASP.NET样板开发框架)系列之16、ABP应用层——数据传输对象(DTOs)

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之16.ABP应用层——数据传输对象(DTOs) ABP是“ASP.NET Boilerplate Project ...

  6. ABP应用层——数据传输对象(DTOs)

    ABP应用层——数据传输对象(DTOs) 基于DDD的现代ASP.NET开发框架--ABP系列之16.ABP应用层——数据传输对象(DTOs) ABP是“ASP.NET Boilerplate Pro ...

  7. 如何一步一步用DDD设计一个电商网站(九)—— 小心陷入值对象持久化的坑

    阅读目录 前言 场景1的思考 场景2的思考 避坑方式 实践 结语 一.前言 在上一篇中(如何一步一步用DDD设计一个电商网站(八)—— 会员价的集成),有一行注释的代码: public interfa ...

  8. 《Entity Framework 6 Recipes》中文翻译系列 (44) ------ 第八章 POCO之POCO中使用值对象和对象变更通知

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 8-4  POCO中使用值对象(Complex Type--也叫复合类型)属性 问题 ...

  9. 应用程序框架实战十七:DDD分层架构之值对象(层超类型篇)

    上一篇介绍了值对象的基本概念,得到了一些朋友的支持,另外也有一些朋友提出了不同意见.这其实是很自然的事情,设计本来就充满了各种可能性,没有绝对正确的做法,只有更好的实践.但是设计与实践的好与坏,对于不 ...

随机推荐

  1. Android SwipeRefreshLayout 下拉刷新——Hi_博客 Android App 开发笔记

    以前写下拉刷新 感觉好费劲,要判断ListView是否滚到顶部,还要加载头布局,还要控制 头布局的状态,等等一大堆.感觉麻烦死了.今天学习了SwipeRefreshLayout 的用法,来分享一下,有 ...

  2. 谈谈如何使用Netty开发实现高性能的RPC服务器

    RPC(Remote Procedure Call Protocol)远程过程调用协议,它是一种通过网络,从远程计算机程序上请求服务,而不必了解底层网络技术的协议.说的再直白一点,就是客户端在不必知道 ...

  3. ASP.NET MVC开发日常一:SessionID合理清除

    在MVC Web开发中临时存储数据一般会用到Session,Cookie,ViewBag,ViewData,TempData.每个的使用场景是不同,具体区别有空再补上. Session数据最敏感,最需 ...

  4. UWP开发之Template10实践:本地文件与照相机文件操作的MVVM实例(图文付原代码)

    前面[UWP开发之Mvvmlight实践五:SuspensionManager中断挂起以及复原处理]章节已经提到过Template10,为了认识MvvmLight的区别特做了此实例. 原代码地址:ht ...

  5. Spark读写Hbase的二种方式对比

    作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 一.传统方式 这种方式就是常用的TableInputFormat和TableOutputForm ...

  6. C# 给word文档添加水印

    和PDF一样,在word中,水印也分为图片水印和文本水印,给文档添加图片水印可以使文档变得更为美观,更具有吸引力.文本水印则可以保护文档,提醒别人该文档是受版权保护的,不能随意抄袭.前面我分享了如何给 ...

  7. .NET Core 2016 回顾

    都在回顾自己的2016,今天我们来看看.NET Core的2016. 每一年的脚步的确是快,转眼间马上就2017.新的一年,带着理想和抱负继续出发. 1 月 ASP.NET 5 改名 ASP.NET ...

  8. 使用github远程仓库

    经过几天对github的研究,终于把自己想完成的给解决了,发现google真的有很多解释,但是很多也会出现一些bug,对于初学者真的很多烦恼,所以整理一份,能给初识github的你有所帮助 一,首先, ...

  9. Flex 布局教程:语法篇

    作者: 阮一峰 网页布局(layout)是CSS的一个重点应用. 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便 ...

  10. iOS在导航栏上居中显示分段控件(UISegmentedControl)

    UISegmentedControl *segmentedControl = [[UISegmentedControl alloc] initWithItems:nil]; segmentedCont ...