业务逻辑层,也可以叫业务实体层,就是由各个业务实体构成的。
同志们可以参考Pet Shop40的业务逻辑层,里面都是诸多实体,举一个例子products:
using PetShop.Model;
using PetShop.IDAL;
namespace PetShop.BLL {
/// <summary>
/// A business component to manage products
/// </summary>
public class Product {
// Get an instance of the Product DAL using the DALFactory
// Making this static will cache the DAL instance after the initial load
private static readonly IProduct dal = PetShop.DALFactory.DataAccess.CreateProduct();
/// <summary>
/// A method to retrieve products by category name
/// </summary>
/// <param name="category">The category name to search by</param>
/// <returns>A Generic List of ProductInfo</returns>
public IList<ProductInfo> GetProductsByCategory(string category) {
// Return new if the string is empty
if(string.IsNullOrEmpty(category))
return new List<ProductInfo>();
// Run a search against the data store
return dal.GetProductsByCategory(category);
}
/// <summary>
/// A method to search products by keywords
/// </summary>
/// <param name="text">A list keywords delimited by a space</param>
/// <returns>An interface to an arraylist of the search results</returns>
public IList<ProductInfo> GetProductsBySearch(string text) {
// Return new if the string is empty
if (string.IsNullOrEmpty(text.Trim()))
return new List<ProductInfo>();
// Split the input text into individual words
string[] keywords = text.Split();
// Run a search against the data store
return dal.GetProductsBySearch(keywords);
}
/// <summary>
/// Query for a product
/// </summary>
/// <param name="productId">Product Id</param>
/// <returns>ProductInfo object for requested product</returns>
public ProductInfo GetProduct(string productId) {
// Return empty product if the string is empty
if(string.IsNullOrEmpty(productId))
return new ProductInfo();
// Get the product from the data store
return dal.GetProduct(productId);
}
}
}
注意业务逻辑层使用数据访问层都是使用一个接口,这一点不难理解,我们数据访问层的实现可能是多样的,Petshop里就提供了Oracle和SQLServer 两种不同的实现。可是怎么样都不会影响到逻辑层,这就是面向接口编程的威力。
ProductInfo是Model,它跨越多层。其他的代码没什么好说的了。
可以纵观全局的看一下,这个业务逻辑层其实是构建好了许多系统中可能使用的业务实体,客户端代码直接使用的就是这些业务实体,就是我们模式中的砖块和木料。至于说下面的数据访问层其实和我们需要的系统是没有什么关系的,今天也许我们使用的是关系数据库,所以构建业务实体需要访问层的SQL语句来构建,明天如果是面向对象的数据库呢,我们真的可以省掉这个访问层,所以数据访问层不是一成不变的,而业务逻辑却是不变的。
好的,再说一下构建业务实体的我认为的好方法,是寻找系统中的名词吗? 也不绝对,有些名词也许不值得为其构建实体。我的方法是,先写好客户端使用这些业务实体的代码(当然这时还是伪代码),与Martin的测试驱动一个道理,先写好客户端代码的目的是让你清晰你所要构建的实体它的表现应该是什么样子的。这种从上往下的设计,看似倒置,其实是反本回源,才是正确的设计方法。
当然你说了,客户端代码使用的习惯每个人写出来还不一样呢。那我说,其实这没有什么绝对,设计一个实体就是要设计的让它越友好使用起来越顺手越好,按照这样去实现你的设计吧。