商務邏輯層,也可以叫業務實體層,就是由各個業務實體構成的。
同志們可以參考Pet Shop40的商務邏輯層,裡面都是諸多實體,舉一個例子products:
using System.Collections.Generic;
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的測試驅動一個道理,先寫好用戶端代碼的目的是讓你清晰你所要構建的實體它的表現應該是什麼樣子的。這種從上往下的設計,看似倒置,其實是反本回源,才是正確的設計方法。
當然你說了,用戶端代碼使用的習慣每個人寫出來還不一樣呢。那我說,其實這沒有什麼絕對,設計一個實體就是要設計的讓它越友好使用起來越順手越好,按照這樣去實現你的設計吧。