博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
领域对象驱动开发:来吧,让我们从对象开始吧
阅读量:4514 次
发布时间:2019-06-08

本文共 4122 字,大约阅读时间需要 13 分钟。

 今天我们通过一个“超市收银”业务来作为我们的示例(虽然这个示例看上去不太正常,但是它确表述我们所需要的)。我们将从业务分析到业务建模然后最后的编码来用“面向领域对象”的方式来做我们的项目。

好,我们开始吧!

 

一、业务分析

 

大家都去超市买过东西,对超市收银业务都比较熟悉。什么?你不熟?好吧,那我们找个收银员给大家讲解下(领域专家)。

 

收银员小慧:哦,是这样呢。顾客排队银帐我就收银呢,我要使用收银机呢。收银机就能计算出要收的钱呢,我就扫一下呢,就OK了呢。然后就收银了呢。

 

听了小慧的讲解,我们心中有了业务的概念了。我们这里采用《业务关键字分析法》来找出此业务流程里面的一些关系字:

 

商品

顾客

收银员

收银机

*收银

*选商品

*收银员使用收银机

*收银机扫商品计算金额

 

好了,列出这些“业务关键字”了,我们就可以建我们的对象模型了。

 

二、系统建模

 

上面我们分析出了一些“业务关键字”接下来我们分析这些业务关键字并深入他们的业务。

 

商品对象(Goods)

属性:商品名称(GoodsName)、商品价格(GoodsPrice)

行为:在这里商品对象是没有行为的,我们也可以叫它“值对象”。

 

顾客对象(Customer)

属性:顾客姓名(CustomerName)、顾客选购的商品(Goodss)

行为:选购想买的商品(LikeBuy)、听收银员说要收多少RMB(ListenAmount)

 

收银员对象(Cashier)

属性:收银员姓名(CashierName)

行为:收银(CashierRegister)

 

收银机对象(CashierRegister)

属性:收银机编号(CashRegisterNo)

字段:总金额(_totalAmount)

行为:收银(CashRegisters)、显示收银总额(ShowAmount)

 

 

有木有!有木有?有木有很直观,这也就是面向对象分析的好处,因为对象就是对现实的抽象,我们现实中的事务可以很方便的用对象抽象出来。我们很容易发现,这和用表来描述这些业务模型显然要不方便的多。表还只能描述属性,造成了属性与行为的分离。

 

三、代码示例

 

商品对象

 

///
 
<summary>
    
///
 商品
    
///
 
</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>
    
///
 顾客
    
///
 
</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>
    
///
 收银员
    
///
 
</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>
        
///
 对象标识
        
///
 
</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);
            }

 

显示结果

 

 

上面的例子虽然不是很恰当,但是它也很好的像我们表达出了领域驱动分析问题、面向对象驱动开发的好处了。

 

最后大家回想一下,用数据库表驱动的方式。分析这个业务会是什么样子的。。。。

转载于:https://www.cnblogs.com/assion/archive/2011/05/13/2045253.html

你可能感兴趣的文章
Kafka Producer相关代码分析【转】
查看>>
LeetCode 121. Best Time to Buy and Sell Stock
查看>>
麻省理工学院公开课-第四讲:快速排序 及 随机化 算法
查看>>
复杂表达式
查看>>
R12.1.3 & R12.2.X 注册客户化应用
查看>>
实验十七 线程同步控制
查看>>
SQL Server 触发器
查看>>
Ural 1146 Maximum Sum(DP)
查看>>
《STL源代码分析》---stl_stack.h读书笔记
查看>>
UVA 10385 - Duathlon(三分法)
查看>>
div同时使用两个class
查看>>
在路上,三线城市互联网创业记录
查看>>
spark 编译遇到的错误及解决办法(五)
查看>>
框架篇: React + React-Router + antd + nodejs + express框架开发运用(nodejs做前后端server)...
查看>>
8、使用转换流处理标准输入
查看>>
Git 常用命令
查看>>
Why does Http header contains "X-SourceFiles"?
查看>>
uva 10976 fractions again(水题)——yhx
查看>>
爬虫实战篇---数据入库之去重与数据库
查看>>
CMPSC-132 – Programming and Computation
查看>>