[英]Static factory method vs public constructor
背景:
這是我目前正在處理的代碼。 首先,基類是一個帳戶類,其中包含有關帳戶的信息並具有一些方法,這些方法在大多數情況下會更改類的屬性的值。
public class Account {
private string _username; [...]
public string Username { get { return _username; } } [...]
public Account() { }
public Account(string[] args) { [...] }
public virtual void ChangePassword(string newPassword) { [...] }
}
然后,我有另一個用於創建帳戶的類,我將其命名為ActiveAccount。 這包含了我要用於帳戶的操作的大多數邏輯,這些邏輯只有在創建帳戶后才可能執行。 無需包括某些類來解釋該問題。 用您的想象力假設這些課程可以做什么:
public class ActiveAccount : Account
{
private List<Conversation> _conversations; [...]
public List<Conversation> Conversations { get { return _conversations; } } [...]
private ActiveAccount() { }
public static ActiveAccount CreateAccount(Account account)
{
// Navigate to URL, input fields, create account, etc.
}
public override void ChangePassword(string newPassword)
{
// Navigate to URL, input fields, change password, etc.
// Update property using base method, if no errors.
base.ChangePassword(newPassword);
}
}
我使用靜態工廠方法有兩個原因。 1)我想要一個可自定義和可擴展的對象構造(例如,將來我可能有一個AccountTemplate,可以從中提供通用信息來創建帳戶;我可以使用AccountTemplate參數輕松創建另一個靜態工廠方法重載),以及2 )具有無參數的構造函數,這使我可以更輕松地將此對象序列化為XML / JSON。
題:
但是,引起我注意的是,我可以很容易地擁有一個接受Account參數,執行邏輯並可以重載進行擴展的公共構造函數。 我可以保留我的私有無參數構造函數,以防止無參數構造並允許序列化。
我是編程新手。 我想知道的是,是否有特定的原因使用靜態工廠方法而不是公共構造函數,如上所述。 做我想做的事的首選方式是什么?
我不會稱您使用的是靜態工廠。 在我看來,它是“命名構造函數”,因為它駐留在類本身中,並且僅創建該特定類的對象。
它通常用於使操作更易於理解,例如比較
int value = Int32.Parse(someString);
int value = new Int32(someString); // doesn't really exist
第一個版本清楚地說明了它解析輸入字符串,第二個版本則不那么冗長。
更新:構造函數和靜態方法(如Int32.Parse
)之間的重要區別是,靜態方法可以選擇是否在發生錯誤時返回null
或引發異常。 構造函數只能拋出一個異常,或者-我不建議這樣做-將對象置於某種狀態,在該狀態中它僅被半初始化。
靜態工廠用於解耦類,並使更改實現更容易,例如,每次需要數據庫連接時,都無需使用代碼中的new
運算符實例化數據庫連接,而是使用返回接口的工廠方法:
SqlConnection myConnection = new SqlConnection(connectionString);
IDbConnection myConnection = myFactory.CreateConnection();
優點是,只需更改CreateConnection
方法,即可對整個項目進行全局更改,交換數據庫服務器甚至數據庫提供程序,而不必在實際使用數據庫連接的所有位置上更改代碼。
我建議您閱讀.NET構造函數指南 。 在某些情況下,可能會導致選擇靜態工廠而不是構造函數。 即
在構造函數中完成最少的工作。 除了捕獲構造函數參數外,構造函數不應做太多工作。 任何其他處理的成本都應延遲到需要時再進行。
和
如果所需操作的語義沒有直接映射到新實例的構造,或者如果遵循構造函數設計准則感到不自然,請考慮使用靜態工廠方法而不是構造函數。
我需要考慮何時需要使用靜態工廠方法以及何時使用構造函數。
1)如果需要執行一些構造函數無法完成的其他動作/初始化,請使用靜態工廠方法。 例如,如果您需要發布新創建的ActiveAccount
對象(例如SomePublicList.Add(ActiveAccount);
),那么從它自己的構造函數中發布它是一個壞習慣。
2)考慮繼承。 如果您需要為ActiveAccount
創建一個后代類(例如NewActiveAccout
),則需要在ActiveAccount
提供一個非私有的構造函數。 在這種情況下,也許您需要使用構造方法而不是工廠方法。
3)如果需要將一些參數傳遞給基類( Account
)構造函數,則需要在ActiveAccount
實現構造函數,因為您無法從靜態工廠方法將參數傳遞給基類構造函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.