[英]should I make this class static?
在我工作的項目中,我有查詢/更新數據庫的類,就像這個,
public class CompanyInfoManager
{
public List<string> GetCompanyNames()
{
//Query database and return list of company names
}
}
隨着我不斷創建越來越多的這類類,我意識到也許我應該使這種類靜態 。 通過這樣做,顯而易見的好處是避免每次需要查詢數據庫時都需要創建類實例。 但是因為對於靜態類,只有一個類的副本,這會導致數百個請求只爭用一個靜態類的副本嗎?
謝謝,
我不會使該類靜態,而是使用依賴注入並將所需的資源傳遞給該類 。 這樣您就可以創建一個模擬存儲庫(實現IRepository接口)來進行測試。 如果你使類靜態並且沒有傳入你的存儲庫那么它很難測試,因為你無法控制靜態類連接的內容。
注意:下面的代碼是一個粗略的例子,僅用於表達這一點,不一定是編譯和執行。
public interface IRepository
{
public DataSet ExecuteQuery(string aQuery);
//Other methods to interact with the DB (such as update or insert) are defined here.
}
public class CompanyInfoManager
{
private IRepository theRepository;
public CompanyInfoManager(IRepository aRepository)
{
//A repository is required so that we always know what
//we are talking to.
theRepository = aRepository;
}
public List<string> GetCompanyNames()
{
//Query database and return list of company names
string query = "SELECT * FROM COMPANIES";
DataSet results = theRepository.ExecuteQuery(query);
//Process the results...
return listOfNames;
}
}
要測試CompanyInfoManager:
//Class to test CompanyInfoManager
public class MockRepository : IRepository
{
//This method will always return a known value.
public DataSet ExecuteQuery(string aQuery)
{
DataSet returnResults = new DataSet();
//Fill the data set with known values...
return returnResults;
}
}
//This will always contain known values that you can test.
IList<string> names = new CompanyInfoManager(new MockRepository()).GetCompanyNames();
關於依賴注入,我不想絮絮叨叨。 Misko Hevery的博客詳細介紹了一篇很棒的文章,以便開始使用 。
這取決於。 你需要讓你的程序多線程嗎? 您是否需要連接到多個數據庫? 你是否需要在這堂課中存儲州? 您需要控制連接的生命周期嗎? 您將來需要數據緩存嗎? 如果您對其中任何一個回答“是”,則靜態類會使事情變得尷尬。
我個人的建議是將它作為一個實例,因為這是更多的OO,並將為您提供將來可能需要的靈活性。
你必須小心使這個類靜態。 在Web應用程序中,每個請求都在其自己的線程上處理。 如果不小心,靜態實用程序可能是線程不安全的。 如果發生這種情況,你就不會幸福。
我強烈建議你遵循DAO模式。 使用像Spring這樣的工具讓你輕松上手。 您所要做的就是配置數據源,您的數據庫訪問和事務將變得輕而易舉。
如果你去靜態課程,你將不得不設計它,使其基本上無國籍。 通常的策略是創建一個具有公共數據訪問功能的基類,然后在特定的類中派生它們,比如加載客戶。
如果對象創建實際上是整個操作的開銷,那么您還可以查看池化預先創建的對象。 但是,我非常懷疑是這種情況。
您可能會發現許多常見的數據訪問代碼都可以構建為靜態方法,但是所有數據訪問的靜態類似乎都在某處丟失了設計。
靜態類本身對多線程訪問沒有任何問題,但顯然鎖和靜態或共享狀態是有問題的。
通過使類靜態,您將有一個艱難的時間單元測試它,因為您可能必須以非清晰的方式在內部管理連接字符串的讀取,通過從類配置文件中讀取它或從管理這些常量的某個類請求它。 我寧願以傳統方式實例化這樣一個類
var manager = new CompanyInfoManager(string connectionString /*...and possible other dependencies too*/)
然后將其分配給全局/公共靜態變量,如果這對於類有意義,即
//this can be accessed globally
public static CompanyInfoManager = manager;
所以現在你不會為單元測試犧牲任何靈活性,因為所有類的依賴都是通過它的構造函數傳遞給它的
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.