閱讀目錄:數據庫
要想正確的設計系統架構就必須能正確的搞懂每一個架構模式的用意,而不是鬍子眉毛一把抓。如今有一個現象是什麼呢,項目的結構從表面上看是很不錯,層分的很合理,其實對業務系統來講也就那麼幾種層設計方法,可是如今不少項目的邏輯架構的設計不是理想,有不少概念你們並非很瞭解,固然也許每一個人對技術的追求不一樣罷了。無論你追求不追求,事實咱們仍是要去往正確的方向努力纔對的。架構
不少人包括我本身在內,都是寫過不少年的過程式的代碼,層對我當年來講就是個擺設而已,最典型的問題就是咱們老是將表模塊模式和事物腳本模式一塊兒混着使用,什麼意思呢,就是說咱們都會使用一些代碼生成器來根據數據庫中的表來生成三層架構中的業務層和數據層,有些比較好的代碼生成器也能夠幫你把UI層中的部分視圖也生成好,確實很強大,有些場合下這是一中最合適的過程。學習
可是如今的系統已經不在是那樣的了,其中重要的一點就是業務複雜了,若是咱們還稀裏糊塗的編寫着代碼,最後只會成爲你或者團隊的技術債務。spa
咱們簡單瞭解一下這裏所謂的「表模塊模式、」事務腳本模式「究竟是什麼樣子的模式,最關鍵是你也許就知道了你目前所使用的業務層架構風格是什麼模式,強調一下「表模塊模式」、「事物腳本模式」都是業務層的構架模式。設計
表模塊模式:code
簡單講就是你數據庫中的每一個表對應着業務層中的一個對象定義,若是你有一個Product表,那麼你在Business Layer中就有一個Product.cs文件,固然這不是絕對的,你也能夠將庫中的視圖也定義一個類型,如,OrderProduct.cs,也是能夠的。而後每一個類中的所處理的邏輯都是跟這張表相關的,你在Product.cs中的代碼就不要包含Order.cs中的代碼了。目前來看是有的,由於如今大部分的項目都是在寫着使用過程式的代碼,也就是事物腳本模式,這樣不免會將其餘類型中的代碼寫到本類中。對象
事物腳本模式:blog
事務腳本模式就是過程式的代碼,只不過它的指標就是每個代碼段獨立完成一個業務單元,而不是處處都是過程代碼,事物腳本模式仍是很強調邏輯的統一性的。隊列
使用此模式進行寫代碼時,你就不要單純的使用數據庫中的表名來定義業務類了,由於你是使用事務腳本模式的,你須要站在業務角度來規劃你的業務層中大概包含哪些業務概念,而後使用這個業務概念來命名你的類。好比:UserOrder,UserOrder,相似這樣的定義,固然這裏只是個假設而已,你不要站在數據庫的腳原本設計業務層就好了,這樣你就起碼不會使用到很細粒度的類型,哪怕下一次迭代進行重構也是能夠的。事務
這篇文章的重點就是本節,咱們將瞭解一下這兩種模式的代碼到底該如何編寫。
說代碼如何編寫彷佛有點讓人以爲不是很禮貌,其實咱們大部分的代碼寫的都是正確的,可是若是咱們將有些代碼稍微的羅一下位置就會明顯不同。
咱們來看一個小例子,例子很簡單,有兩個類型Order、Product,用來完成通常的業務邏輯處理,咱們經過不一樣的模式來看到底如何使用。
如今的事務腳本模式的代碼:
namespace Business { public class Order { [Serializable] public class OrderField { public string OId { get; set; } [NonSerialized] public List<Product.ProductField> Products { get; set; } } public OrderField Field { get; set; } public void AddOrder(OrderField orderField) { var sendMQOrders = new List<string>();//合格的產品ID集合 orderField.Products.ForEach(product => { if (product.Price <= 20)//不知足條件 return; sendMQOrders.Add(product.PId);//知足條件 }); MqHelper.SendOrder(orderField, sendMQOrders);//發送訂單數據實體到隊列中 } } }
Order業務類中有一個添加Order的方法,在該方法中是一些簡單的業務邏輯處理,判斷了要添加的這個商品的價格是否大於20塊錢。最後使用過濾下來的商品ID做爲本訂單的有效產品。
這就是咱們目前使用的代碼風格,這裏有兩個問題,第一:類的命名,Order的概念太大了,沒有進行細化,顯然不是按照事務腳本模式來進行設計的而是按照表模塊方式進行劃分的,還有若是我就算你是按照事物腳本模式來設計的,我就喜歡定義大的概念難道不對嗎?也能夠,可是在Order的定義裏面明確使用了Product類型下的子類型,也就說這裏出現了兩個獨立的業務範圍,正常的理解確定是按照表模塊模式來設計的。第二:若是是按照表模塊模式來設計的,由於根據這個對象的命名很明顯是此模式,可是仔細閱讀一下代碼發現職責仍是有點不清晰,在Order.AddOrder(OrderField orderField)方法中,有Product的邏輯在裏面if (product.Price <= 20),固然這裏是業務邏輯比較簡單的狀況下的,若是是業務比較複雜的時候,就會出現大量的代碼在Order類中,到最後就會發現咱們已經分不清此業務架構究竟是使用何種模式來設計的。
咱們有兩個作法,第一個作法是:將其改爲事務腳本模式,讓類的命名和設計泛化,也就是說不要定義那麼明顯的數據庫中的表名字,不要清晰的區分Order和Product兩個職責。第二個作法是:將其改爲表模塊模式,將每一個類型中的業務邏輯徹底清晰化,將if (product.Price <= 20)提取到Product業務類中去,而後在應用控制器中先處理此邏輯後在調用Order.AddOrder(OrderField orderField)方法進行處理,這個方法裏面只作跟當前類型相關的邏輯,參考的依據就是一旦你發現你所寫的代碼裏出現了別的類型時,此時你應該告訴本身有可能這個地方須要重構職責。
兩個方法來移動此邏輯:
1:(將if (product.Price <= 20)封進Price屬性中)
namespace Business { public class Order { [Serializable] public class OrderField { public string OId { get; set; } [NonSerialized] public List<Product.ProductField> Products { get; set; } } public OrderField Field { get; set; } public void AddOrder(OrderField orderField) { var sendMQOrders = new List<string>();//合格的產品ID集合 orderField.Products.ForEach(product => { if (product.Price.IsValid()/*執行價格判斷*/) return; sendMQOrders.Add(product.PId);//知足條件 }); MqHelper.SendOrder(orderField, sendMQOrders);//發送訂單數據實體到隊列中 } } }
此方法有個問題就是商品的價格沒有收到訂單的控制,這看具體的業務須要了,我只是個假設。
2:徹底獨立的過濾無效產品的方法
namespace Business { public class OrderApplicationController { public void SubmitOrder(Order.OrderField field) { field.Products = new Product().FilterProduct(field.Products);//先過濾 new Order().AddOrder(field);//在添加 } } }
咱們先調用Product中的業務方法過濾無效的商品,而後在進行訂單添加操做,這樣咱們就將各自的職責放到本身的位置去。
仍是那句話,這只是我學習過程當中的一點小小的領悟,給你們一個參考的資料,但願對你有用,謝謝。