回答
如果出於某種原因需要將工廠和構建的類放在單獨的程序集中(這意味着只需使用internal
就行不通),並且您可以確保工廠有機會首先運行,可以這樣做:
// In factory assembly:
public class Factory
{
public Factory()
{
token = new object();
MyClass.StoreCreateToken(token);
}
public MyClass Create()
{
return new MyClass(token);
}
private object token;
}
// In other assembly:
public class MyClass
{
public static void StoreCreateToken(object token)
{
if (token != null) throw new InvalidOperationException(
"Only one factory can create MyClass.");
this.token = token;
}
public MyClass(object token)
{
if (this.token != token) throw new InvalidOperationException(
"Need an appropriate token to create MyClass.");
}
private static object token;
}
是的,這很麻煩和笨拙。但可能會出現奇怪的情況,這實際上是一個很好的解決方案。
使其構造函數爲私有,並將該工廠方法作爲靜態方法提供給類本身。
在大多數情況下,您只需將構造函數設置爲內部函數,即可將工廠劃分爲自己的類 - 我發現通常不值得設法阻止自己的團隊使用new
在類中創建實例' 部件。
將構造函數放在內部並將工廠放置在同一個程序集中。
public MyClass
{
internal MyClass()
{
}
}
在同一裝配
public MyClassGenerator
{
public static CreateMyClass()
{
return new MyClass();
}
}
如果工廠不能在同一程序或此方法不爲你工作,看Dan's answer
如果工廠是在相同的程序集並且只需要保護實例化類的外部程序集,就可以使構造函數成爲內部函數。我知道阻止所有其他類(包括同一程序集中的類)的唯一方法是將實例化的類作爲工廠的嵌套私有類,並僅將其作爲接口公開。如果這個類是它自己的工廠(一個靜態工廠方法),那麼你可以像前面提到的那樣使構造函數保持私有。
+1 - 如果你真的需要這個,這是如何完成它。 – 2010-09-08 19:59:01
它總是通過調用新的某處創建的,但是如果您只希望在工廠類中發生這種情況,您可以將所有構造函數設置爲Internal(或Private),並使用Public Static工廠方法同班)。
我不喜歡在類型本身上有工廠,特別是如果它是一個域對象。有內部如果你有一個單獨的類作爲工廠(我認爲你應該)。如果工廠位於不同的裝配上,請使用InternalVisible屬性。
很多人都提到過使用內部函數,但是你也可以讓你的構造函數受到保護,並派生一個只包含靜態工廠方法的類。這並不妨礙其他人做同樣的事情,但在限制直接訪問構造函數方面做得相當不錯。
你可以將你的具體類作爲嵌套的私有類,在工廠類中使用公共構造函數 - 這樣你的工廠就可以創建它們,其他人甚至不能看到它們。 無論如何,你從工廠返回一些接口/抽象類,而不是具體類型。 當然,你不能將你的返回類型轉換爲客戶端代碼中某個具體類型,但首先它是一個糟糕設計的標誌,其次你總是可以用更具體的接口/抽象類來解決它,因爲嵌套的私有類繼承。
,你可以參考埃裏克利珀的答案在這裏(對於類似的問題): Why Would I Ever Need to Use C# Nested Classes
- 1. 創建域創建一個工廠的正確方式對象
- 2. 進樣嘲笑由工廠類創建的對象
- 3. 對象創建工廠模式
- 4. 創建通用對象工廠
- 5. 創建對象 - 工廠方法
- 6. 獨家使用工廠創建對象
- 7. 工廠對象創建需要其他對象的對象
- 8. C++對象工廠函數
- 9. 創建一個c#工廠
- 10. 工廠創建工廠?
- 11. 創建一個工廠方法來創建新的SqlConnection對象
- 12. 對象工廠
- 13. 工廠類別 - 保存對象
- 14. DDD我可以使用抽象工廠創建域對象
- 15. 確保只有工廠可以創建實例
- 16. 爲工廠創建抽象工廠是否有意義?
- 17. 對工廠或創建對象的依賴關係
- 18. 如何在PowerShell中創建一個由webservice工廠函數定義的對象?
- 19. 如何配置HK2注入由工廠方法創建的對象?
- 20. 如何「訂閱」由Java中的工廠創建的對象上的事件?
- 21. 在對象工廠
- 22. 工廠對象與工廠功能
- 23. 工廠方法VS工廠對象
- 24. 對象工廠字典在C++
- 25. 如何確保特定對象僅由另一個對象實例化?
- 26. 類工廠創建派生類C++
- 27. 如果要創建的對象需要另一個對象,工廠是否應該使用另一家工廠?
- 28. FactoryGirl RSpec創建工廠對象時沒有方法錯誤,其中工廠設置了該對象的屬性
- 29. 創建由jQuery對象
- 30. 創建C++對象
我喜歡這個,除了有兩個問題...(1)你的例子似乎只允許我使用1個工廠。我想允許創建許多工廠(可能有不同的工廠風格),唯一的要求是必須使用Factory對象創建MyClass的對象。 (2)如果我用new()約束來使用泛型,那麼MyClass需要一個無參數的構造函數呢?你的例子在這種情況下不起作用。 – JoelFan 2010-09-12 23:36:40
「你的例子似乎只允許我使用1個工廠。」使'token'靜態或以其他方式在不同的工廠實例中共享它。任何有權訪問該令牌的東西都可以創建'MyClass'的實例「如果我使用帶new()約束的泛型,那麼MyClass需要一個無參數構造函數?」那麼你也不需要工廠。 – munificent 2010-09-13 14:26:27