一、简介
为了保证软件实现的简洁性,并且与模型保持一致,不管实际情况有多复杂,必须使用建模和设计的最佳实践,即让通过我们的编程技术(设计模型、指责驱动、契约式设计)充分地体现领域模型,并保持模型地健壮性和可扩展性,而不是单单地实现模型.某些决策设计能和模型紧紧地结合,这种结合要求我们注意每个元素地细节.
开发一个好的领域模型是一门艺术,而模型中的各个元素的实际设计和实现则相对系统化,将领域设计(也可以是软件系统中的其他关注点)与软件系统中的其他关注点(也可以是领域设计)分离使整个领域模型非常的清晰.根据不同模型的指责(特性)会使元素的意义更加鲜明.
二、实战
上图展示的模型驱动设计的基本构造块,当然实际开发中可能不止这些内容,可能还会有施加在实体上的一些契约还有一些特殊的计算规则、可能还有有一些复杂的实体运算,这些运算可能还需要使用一些设计模式去设计等等.但这个基本的构造.
下面通过C#代码来实现一个简单的用户订单计价系统,如下:
项目结构如下:
代码如下:
////// 用户聚合根 /// public class UserAggregate { /// /// 抽象的用户 /// public AbstractUser AbstractUser { get; set; } }
////// 抽象的用户,里面定义用户的基本属性 /// public abstract class AbstractUser { /// /// 值对象 /// public abstract string UserName { get; set; } /// /// 值对象 /// public abstract int Age { get; set; } /// /// 值对象 订单价格 /// public abstract double OrderPrice { get; set; } }
////// 计价策略类,具体的计算规则,随着业务的变化,可已重新实现 /// public class UserPriceAggregateStartegy : IUserPriceAggregateStartegies { public double CalculatePrice(UserAggregate user) { double totalfee = 0; if (user.AbstractUser is WxUser) { //这里具体的优惠尺度可以去读取配置文件 totalfee=user.AbstractUser.OrderPrice * 0.8; } else if (user.AbstractUser is NormalUser) { totalfee=user.AbstractUser.OrderPrice; } return totalfee; } }
////// 普通用户 /// public class NormalUser : AbstractUser { public override string UserName { get; set; } public override int Age { get; set; } public override double OrderPrice { get; set; } }
////// 微信用户 /// public class WxUser: AbstractUser { public override string UserName { get; set; } public override int Age { get; set; } /// /// 微信用户的OpenId /// public string OpenId { get; set; } /// /// 值对象 订单价格 /// public override double OrderPrice { get; set; } }
////// 用户计价聚合根约束 /// public interface IUserPriceAggregateFactory { UserAggregate CalculatePrice(IUserPriceAggregateStartegies startegies); }
////// 用户聚合根工厂,按照计价策略生成对应的用户实体,这个类会暴露给外面的业务结构使用 /// 将业务逻辑的处理交给工厂类,这样做的好处,是减轻控制器的压力,也符合领域驱动设计的理念 /// public class UserPriceAggregateFactory: IUserPriceAggregateFactory { private UserPriceAggregateFactory() { } private UserAggregate _userAggregate; public UserPriceAggregateFactory(UserAggregate userAggregate) { _userAggregate = userAggregate; } public UserAggregate CalculatePrice(IUserPriceAggregateStartegies startegies) { var price=startegies.CalculatePrice(_userAggregate); _userAggregate.AbstractUser.OrderPrice = price; return _userAggregate; } }
控制台调用代码如下:
class Program { static void Main(string[] args) { //拿到用户的输入 var normalUser = new WxUser() { UserName = "小超", Age = 23, OrderPrice = 6 }; //组成业务聚合根 var aggregare = new UserAggregate() { AbstractUser = normalUser }; //生成用户计价类型的聚合根 var user = new UserPriceAggregateFactory(aggregare); //生成具体的计价类型 var startegy = new UserPriceAggregateStartegy(); //生成计价过后的业务聚合根 var priceUser = user.CalculatePrice(startegy); //随后将经过业务计算后的聚合根通过仓储初始化到数据库中 //.....省略 Console.WriteLine("当前用户的订单价格为:{0}", priceUser.AbstractUser.OrderPrice); Console.ReadKey(); } }
根据上面的代码可以得出一个基本的领域模型,如下:
注意下图
这个过程可以随意组合,可以通过Facade模式,组合多种策略,然后施加到用户聚合根上,得到最终的聚合根