3

私はこれについて逆方向に進んでいるかもしれません...ドキュメントのようなクラスとテンプレートのような別のクラスがあります。どちらも同じ基本クラスから継承され、テンプレートから新しいドキュメントを作成するメソッドがあります (または別のドキュメントから、基本クラスにあるメソッド)。したがって、テンプレートから新しいドキュメントを作成する場合は、テンプレートをインスタンス化して GetNewDoc() を呼び出すだけです。

Document doc = mytemplate.GetNewDoc();

Document クラスには、新しい空のドキュメントを作成する空のコンストラクターと、データベースからドキュメントをロードできるようにドキュメント ID を受け取る別のコンストラクターがあります。ただし、テンプレート ID を受け取るコンストラクターも必要です。こうすればできる

Document doc = New Document(TemplateID)

テンプレート クラスには既にドキュメントを返す機能があるため、コンストラクターに次のようなことをさせたいと思います。

Template temp = new Template(TemplateID);
this = temp.GetNewDoc();

もちろん、「これ」は読み取り専用であるため、これを行うことはできません。とにかく奇妙に感じます。私はここで非常にばかげていると感じているので、気軽に叫んでください:)

問題は、問題のオブジェクトが子オブジェクトのいくつかのコレクションと複数のテーブルにわたるデータベースの永続性で非常に複雑であるため、あまり多くのコードを複製したくないということです。ただし、テンプレートから新しいドキュメントを取得し、フィールド/プロパティをコピーするだけで、コレクションが簡単にフォローできるようになると思います-重複のように思えます.

より精巧なコード例:

using System;
using System.Collections.Generic;
using System.Text;

namespace Test
{
class Program
{
    static void Main(string[] args)
    {
        // This just creates the object and assigns a value
        Instance inst = new Instance();
        inst.name = "Manually created";
        Console.WriteLine("Direct: {0}", inst.name);

        //This creates a new instance directly from a template
        MyTemplate def = new MyTemplate();
        Instance inst2 = def.GetInstance(100);
        Console.WriteLine("Direct from template: {0}", inst2.name);

        Instance inst3 = new Instance(101);
        Console.WriteLine("Constructor called the template: {0}", inst3.name);
        Console.ReadKey();

    }
}

public class Instance
{
    public string name;

    public Instance(int TemplateID)
    {
        MyTemplate def = new MyTemplate();
        //If I uncomment this line the build will fail
        //this = def.GetInstance(TemplateID);
    }

    public Instance()
    {
    }
}

class MyTemplate
{
    public Instance GetInstance(int TemplateID)
    {
        Instance inst = new Instance();
        //Find the template in the DB and get some values
        inst.name = String.Format("From template: {0}", TemplateID.ToString());
        return inst;
    }
}
}

4

3 に答える 3

7

コンストラクター内のコードから新しいオブジェクトを作成する以外のことができるようにしたい場合は、そもそもコンストラクターを使用しないでください。

int を取るインスタンス コンストラクタが本当に必要ですか? 静的ファクトリ メソッドに変えてみませんか。

public static Instance CreateInstance(int id)
{
    MyTemplate def = new MyTemplate();
    return def.GetInstance(id);
}

静的メソッドには、コンストラクターに比べてさまざまな利点がありますが、いくつかの欠点もあります。(それについては別のSOの質問があります-一見の価値があります。)

于 2008-11-27T17:55:00.787 に答える
2

コンストラクタまたは他のメソッドから「this」を再作成することはできません。別のオブジェクトを作成してコンテンツをコピーすることもできますが、代わりにファクトリをパブリックにします。3 つの createDocument() メソッドを持つファクトリ クラスを定義します。1 つは空のドキュメント用、もう 1 つは DB のドキュメント用、3 番目はテンプレートのドキュメント用です。

public class Factory {
   public static Document createBlankDocument();
   public static Document createDocument( DocumentId id );
   public static Document createDocumentFromTemplate( TemplateId id );
}
于 2008-11-27T17:57:26.617 に答える
0

私は Jon と一緒です。ファクトリ メソッドを使用する方が、何が起こっているか (単に新しいオブジェクトを作成する 以上のこと) について開発者にとって非常に明確であるため、はるかに優れています。

ファクトリ メソッドはプログラマーに、「ここでは特別な初期化が行われており、newを使用しても十分ではありません」と言います。

通常、リソースをリサイクルまたはキャッシュする場合はファクトリを使用します。逆に、newキーワードを使用する場合、リソースがリサイクルまたはキャッシュされることは期待できません。あなたは真新しいリソースを期待しています(それはキーワードに組み込まれています):)

于 2008-11-27T18:41:00.930 に答える