Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Design patterns 两步对象构造初始化模式的名称和说明是什么?_Design Patterns_Constructor_Initialization - Fatal编程技术网

Design patterns 两步对象构造初始化模式的名称和说明是什么?

Design patterns 两步对象构造初始化模式的名称和说明是什么?,design-patterns,constructor,initialization,Design Patterns,Constructor,Initialization,是否有一篇深入的文章对此进行了解释?我希望了解可用的解决方案,并避免重新发明模式 其思想是,即使没有完全初始化,实例也是有用的,并且在构建时不知道初始化依赖项。因此,实例构造是一个分两步的过程:首先通过普通构造函数创建,然后在可能更晚的某个阶段通过公共方法初始化 以下是一个示例: public static void Main() { var mutation = new Mutation("Specimen 1"); //Do something with mutation

是否有一篇深入的文章对此进行了解释?我希望了解可用的解决方案,并避免重新发明模式

其思想是,即使没有完全初始化,实例也是有用的,并且在构建时不知道初始化依赖项。因此,实例构造是一个分两步的过程:首先通过普通构造函数创建,然后在可能更晚的某个阶段通过公共方法初始化

以下是一个示例:

public static void Main()
{
    var mutation = new Mutation("Specimen 1");

    //Do something with mutation - log, report etc.

    if (!mutation.IsInitialized)
    {
        var first = new Creature("Cat", new List<string> {"Paws", "Whiskers"});
        var second = new Creature("Crow", new List<string> { "Wings", "Beak" });

        mutation.Initialize(first, second);
    }

    Console.WriteLine(mutation.CommonTraits.Aggregate((p,n) => p + ", " + n));
    Console.ReadKey();
}

public class Mutation
{
    public Mutation(string name)
    {
        Name = name;
    }

    public string Name { get; set; }
    public Creature First { get; set; }
    public Creature Second { get; set; }
    public List<string> CommonTraits { get; set; }
    public bool IsInitialized { get; private set; }

    public void Initialize(Creature first, Creature second)
    {
        First = first;
        Second = second;

        CommonTraits = new List<string>();

        CommonTraits.AddRange(first.Traits); //TODO: select randomly.
        CommonTraits.AddRange(second.Traits); //TODO: select randomly.

        IsInitialized = true;
    }
}

public class Creature
{
    public Creature(string name, List<string> traits)
    {
        Name = name;
        Traits = traits;
    }

    public string Name { get; private set; }
    public List<string> Traits { get; private set; }
}

你在寻找它的专业化吗?

听起来你想问的是,是否有一个术语用于需要:

Thing it = new Thing(someParams);
Thing.Initialize(moreParams);
而不是

Thing it = new Thing(someParams, moreParams);
术语“两阶段初始化”有时用于指构造函数生成的对象在调用第二个方法之前是无用的。虽然从API的角度来看,这样的设计在某些情况下可能是有意义的,但这种设计通常是由于Java或许多.NET语言中缺乏控制对象构造顺序的工具造成的

在许多情况下,构造有用的对象需要基类代码调用虚拟方法,而在使用传递给派生类构造函数的参数来设置派生类对象之前,虚拟方法是不可用的。虽然C允许在链接到基类构造函数之前初始化其值不依赖于构造函数参数的派生类字段,但在基类构造函数放弃对构造过程的所有控制之前,C没有提供派生类可以使用其构造函数参数的干净方法。两阶段初始化是一种有点丑陋但可行的处理方法


此外,如果一个对象必须持有有用的资源,那么将此类资源的获取推迟到初始化方法将使客户机代码能够将对象包装在try或using块中,以确保即使对象的初始化引发异常,该对象使用的资源也会被释放。由于.NET和Java不遗余力地防止构造函数抛出异常的对象的暴露,因此在不使用两阶段初始化的情况下防止资源泄漏要比使用两阶段初始化困难得多。

会认为这种糟糕的设计。您可能需要两个类,一个可能只有名称的Emotation类,一个变异类需要两个生物作为其构造函数的一部分。@dbugger听起来像是将复杂性转移到了另一个地方——引入了一个额外的类型。你试图用一个类型做两件不同的事情——这导致了复杂性。几乎是No的重复,但我理解其相关性。