SqlHelper和DBHelper
前言:
還記得剛學ADO.NET的情景麼?
還記得當年是怎麼從ADO.NET被忽悠到用SqlHelper的麼?
話說從入門到走上工作崗位那些年,我們就一直被純純地教導或引導,ADO.NET太原始,得封裝成SqlHelper或DBHelper......
後來,這種思維一直深深就存在腦海裡,並不知不覺中進入了潛意識,形成一種習慣。
在寫框架的前幾年,我也一直延續著這種思維,早期CYQ.Data的原始碼裡,也有Sqlhelper,我也分享過Sqlhelper類的原始碼......
後來框架寫久了,開始對框架的命名有講究了,就默默低調的把Sqlhelper給改名了...
上個月的某一天,我給以前的同事傳授知識時,不自覺的提到這個Helper悖論問題。
今天,無意中看到了這樣的一篇文章,於是覺得可以分享一下自己的觀點了:
文章裡只有一個幫助類的程式碼,這裡只截一小段(這是一段典型的有問題的程式碼,用來給下文當反例用的):
這些年框架寫多了,對物件導向相關的很多定義和使用,在潛意識裡已經自有一套模式,以下分享兩個小點:
1:定義Static變數需要考量的兩個因素:記憶體和併發:
1:定義static變數:意味著該物件從始致終,都存在記憶體中,因此,你需要思考物件可預計或不可預計的大小,是否全域性,若否,需要在何處需要將物件置Null?以便垃圾回收!
2:定義static變數:意思著在(Web)多執行緒環境下必然需要思考:是否有執行緒訪問衝突?問題需要解決?需要Lock嗎?需要雙重判斷?
若寫程式碼時沒有這兩種考量,容易導致static亂用問題。
因此,上面的程式碼對Connection物件定義為static,明顯錯誤有二:
1:資源只能用一個。
2:多執行緒下掛掉或拋異常是必然的,因為共用一個物件(場景如:A操作完Close,B操作到一半發現被Close了,好囧......)。
發現有超過一半的人分不清文章的邏輯,所以加點無敵分隔線,以便後續來者看的簡單些。
----------------------------------以上內容只是引子和分享點知識,和標題要陳述的內容無關--------------------------------
評論的問題在於:
A:只針對引子1去發表意見,而忽視重要的論據2和3,沒有人針對論據2和3去評論?
B:把範圍擴大到Static和Helper去評論,不知道文章說的是sqlHelper或DBHelper,是針對資料庫的麼?
----------------------------------下面的2-3才是針對標題的論據---------------------------------------------------------
2:資料庫操作類不應該為設計為static:
在現實的專案中,資料庫的併發和事務是一件很自然就存在的事情。
因此:
1:併發的存在:意味著資料庫操作類(ADO.NET)物件不能設定為static。(把特意把物件加粗,這裡不是說方法)
2:事務的存在:意味著資料庫操作類不能將方法定義為static。(這裡才是說方法)
因此,資料庫操作類合適的方式,應該設計成例項方式。
進一步補充解釋:
1:透過在static裡方法產生例項,可以避免執行緒問題,但物件不能複用,事務沒法用。
2:把物件提升為引數,外部例項後傳入:能複用物件和事務,但根據業務場景需要不斷增加過載方法,修改方法以適用,所以這種設計也不合理。
比如你需要增加引數來達到複用:執行的時候是否關閉連結、事務是否提交、引數是否清除、DataReader返回的引數過載等N種場景。
再簡化解釋:
1:不該將物件定義為靜態(這個1的引子可見)
2:不該方法定義為static(因為要操作事務共享,進一的論據是場景會引發過載過多,導致設計不合理)
如果還是看不懂。。。多看幾遍吧,這裡是重要的論據。
3:關於XXXHepler或XXXUtility的思維定義:
我們可以用Reflector在微軟的內庫裡搜Helper或Utitliy結尾定義的類,可以隨便挑著看:
結論都一個樣:
1:這個類應該是個幫助類或定義為static類。
2:內部應該(或大部分)是靜態方法。
悖論出來了:
我在園子裡掃了一下,發現大部分的SqlHelper類或DbHelper在經過專案的實戰後,都知道該轉成例項方式提供。
可是,既然都轉成了例項,為啥還叫SqlHelper或DbHelper???
應該改名的!
為啥?為啥?為啥不改名呢?(那是我們從小就被教壞了。。。)
因果論:
因為:資料庫操作設計不應該為Static,同時Helper字尾的不該設計為例項類。
所以:在資料庫操作類設計裡,SqlHelper和DBHelper不該存活。
總結:
過程很友善,結論很無情!
世事無絕對,存在即合理,人生的理由除了應不應該,還有喜不喜歡,值不值得,習不習慣,所以,樓下都在為它找一個合理存在的理由。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/430/viewspace-2803570/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- .NET中封裝SqlHelper封裝SQL
- c#封裝DBHelper類C#封裝
- 分享一個自己寫的C# SqlHelperC#SQL
- sqlhelper整合dynamic多資料來源的分頁問題(非教學向)SQL
- 路徑中./和../和/
- ../和./和/的區別
- not in 和 not exists 比較和用法
- xftp和xshell,xftp和xshell的下載和安裝FTP
- #和&
- !=和<>
- ABAP和Java的destination和JNDIJava
- @NotEmpty和@NotBlank和@NotNull小結Null
- 字首和與二維字首和
- ♻️同步和非同步;並行和併發;阻塞和非阻塞非同步並行
- XML基本操作-建立(DOM和LOINQ)和LINQ查詢和儲存XML
- workman 和swoole 區別 和異同
- 寬鬆相等和嚴格相等(==和===)
- 淺談mouseenter和mouseover,mouseout和mouseleave
- csv和excel讀取和下載Excel
- Cookie 和 Session 關係和區別CookieSession
- javafx 和swing_整合JavaFX和SwingJava
- 檔案路徑問題( ./ 和 ../ 和 @/ )
- 堆和棧的概念和區別
- ThymeleafViewResolver和SpringTemplateEngine和SpringResourceTemplateResolver的關係ViewSpring
- 尤拉計劃739:和的和
- 【-Flutter/Dart 語法補遺-】 sync* 和 async* 、yield 和yield* 、async 和 awaitFlutterDartAI
- if if和if else if
- ul和
- 字首和
- equals 和 ==
- Redis RDB和AOF取捨和選擇Redis
- ssr、ss和vpn介紹和區別
- 使用Jquery和JSON的州和城市列表jQueryJSON
- VM和Container 虛擬機器和容器AI虛擬機
- 和AI談倫理、道德和謊言AI
- 堆和棧的解釋和區別
- lodsb、stosb(和lodsw、stosw和lodsd、stosd指令)
- vue和react的相同點和不同點VueReact