面向领域开发示例有哪些具体案例?
- 内容介绍
- 文章标签
- 相关推荐
本文共计1675个文字,预计阅读时间需要7分钟。
最近面向领域的知识爆炸,我也来添一把火。说说平时做项目时用到的发展方式,以下为伪代码,主要展示一下我现在的发展方式,供大家讨论。
系统开发中不考慮持續、UI、AOP 和 。
最近面向领域的知识挺火,我也来插一腿。说说我平时做项目时候用到的开发方式,以下代码为伪代码,主要展示一下我现在的开发方式供大家讨论,系统中不考虑持久、UI、AOP和IOC等方面内容。
说到.NET社区的“开发方式”就不得不提一下Petshop了,可以说Petshop真是影响了.NET的一代人。以至于三层成了.NET这边流行的标准的开发方式。但是要说一下Petshop是数据库驱动业务核心的过程式开发,也正是它也毒害了一批人。
下面我们以一个最常见也是大家比较熟的下定单来简单看一下。首先是系统的几个领域类:
应牧章的要求,加上类之间的关系:这里的关系很简单,Order与OrderItem是一对多关系;OrderItem与Product是一对多关系;定单提交业务Order对象是个“根”
我也就不解释了,发下几个类的代码里面有注解。大家看一下就明白了。这里我们要强调的是类关系,还有一个根的概念。每个业务流都会有一个根。而根不是整个系统唯一确定的是而是根据对象在哪个业务范围内而决定的。显然这里面是Order定单对象。
///<summary>///商品
///</summary>
publicclassProduct
{
///<summary>
///键
///</summary>
publicintSysNo{get;set;}
///<summary>
///商品名称
///</summary>
publicstringProductName{get;set;}
///<summary>
///商品价格
///</summary>
publicdecimalProductPrice{get;set;}
privateCategory_category;
///<summary>
///所属分类
///</summary>
publicCategoryCategory
{
get{return_category;}
set{_category=value;}
}
} ///<summary>
///定单
///</summary>
publicclassOrder
{
#region属性
///<summary>
///键
///</summary>
publicintSysNo{get;set;}
///<summary>
///定单ID
///</summary>
publicstringOrderId{get;set;}
///<summary>
///定单金额
///</summary>
publicdecimalOrderAmount{get;set;}
///<summary>
///运费金额
///</summary>
publicdecimalShipAmount{get;set;}
///<summary>
///支付金额
///</summary>
publicdecimalPayAmount{get;set;}
///<summary>
///定单状态
///</summary>
publicintOrderStatus{get;set;}
///<summary>
///定单时间
///</summary>
publicDateTimeOrderTime{get;set;}
privateList<OrderItem>_orderItems=newList<OrderItem>();
///<summary>
///定单明细
///</summary>
publicList<OrderItem>OrderItems
{
get{return_orderItems;}
set{_orderItems=value;}
}
#endregion
#region方法
///<summary>
///计算定单金额
///</summary>
///<returns></returns>
publicdecimalGetOrderAmount()
{
decimalamount=0;
//计算商品金额
foreach(variteminOrderItems)
{
amount+=item.GetAmount();
}
//加上运费
amount+=ShipAmount;
returnamount;
}
#endregion
} ///<summary>
///定单明细
///</summary>
publicclassOrderItem
{
#region属性
///<summary>
///键
///</summary>
publicintSysNo{get;set;}
privateProduct_product=newProduct();
///<summary>
///购买商品
///</summary>
publicProductProduct
{
get{return_product;}
set{_product=value;}
}
///<summary>
///购买价格
///</summary>
publicdecimalProductPrice{get;set;}
///<summary>
///购买数量
///</summary>
publicintProductQty{get;set;}
#endregion
#region方法
///<summary>
///主算小计金额
///</summary>
///<returns></returns>
publicdecimalGetAmount()
{
returnthis.ProductPrice*Convert.ToDecimal(this.ProductQty);
}
#endregion
} ///<summary>
///商品库存
///</summary>
publicclassInventory
{
#region属性
///<summary>
///键
///</summary>
publicintSysNo{get;set;}
///<summary>
///更新键,用来保证更新的数据之前没有别人更新过。对应表的ModKey列,每更新一次更新Guid值
///</summary>
publicGuidModKey{get;set;}
privateProduct_product=newProduct();
///<summary>
///商品
///</summary>
publicProductProduct
{
get{return_product;}
set{_product=value;}
}
///<summary>
///库存数量
///</summary>
publicintQty{get;set;}
#endregion
#region方法
///<summary>
///验证库存是否有库存
///</summary>
///<returns></returns>
publicboolValidInventory()
{
if(this.Qty>0)
returntrue;
else
returnfalse;
}
///<summary>
///减库存
///</summary>
///<paramname="qty"></param>
publicvoidMinusInventory(intqty)
{
if(this.Qty<qty)
thrownewException("库存不足!");
this.Qty-=qty;
}
#endregion
}
接下来看看我这个伪代码的项目结构。做的很简单,简单明快的架构就是好的架构,不要把架构搞的很复杂。
Domain:领域层,里面放的是领域对象。这个层对其它层没有依赖
Repository:持久层,对领域对象进行持久。里面可以有级存和DB等。这个层依赖Domain
Services:应用程序服务,这个名字喜好着起吧。我们可以把它理解为业务逻辑层,当然这个业务逻辑是对一个功能更粗粒度的API。里面会调用依赖的领域对象进行业务组合达到业务需求。当然对对象的持久也是这里来做的。这个层依赖Domain和Repository
Web:UI层,调用Services进行业务处理,需要ViewModel(VO)我们可以加,我个人比较喜欢按需要创建ViewModel对象,不需要的没必要增加工作量。
基本流程就是
UI调用Serivices创建定单
Services调用Domain对象进行业务组合处理
最后Services调用Repository进行对象的持久
我们从上到下,首先是UI的控制器里面开始。生成定单
publicActionResultAbout(){
//创建定单,生成定单必要数据收货信息,购物车信息等
Orderorder=newOrder();
OrderServiceservice=newOrderService();
service.OrderBuy(order);//定单提交
returnView();
}
然后是Services里面的方法
///<summary>///定单提交
///</summary>
///<paramname="order"></param>
publicvoidOrderBuy(Orderorder)
{
//事务开始
order.OrderAmount=order.GetOrderAmount();//计算订单金额
//更新库存
foreach(variteminorder.OrderItems)
{
Inventoryinventory=InventoryRepository.LoadInventory(item.Product);//取得一个库存对象
inventory.MinusInventory(item.ProductQty);//调用库存调用方法
InventoryRepository.SaveInventory(inventory);//持久更新完的库存
}
OrderRepository.SaveOrder(order);//持久化定单
//事务结束
}
Repository里面的是伪代码,就不发了。
工作呢,写的很粗略。最后说一点,其实面向领域开发通过这些代码是看不出本质的。我在这总结一下。
把你的开发关注点提到类(对象)上来,不要把关注点放到数据库(表)上。
PS:我也是存储过程(业务)反对派
本文共计1675个文字,预计阅读时间需要7分钟。
最近面向领域的知识爆炸,我也来添一把火。说说平时做项目时用到的发展方式,以下为伪代码,主要展示一下我现在的发展方式,供大家讨论。
系统开发中不考慮持續、UI、AOP 和 。
最近面向领域的知识挺火,我也来插一腿。说说我平时做项目时候用到的开发方式,以下代码为伪代码,主要展示一下我现在的开发方式供大家讨论,系统中不考虑持久、UI、AOP和IOC等方面内容。
说到.NET社区的“开发方式”就不得不提一下Petshop了,可以说Petshop真是影响了.NET的一代人。以至于三层成了.NET这边流行的标准的开发方式。但是要说一下Petshop是数据库驱动业务核心的过程式开发,也正是它也毒害了一批人。
下面我们以一个最常见也是大家比较熟的下定单来简单看一下。首先是系统的几个领域类:
应牧章的要求,加上类之间的关系:这里的关系很简单,Order与OrderItem是一对多关系;OrderItem与Product是一对多关系;定单提交业务Order对象是个“根”
我也就不解释了,发下几个类的代码里面有注解。大家看一下就明白了。这里我们要强调的是类关系,还有一个根的概念。每个业务流都会有一个根。而根不是整个系统唯一确定的是而是根据对象在哪个业务范围内而决定的。显然这里面是Order定单对象。
///<summary>///商品
///</summary>
publicclassProduct
{
///<summary>
///键
///</summary>
publicintSysNo{get;set;}
///<summary>
///商品名称
///</summary>
publicstringProductName{get;set;}
///<summary>
///商品价格
///</summary>
publicdecimalProductPrice{get;set;}
privateCategory_category;
///<summary>
///所属分类
///</summary>
publicCategoryCategory
{
get{return_category;}
set{_category=value;}
}
} ///<summary>
///定单
///</summary>
publicclassOrder
{
#region属性
///<summary>
///键
///</summary>
publicintSysNo{get;set;}
///<summary>
///定单ID
///</summary>
publicstringOrderId{get;set;}
///<summary>
///定单金额
///</summary>
publicdecimalOrderAmount{get;set;}
///<summary>
///运费金额
///</summary>
publicdecimalShipAmount{get;set;}
///<summary>
///支付金额
///</summary>
publicdecimalPayAmount{get;set;}
///<summary>
///定单状态
///</summary>
publicintOrderStatus{get;set;}
///<summary>
///定单时间
///</summary>
publicDateTimeOrderTime{get;set;}
privateList<OrderItem>_orderItems=newList<OrderItem>();
///<summary>
///定单明细
///</summary>
publicList<OrderItem>OrderItems
{
get{return_orderItems;}
set{_orderItems=value;}
}
#endregion
#region方法
///<summary>
///计算定单金额
///</summary>
///<returns></returns>
publicdecimalGetOrderAmount()
{
decimalamount=0;
//计算商品金额
foreach(variteminOrderItems)
{
amount+=item.GetAmount();
}
//加上运费
amount+=ShipAmount;
returnamount;
}
#endregion
} ///<summary>
///定单明细
///</summary>
publicclassOrderItem
{
#region属性
///<summary>
///键
///</summary>
publicintSysNo{get;set;}
privateProduct_product=newProduct();
///<summary>
///购买商品
///</summary>
publicProductProduct
{
get{return_product;}
set{_product=value;}
}
///<summary>
///购买价格
///</summary>
publicdecimalProductPrice{get;set;}
///<summary>
///购买数量
///</summary>
publicintProductQty{get;set;}
#endregion
#region方法
///<summary>
///主算小计金额
///</summary>
///<returns></returns>
publicdecimalGetAmount()
{
returnthis.ProductPrice*Convert.ToDecimal(this.ProductQty);
}
#endregion
} ///<summary>
///商品库存
///</summary>
publicclassInventory
{
#region属性
///<summary>
///键
///</summary>
publicintSysNo{get;set;}
///<summary>
///更新键,用来保证更新的数据之前没有别人更新过。对应表的ModKey列,每更新一次更新Guid值
///</summary>
publicGuidModKey{get;set;}
privateProduct_product=newProduct();
///<summary>
///商品
///</summary>
publicProductProduct
{
get{return_product;}
set{_product=value;}
}
///<summary>
///库存数量
///</summary>
publicintQty{get;set;}
#endregion
#region方法
///<summary>
///验证库存是否有库存
///</summary>
///<returns></returns>
publicboolValidInventory()
{
if(this.Qty>0)
returntrue;
else
returnfalse;
}
///<summary>
///减库存
///</summary>
///<paramname="qty"></param>
publicvoidMinusInventory(intqty)
{
if(this.Qty<qty)
thrownewException("库存不足!");
this.Qty-=qty;
}
#endregion
}
接下来看看我这个伪代码的项目结构。做的很简单,简单明快的架构就是好的架构,不要把架构搞的很复杂。
Domain:领域层,里面放的是领域对象。这个层对其它层没有依赖
Repository:持久层,对领域对象进行持久。里面可以有级存和DB等。这个层依赖Domain
Services:应用程序服务,这个名字喜好着起吧。我们可以把它理解为业务逻辑层,当然这个业务逻辑是对一个功能更粗粒度的API。里面会调用依赖的领域对象进行业务组合达到业务需求。当然对对象的持久也是这里来做的。这个层依赖Domain和Repository
Web:UI层,调用Services进行业务处理,需要ViewModel(VO)我们可以加,我个人比较喜欢按需要创建ViewModel对象,不需要的没必要增加工作量。
基本流程就是
UI调用Serivices创建定单
Services调用Domain对象进行业务组合处理
最后Services调用Repository进行对象的持久
我们从上到下,首先是UI的控制器里面开始。生成定单
publicActionResultAbout(){
//创建定单,生成定单必要数据收货信息,购物车信息等
Orderorder=newOrder();
OrderServiceservice=newOrderService();
service.OrderBuy(order);//定单提交
returnView();
}
然后是Services里面的方法
///<summary>///定单提交
///</summary>
///<paramname="order"></param>
publicvoidOrderBuy(Orderorder)
{
//事务开始
order.OrderAmount=order.GetOrderAmount();//计算订单金额
//更新库存
foreach(variteminorder.OrderItems)
{
Inventoryinventory=InventoryRepository.LoadInventory(item.Product);//取得一个库存对象
inventory.MinusInventory(item.ProductQty);//调用库存调用方法
InventoryRepository.SaveInventory(inventory);//持久更新完的库存
}
OrderRepository.SaveOrder(order);//持久化定单
//事务结束
}
Repository里面的是伪代码,就不发了。
工作呢,写的很粗略。最后说一点,其实面向领域开发通过这些代码是看不出本质的。我在这总结一下。
把你的开发关注点提到类(对象)上来,不要把关注点放到数据库(表)上。
PS:我也是存储过程(业务)反对派

