如何防止在工厂外实例化类 [英] How to keep a class from being instantiated outside of a Factory

查看:50
本文介绍了如何防止在工厂外实例化类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一家工厂.我不想允许在工厂外部实例化该工厂生产的类.如果我将它们抽象化,静态化,或者为它们提供私有的构造函数,那么它们将根本无法实例化!这是语言限制还是什么?

I have a Factory. I do not want to allow classes that this factory produces to be instantiated outside of the factory. If I make them abstract, static, or give them private constructors then they won't be instantiable at all! Is this a language restriction or what?

我不想允许这个

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

推荐答案

您不能完全禁止这样做.这是否是一种语言限制"将是一个意见问题,但是您可以考虑以下几点:

You can't completely disallow this. Whether or not it's a language "restriction" would be a matter of opinion, but there are things that you could consider:

  • 使构造函数为internal.这将允许声明程序集中的任何类型调用构造函数,但程序集外部的任何类型都可以调用构造函数.这意味着您在该程序集中编写的任何代码都负责调用工厂,并且这也意味着您无法在另一个程序集中声明该类的子类型,因为它将无法调用构造函数.
  • 一种类似的方法是使您公开 abstract (或接口)的类,然后声明internal(甚至private作为工厂的子类),因为它将实现抽象类或接口的类型).
  • 需要只有工厂才能在构造函数中提供的令牌.这是DataTable类的工作方式.尽管仍可以将构造函数称为 ,但用户必须传入null作为值,至少显然,他们不应该这样做.
  • Make the constructor internal. This will allow any type within the declaring assembly to call the constructor, but nothing outside the assembly. This would mean that any code you write in that assembly to be responsible for calling the factory, and it also means that you could not declare subtypes of the class in another assembly, since it would be unable to call the constructor.
  • A similar approach would be to make the class you expose abstract (or an interface), then declare an internal (or even private as a subclass of the factory, since it would never be referenced outside of the factory) type that implements the abstract class or interface.
  • Require a token that only the factory can provide in the constructor. This is how the DataTable class works. While the constructor could still be called, the user would have to pass in null for the value and it would at least be obvious that they shouldn't be doing this.

这篇关于如何防止在工厂外实例化类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆