如何防止类在工厂外部实例化

本文关键字:外部 实例化 工厂 何防止 | 更新日期: 2023-09-27 18:34:11

我有一个工厂。我不想允许此工厂生成的类在工厂外部实例化。如果我将它们抽象化、静态化或给它们私有构造函数,那么它们根本不是可实例化的!这是语言限制还是什么?

我不想允许这个

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因为本身无法实例化它。

溶液:

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; 
   } 
 }
}