今天看了實戰項目分析一文,對文中有些觀點頗為不解。雖然很多園友都說不錯.看了原文,作者提出的項目問題,自己的比較下自己平時做的項目,居然很多都一樣,心哇涼哇涼水的,難道以前自認為不錯的項目都是些垃圾嗎?與高手做的項目就差這麼遠嗎?仔細想下,總覺的說的讓人不服,不服的原因並不是作者寫的不好,而是本人不理解而已.
疑問一:分層架構中的面向介面
引用原文:
----------------------------------------
a.下層對上層隱藏細節,只暴露介面。再此,本應屬於商務邏輯層的業務對象被暴露到了展現層。
b.上層對下層不可見。即下層不知道上層的存在,只提供介面。這裡商務邏輯層的業務對象被資料存取層操作,會導致兩個層之間糾纏不清,以至於會出現改動商務邏輯會影響資料存取方式的荒謬現象。另外,強型別DataSet也有同樣的問題(本應是屬於資料存取層的,卻被傳遞到商務邏輯層,甚至是展現層) 本應是屬於資料存取層的,卻被傳遞到商務邏輯層,甚至是展現層.
舉一個簡單的例子:本系統中商務邏輯層會調用資料存取層的方法,得到一些資料。比如調用一個PartnerAccess類的GetPartner的方法。PartnerAccess是資料存取層的一個具體類,負責Patrner表的所有增刪改查操作。而商務邏輯層到處充斥著這樣的文法:PartnerAccess partnerac = new PartnerAccess();partnerac.getPartner();
這就是一個典型的依賴於具體實現的方案。這樣的後果是,商務邏輯層知道每一個資料表的資料結構,甚至是無需知道的細節,並且對資料層的每一個方法都了如指掌,到處都在使用。當我們開始修改PartnerAccess的其中一個方法的時候(比如增加一個參數)都要修改商務邏輯層的相關代碼,但誰知道那些代碼都在哪呢?只好重新編譯吧,讓編譯器告訴我們。而面向介面編程可以使我們避免這種問題。我們不再依賴於千千萬萬個PartnerAccess或者什麼別的Access類,而是依賴一個IDataAccess的介面。這樣,所有的資料存取都被標準化,我們的調用代碼便的更簡單,不會依賴任何資料庫的結構,甚至不需要知道表的名字,有多少個欄位等等。當我們增加一個OrderAccess類時,只需在資料存取層增加一個檔案,一個類就好了,而不需要更改商務邏輯層的任何代碼。
----------------------------------------
按照作者所說的情況,我寫了一個類似實現的DEMO。這個DEMO就按作者的意思面向介面,不知道是否完全符合.
資料存取層有一個類PartnerAccess,和一個介面IDataAccess
IDataAccess:
Code
public interface IDataAccess
{
IList<string> getPartner();
}
PartnerAccess:
Code
/**//// <summary>
/// 負責Patrner表的所有增刪改查操作
/// </summary>
public class PartnerAccess : IDataAccess
{
/**//// <summary>
/// 取得所有合作者的姓名
/// </summary>
/// <returns>合作者記錄集</returns>
public IList<string> getPartner()
{
//方便說明問題,就省略資料庫取記錄的操作了.
IList<string> _list = new List<string>();
for (int i = 1; i < 100; i++)
{
//加入99個合作者的姓名
_list.Add(i.ToString());
}
return _list ;
}
}
商務邏輯層會調用資料存取層的方法,得到一些資料,這裡我構造了一個類:Partner_BLL
Code
/**//// <summary>
/// 負責Patrner表的所有增刪改查操作
/// </summary>
public class Partner_BLL
{
/**//// <summary>
/// 取得所有合作者的姓名
/// </summary>
/// <returns>合作者記錄集</returns>
public IList<string> getPartner()
{
//調用資料層中的相關類完成資料的讀取操作
IList<string> _list = new List<string>();
IDataAccess _Parter = new PartnerAccess();
_list = _Parter.getPartner();
return _list ;
}
}
這樣的代碼真的可以做到一個層的變化不會引起另一層的變化嗎?
面向介面,介面並不是光定義就行的,它也要有具體的類去實現它,既然有了實現的類,那就會必然會存在一定的耦合。例如都在一個介面IDataAccess,當你選擇用PartnerAccess類的時候,上面商務邏輯的IDataAccess就會變IDataAccess _Parter = new PartnerAccess();當使用OrderAccess類時就會變成:IDataAccess _Parter = new OrderAccess();
無論你怎麼面向介面,商務邏輯層也是要修改代碼的,除非你採用原廠模式來實現。話又說回來了,就是採用原廠模式它也是要修改工廠類的。並不能說修改一個層就一切OK。
當我們開始修改PartnerAccess的其中一個方法的時候,是否會引起商務邏輯層的修改,不在於是否面向介面,而在於你如何修改,如果你的方法中修改了參數,那即使面向介面的話,也是要修改介面,以及具體的實作類別,如果是不影響方法重載的情況下,當然可以.
疑問二:強型別的DataSet為什麼不能在層與層之間傳遞呢?
引用原文
--------------------------------------
本應是屬於資料存取層的,卻被傳遞到商務邏輯層,甚至是展現層
--------------------------------------
記錄集如果不傳遞的話,那最終UI層是如何取得資料存取層的記錄集的呢?本人不才,實在不解。
我總覺的把對象在層與層之間傳遞與系統架構關聯起來特別牽強.
總結:一說到系統架構,一般都是大師層級的人來做的事,做為只涉及.net皮毛的程式員來說在這胡說八道可能有點不妥,但大師也是從精通人過來的,適當的參與一下也不為過. :) ,面向介面的強大是不用說的,但並不是萬能的,適當的面向介面才能發揮最大的作用。系統設計也是要有度的。本文並不是說面向介面不好,只是針對原文有點想法而已。本文只代表個人意見,並沒有針對原文作者文章的意思,純屬技術溝通,如有不妥望諒解。