如何防止类在工厂外实例化
我有一个工厂。 我不想允许这个工厂生产的类在工厂外实例化。 如果我将它们变成抽象的,静态的,或者给它们私有的构造函数,那么它们就不会是可实例化的! 这是语言限制还是什么?
我不想允许这个
var awcrap = new Extrude2013 (); // BAD !!! awcrap.extrudify (); // I don't want to allow this
其余代码:
using System; namespace testie { public enum ExtrudeType { Extrude2013, Extrude2014 } public interface IExtrudeStuff { void extrudify(); } public class Extrude2013 : IExtrudeStuff { public void extrudify(){ Console.WriteLine ("extrudify 2013"); } } public class Extrude2014 : IExtrudeStuff { public void extrudify(){ Console.WriteLine ("extrudify 2014"); } } public static class ExtrudeFactory { public static IExtrudeStuff Create(ExtrudeType t) { switch (t) { case ExtrudeType.Extrude2013: return new Extrude2013 (); case ExtrudeType.Extrude2014: return new Extrude2014 (); default: return null; } } } class MainClass { public static void Main (string[] args) { // Now for the pretty API part var o = ExtrudeFactory.Create (ExtrudeType.Extrude2013); o.extrudify (); var p = ExtrudeFactory.Create (ExtrudeType.Extrude2014); p.extrudify (); var awcrap = new Extrude2013 (); // BAD !!! awcrap.extrudify (); // I don't want to allow this } } }
你不能完全不允许这样做。 它是否是一种语言“限制”将是一个意见问题,但有些事情你可以考虑:
- 使构造函数
internal
。 这将允许声明程序集中的任何类型调用构造函数,但程序集外部没有任何内容。 这意味着您在该程序集中编写的任何代码都负责调用工厂,这也意味着您无法在另一个程序集中声明该类的子类型,因为它无法调用构造函数。 - 类似的方法是使您公开的类抽象 (或接口),然后声明一个
internal
(甚至private
作为工厂的子类,因为它永远不会在工厂外引用)实现抽象类的类型或界面。 - 需要只有工厂可以在构造函数中提供的标记。 这就是
DataTable
类的工作方式。 虽然仍然可以调用构造函数,但是用户必须为值传递null
,并且至少很明显他们不应该这样做。
Factory Pattern
是只有Factory知道如何选择和创建一个对象,它只通过一个接口而不是一个具体的类来暴露实例化对象的function。 使对象的构造函数私有失败,因为Factory
本身无法实例化它。
解:
1-定义一个interface
类,所有类型的Extrude20XX
类都实现它,例如IExtrudeStuff
。
2-将Extrude20XX
类作为私有嵌套类包装在Factory
类中。
3-在所有ExtrudeXX
类中实现IExtrude
接口。
4-编写(静态) Create (t)
方法,如:
public static class ExtrudeFactory { public static IExtrudeStuff Create(ExtrudeType t) { { switch (t) { case ExtrudeType.Extrude2013: return new Extrude2013 (); case ExtrudeType.Extrude2014: return new Extrude2014 (); default: return null; } } }