业务逻辑层的设计(一)——逻辑是谁的职责
如何让一些业务逻辑重用
有很长一段时间,我的业务逻辑代码遍布在整个项目代码的任何角落,也同时在操作ADO.NET调用代码的中见缝插针,但我相信这是从一个程序员走向设计师必定要踩过的坑。
有个简单的需求是这样的。你需要新增一张订单,订单中包含几个项,所以你在新增订单的同时连同它包含的所有项都保存进数据库。
Order、OrderItem显然是领域模型,而且它们之间是一对多关系。
public class Order { private IList<OrderItem> _orderItems = new List<OrderItem>(); public virtual IList<OrderItem> OrderItems { get { return _orderItems; } set { _orderItems = value; } } public virtual string Name { get; set; } } public class OrderItem { public virtual string ItemName { get; set; } }
规则验证
加入了订单名称的长度限制。
public class Order { private string _name; private IList<OrderItem> _orderItems = new List<OrderItem>(); public virtual IList<OrderItem> OrderItems { get { return _orderItems; } set { _orderItems = value; } } public virtual string Name { get { return _name; } set { if (value.Length <= 0 && value.Length > 25) { throw new IndexOutOfRangeException("订单名称必须在0-25个字符以内"); } _name = value; } } public bool IsValid { get { if (Name.Length <= 0 || Name.Length > 25) { return false; } return true; } } public string Vali() { StringBuilder builder = new StringBuilder(); if (!this.IsValid) { if (Name.Length <= 0 || Name.Length > 25) { builder.AppendLine("订单名称必须在0-25个字符以内"); } } return builder.ToString(); } }
下面来模拟一下实际调用验证
[Test] public void TestVali() { Ordere order = new Ordere(); order.Name = ""; if (!order.IsValid) { //Name长度为0显然不合法,这里果断没有通过验证。 Console.WriteLine(order.Vali()); //Vali方法让我们知道了验证没有通过的原因 //订单名称必须在0-25个字符以内 //Expected: True //But was: False } Assert.AreEqual(false, order.IsValid); }
实际使用当中,其实完全可以引入微软企业库5.0的验证模块,利用特性来取代手动编写Vali方法的内容。
填充业务逻辑
例子中的业务比较简单,
实践中,我经常遇到一种流程控制的业务逻辑,
比如:
我在流程1要提交,必须要当前进度处于流程状态1,
我在流程1要撤销提交,必须要当前进度处于流程状态2(已提交)
这个业务整在领域模型里面,可以避免散落各处,
当我需求修改为:
流程1要提交,必须要当前进度处于流程状态1或7,只需要修改一处即可,减少了各处修改出错的可能。