工厂模式:将对象构造限制在工厂

我有一个类T和一个TFactory创建类型对象的工厂T。我想确保只允许工厂创建新T对象。


一个半心半意的解决方案是要求工厂作为T的构造函数中的参数,唯一的目的是只有至少带来工厂对象的人才能创建 的T:


class T

{

    public T(TFactory Tf)

    {

        if (!(Tf is TFactory))

            throw new InvalidOperationException("No factory provided");

    }

}

但是,只要 aTFactory在手边,就可以构造T'。另一种方法是通过堆栈跟踪检查构造函数调用是否真的来自 TFactory 内部,但这对我来说似乎有点过分了。


第三种方法是将 TFactoryT和 TFactory 放在它们自己的程序集中,即 makeT的构造函数internal。但是一个新的项目和组装只是为了这个目的吗?


有人有更好的主意吗?(虽然我的代码是C#,但这可能是一个更笼统的问题)


红糖糍粑
浏览 114回答 3
3回答

喵喔喔

这是与您的第三种方法非常相似的东西:将工厂声明为的内部类T,以及 makeT的构造函数private:public class T {    public class Factory {        public T GetT() {            return new T(); // simple implementation just for an example here        }    }    private T() {}}由于Factory是 inside T,它可以访问私有构造函数,但外部代码不能。如果您不想创建单独的程序集,可以考虑这种方法。请注意,您仍然可以将工厂类和放在T两个不同的文件中,其中包含partial类:public partial class T {    private T() {}    // other stuff about T here...}// in another filepublic partial class T {    public class Factory {        public T GetT() {            return new T();        }        // other stuff about Factory here...    }   }

陪伴而非守候

public abstract class T { }public class TFactory{    public T CreateT() => new TImpl();    private class TImpl : T { }}

一只名叫tom的猫

第二种方法是最糟糕的。这种行为对客户来说是绝对不明显和不清楚的。堆栈跟踪还会减慢执行速度。第一个和第二个是有道理的。如果您想完全控制实例创建,请将其放入类型中。使用工厂方法。请记住,在对实例创建施加约束时应该是合理的。例如,实例应该使用多态(虚拟)方法启动。不能从构造函数中调用这样的方法(一种非常糟糕的做法),因此应该在构造之后调用该方法。为了不把这个责任推给客户,隐藏一个构造函数并提供一个工厂方法。abstract class Base{    protected abstract void Initialize();}class Derived : Base{    protected Derived() { /* ... */}    protected override void Initialize() { /* ... */}    public Derived CreateDerived()    {        var derived = new Derived();        derived.Initialize();        return derived;    }}
打开App,查看更多内容
随时随地看视频慕课网APP