领域模型和领域对象的概念
面向对象架构模式之:领域模型(Domain Model)
领域模型是对领域内的概念类或现实世界中对象的可视化表示。又称概念模型、领域对象模型、分析对象模型。它专注于分析问题领域本身,发掘重要的业务领域概念,并建立业务领域概念之间的关系。
先来完成最简单的部分,即找关系。也就是说,按照所谓的关系,我们来重构 事务脚本 中的代码。上篇“你在用什么思想编码:事务脚本 OR 面向对象?”中同样的需求,如果用领域模式来做的话,我们大概可以这样设计:
概念
编辑
核心元素
编辑
命名
编辑
对象
编辑
模型
编辑
主角
编辑
定位
编辑
特征
编辑
设计
编辑
抽象业务模型
编辑
关系
编辑
总结
编辑
领域对象驱动开发:来吧,让我们从对象开始吧
今天我们通过一个“超市收银”业务来作为我们的示例(虽然这个示例看上去不太正常,但是它确表述我们所需要的)。我们将从业务分析到业务建模然后最后的编码来用“面向领域对象”的方式来做我们的项目。
好,我们开始吧!
一、业务分析
大家都去超市买过东西,对超市收银业务都比较熟悉。什么?你不熟?好吧,那我们找个收银员给大家讲解下(领域专家)。
收银员小慧:哦,是这样呢。顾客排队银帐我就收银呢,我要使用收银机呢。收银机就能计算出要收的钱呢,我就扫一下呢,就OK了呢。然后就收银了呢。
听了小慧的讲解,我们心中有了业务的概念了。我们这里采用《业务关键字分析法》来找出此业务流程里面的一些关系字:
商品
顾客
收银员
收银机
*收银
*选商品
*收银员使用收银机
*收银机扫商品计算金额
好了,列出这些“业务关键字”了,我们就可以建我们的对象模型了。
二、系统建模
上面我们分析出了一些“业务关键字”接下来我们分析这些业务关键字并深入他们的业务。
商品对象(Goods)。
属性:商品名称(GoodsName)、商品价格(GoodsPrice)。
行为:在这里商品对象是没有行为的,我们也可以叫它“值对象”。
顾客对象(Customer)。
属性:顾客姓名(CustomerName)、顾客选购的商品(Goodss)
行为:选购想买的商品(LikeBuy)、听收银员说要收多少RMB(ListenAmount)
收银员对象(Cashier)。
属性:收银员姓名(CashierName)
行为:收银(CashierRegister)
收银机对象(CashierRegister)。
属性:收银机编号(CashRegisterNo)
字段:总金额(_totalAmount)
行为:收银(CashRegisters)、显示收银总额(ShowAmount)
有木有!有木有?有木有很直观,这也就是面向对象分析的好处,因为对象就是对现实的抽象,我们现实中的事务可以很方便的用对象抽象出来。我们很容易发现,这和用表来描述这些业务模型显然要不方便的多。表还只能描述属性,造成了属性与行为的分离。
三、代码示例
商品对象
/// 商品
/// </summary>
public class Goods
{
/// <summary>
/// 对象标识
/// </summary>
public Guid OKey { get ; set ; }
/// <summary>
/// 商品名称
/// </summary>
public string GoodsName { get ; set ; }
/// <summary>
/// 商品价格
/// </summary>
public decimal GoodsPrice { get ; set ; }
}
顾客对象
/// 顾客
/// </summary>
public class Customer
{
/// <summary>
/// 对象标识
/// </summary>
public Guid OKey { get ; set ; }
/// <summary>
/// 顾客姓名
/// </summary>
public string CustomerName { get ; set ; }
private List < Goods > _goodss = new List < Goods > ();
/// <summary>
/// 顾客购买的商品
/// </summary>
public List < Goods > Goodss
{
get { return _goodss; }
set { _goodss = value; }
}
/// <summary>
/// 顾客选购商品
/// </summary>
/// <param name="goods"> 商品 </param>
public void LikeBuy(Goods goods)
{
this ._goodss.Add(goods);
}
/// <summary>
/// 听收银员应收多少钱
/// </summary>
/// <param name="amount"></param>
public void ListenAmount( decimal amount)
{
Console.WriteLine( " 我是[{0}],我买了{1}件商品。我共花了{2}元RMB。 " , this .CustomerName, this .Goodss.Count, amount.ToString( " f2 " ));
}
收银员对象
/// 收银员
/// </summary>
public class Cashier
{
/// <summary>
/// 对象标识
/// </summary>
public Guid OKey { get ; set ; }
/// <summary>
/// 收银员姓名
/// </summary>
public string CashierName { get ; set ; }
/// <summary>
/// 收银
/// </summary>
/// <param name="customer"> 顾客 </param>
public void CashRegister(Customer customer)
{
// 打开使用收银机
CashRegister cashRegister = new CashRegister();
// 对顾客的商品进行收银机扫码,收银
foreach (var goods in customer.Goodss)
{
// 使用收银机扫商品进行收银
cashRegister.CashRegisters(goods);
}
// 通知顾客一共收多少钱
customer.ListenAmount(cashRegister.ShowAmount());
}
}
收银机对象
/// 对象标识
/// </summary>
public Guid OKey { get ; set ; }
/// <summary>
/// 收银机编号
/// </summary>
public string CashRegisterNo { get ; set ; }
/// <summary>
/// 总价格
/// </summary>
private decimal _totalAmount { get ; set ; }
public CashRegister()
{
// 收银总额置0
this ._totalAmount = 0 ;
}
/// <summary>
/// 收银
/// </summary>
/// <param name="goods"> 商品 </param>
public void CashRegisters(Goods goods)
{
this ._totalAmount += goods.GoodsPrice;
}
/// <summary>
/// 显示收银总额
/// </summary>
/// <returns></returns>
public decimal ShowAmount()
{
return this ._totalAmount;
}
模拟业务流程
Goods RedWine = new Goods() { GoodsName = " 红酒 " , GoodsPrice = 1800 ,OKey = Guid.NewGuid() };
Goods Condoms = new Goods() { GoodsName = " 安全套 " , GoodsPrice = 35 ,OKey = Guid.NewGuid() };
// 我们创建几位顾客
Customer Chunge = new Customer() { CustomerName = " 春哥 " , OKey = Guid.NewGuid() };
Customer Beianqi = new Customer() { CustomerName = " 贝安琪 " , OKey = Guid.NewGuid() };
// 当然,我们需要收银员啊
Cashier CashierMM = new Cashier() { CashierName = " 收银员MM " , OKey = Guid.NewGuid() };
// 顾客逛了一圈,选了自己想要的商品
Chunge.LikeBuy(RedWine);
Beianqi.LikeBuy(RedWine);
Beianqi.LikeBuy(Condoms);
// 顾客开始排队结帐了
Queue < Customer > customerQueue = new Queue < Customer > ();
customerQueue.Enqueue(Chunge);
customerQueue.Enqueue(Beianqi);
// 队伍过来,按先后顺序挨个收银喽
foreach (var customer in customerQueue)
{
// 收银
CashierMM.CashRegister(customer);
}
显示结果
上面的例子虽然不是很恰当,但是它也很好的像我们表达出了领域驱动分析问题、面向对象驱动开发的好处了。
最后大家回想一下,用数据库表驱动的方式。分析这个业务会是什么样子的。。。。
领域模型和领域对象的概念相关推荐
- java领域对象_java的几种对象(po,dto,dao等)
j2ee中,经常提到几种对象(object),理解他们的含义有助于我们更好的理解面向对象的设计思维. POJO(plain old java object):普通的java对象,有别于特殊的java对 ...
- DDD领域驱动开发概念介绍及简单示例
什么是领域驱动模型? 2004年Eric Evans 发表<领域驱动设计--软件核心复杂性应对之道>(Domain-Driven Design –Tackling Complexity i ...
- 领域驱动核心概念总结
领域驱动的核心是建立正确的领域模型,以一种领域专家(产品经理-项目经理).开发人员都能理解的通用语言作为相互交流的工具,在交流的过程中发现领域概念,然后将这些概念设计成一个领域模型:每一个领域都是一个 ...
- 基于事件驱动架构构建微服务第2部分:领域对象和业务规则
原文链接:https://logcorner.com/building-microservices-through-event-driven-architecture-part2-domain-obj ...
- java中级做dao模型_DAO-持久层-领域对象-贫血模型
原文 关于"贫血模型"的讨论几乎没有停止过,在openfans.org的开发过程中,我们也讨论了很久,我觉的有很多东西应该记下来: 明确一下意思先: DAO:数据操作对象,会操作数 ...
- 20190813 On Java8 第一章 对象的概念
第一章 对象的概念 抽象 Alan Kay 总结了对象的五大基本特征 万物皆对象. 程序是一组对象,通过消息传递来告知彼此该做什么. 每个对象都有自己的存储空间,可容纳其他对象. 每个对象都有一种类型 ...
- 【DDD】持久化领域对象的方法实践
目录 概述 开篇 字段 Or 表 来说一下持久化为字段的情况 来说一下持久化为表的情况 怎么持久化集合值对象 将集合值对象存为字段 将集合值对象存为表 基于快照的数据存储对象 比较 总结 概述 在实践 ...
- 信息系统分析与设计——第八章 领域对象建模
找到问题域中的对象并建立模型 一.面向对象方法概述 从面向对象的角度来看,世界就是由对象组成的.任何给定的商业功能都是由一整套共同工作的对象互相协作来完成的.对象不仅可以执行功能,还拥有属性(数据). ...
- 使用扩展方法和静态门面类实现伪领域对象
背景介绍 领域对象,在此特指充血的领域对象模型,在解决什么是伪领域对象之前,需要事先解释何为充血的领域对象.在此后的介绍中,假设我们存在对象模型Employee-Department. 在面向对象的实 ...
最新文章
- caffe loss一直nan什么情况
- centos 安装 MatConvNet (gpu)
- Python数据分析学习笔记02:Python语言基础、IPython与Jupyter笔记本
- 使用SQL Server代理生成计划
- python字符串及基本运算
- 工业机器人操作机设计原则和设计方法
- 单片机内部弱上拉_有继电器引发对单片机驱动能力的思考!
- 软考软件设计师中java题_计算机基础试题整理与解析-软考中级软件设计师
- 中学生计算机制作大赛作品,“全国中小学电脑制作大赛”全校征集啦!
- 内容:提出共享储能背景下微网运营商与用户聚合商间的 Stackelberg 博弈模型,在 MATLAB 平台上进行算例仿真
- Excel功能逻辑结构图
- 从北斗到Mate 50:星空中的中国式浪漫
- 龙卷风代码html,龙卷风旋涡.html
- 操作系统:覆盖技术与交换技术
- DTOI 10.25 测试 T3 雪人
- 2020 ICPC 济南 A Matrix Equation (高斯消元)
- NLPCC2017 | AISpeech Night学术交流晚宴等你来!
- 一文读懂命名实体识别
- 如何搭建一个机器人控制系统
- 我心中的程序设计新时代