最近,公司開發了一個檔案產品,實現兩種數據庫(SQL Server 和 Oracle)的數據存儲,我雖然沒有進行此項目的開發,但是本着學習的動機,也開始思考這個項目如果交給我,我會如何去做(考慮用最少的代碼和最少的時間去開發,保障程序運行效率)。
因為之前學習過設計模式,第一反應就是工廠模式與抽象工廠模式可以實現這個需求(但運用的太少,學習的也不是很深奧,因此重新學習,希望各位一起討論)。
按照個人的理解,面向對象的設計語言有三大機制:封裝、繼承、多態。前兩個特征都比較好理解,這里不解釋說明了。那什么是多態?我的理解是 :多態(Polymorphism)--》通過繼承實現的不同對象調用相同的方法,表現出不同的行為,稱之為多態。如果說不明白,可以舉一個例子,請看下圖。
從編程角度出發,狗(Dog)是個抽象類,狗都有跑的屬性,但跑的快慢是有差異的。貴賓犬和獵狗是個實體類,是具體的狗,他們都繼承了狗會跑的性質。
如果用代碼表示,可以這樣
Dog dog=new 貴賓犬() 或者 Dog dog=new 獵狗();
當我們給狗這個抽象類一個具體的實例時,狗的跑動快慢是不同的。這就是多態的表現方式之一,不知道我說的是否明白?。
那么,什么是設計模式?這真的很抽象,太抽象了。經過努力,找到了下面一段話(覺得比較通俗易懂):
設計模式描述了軟件設計過程中某一類常見問題的一般性的解決法案。面向對象設計模式描述了面向對象設計過程中,特定場景下、類與相互通信的對象之間常見的組織關系。
個人理解如果項目沒有太大需求的變化,是不需要使用設計模式,或者說不需要面向對象設計,雖然我們使用的C#、Java都是面向對象語言,但通常我們的編程習慣與面向過程的編寫習慣沒有太大的差別(理解錯誤請指正)。
記得在讀大學學習軟件工程的時候,老師給我們講課,總愛提起耦合這個名詞,當時沒怎么去理解,覺得這些理論沒什么用處,而現在逐漸有了清晰的認識。
耦合關系直接決定着軟件面對變化時的行為,即模塊與模塊之間的緊耦合使得軟件面對變化時,相關的模塊都要隨之更改,模塊與模塊之間的松耦合使得軟件面對變化時,一些模塊更容易被替換或者更改,使其他模塊保持不變。
這段理論中,模塊與模塊的耦合度到底要多松,才是合適的,是一個值得商榷的地方,值得我思索。
一個產品中,可能用到幾種模式,或者一種模式都未用。人們會說,為了模式而去用模式不好,深刻理解面向對象是學好設計模式的繼承。
學習Factory Method,應該有這樣的疑問:為什么會有這個模式,這個模式是來用來干什么的,這個模式是什么,使用這個模式要注意什么。
動機:在軟件系統中,經常面臨着“某個對象”的創建工作,由於需求的變化,這個對象經常面臨着劇烈的變化,但是它卻擁有比較穩定的接口。
意圖:定義一個用於創建對象的接口,讓子類決定實例化哪一個類(GOF)。
一個類是變化的,但這個類擁有穩定的接口,什么是穩定的接口,怎樣才算是穩定的接口,希望各位解釋下。
下面是我的思考過程,希望各位拍磚。
首先分層編寫,必然之道;其次,數據庫不同,實際是sql server 和 oracle的一些語法差別不同,比如占位符,sql server 是@,oracle是:,數據庫的幫助類SQLHelpe也是不同的,因此,我就從SQLHelper這里下手。
首先建立兩個類,分別代表操作Sql和操作Oracle數據的類。
操作Sql數據庫的類SqlDBHelper
1 public class SqlDBHelper
2 { 3 static readonly string conStr = ConfigurationManager.ConnectionStrings["conStr"].ConnectionString; 4 public DataTable GetDataTable(string sql, params OracleParameter[] param) 5 { 6 using (SqlConnection con = new SqlConnection(conStr)) 7 { 8 con.Open(); 9 using (SqlCommand cmd = con.CreateCommand()) 10 { 11 cmd.CommandText = sql; 12 if (param != null) 13 { 14 cmd.Parameters.AddRange(param); 15 } 16 using (SqlDataAdapter adapert = new SqlDataAdapter(cmd)) 17 { 18 DataTable sqlDt = new DataTable(); 19 adapert.Fill(sqlDt); 20 return sqlDt; 21 } 22 } 23 } 24 } 25 }
操作Oracle數據庫的類 OracleDbHelper
1 public class OracleDbHelper:
2 { 3 static readonly string conStr = ConfigurationManager.ConnectionStrings["conStr"].ConnectionString; 4 public DataTable GetDataTable(string sql, params SqlParameter[] param) 5 { 6 using (OracleConnection con = new OracleConnection(conStr)) 7 { 8 con.Open(); 9 using (OracleCommand cmd = con.CreateCommand()) 10 { 11 cmd.CommandText = sql; 12 if (param != null) 13 { 14 cmd.Parameters.AddRange(param); 15 } 16 using (OracleDataAdapter adapert = new OracleDataAdapter(cmd)) 17 { 18 DataTable oraclelDt = new DataTable(); 19 adapert.Fill(oraclelDt); 20 return oraclelDt; 21 } 22 } 23 } 24 }
當數據庫是SQL Server的時候,調用SqlDBHelper的方法GetDataTable(),當數據庫是Oracle的時候,我調用OracleDbHelper的GetDataTable()方法。因此,這里需要寫兩種不同的數據操作類,我覺得不是太好。經過尋找,我在net自帶的類中找到了一種方法,這樣,程序員在數據層中調用數據庫操作類的時候不用去判斷調用是SqlDBHelper還是OracleDbHelper了,請看我的下一篇博文。