3

数か月前、独立系ソフトウェア開発会社の代表者 2 人が主催するプレゼンテーションに出席しました。それは主に、優れたソフトウェア設計と実践に関するものでした。

2 人は主に Java について話していましたが、状況によっては、コンストラクターの代わりに getInstanceOf() を使用するのが非常に良い方法であると言っていたのを覚えています。これは、コンストラクターではなく異なるクラスから常に getInstanceOf() を呼び出すようにすることと関係があり、大規模なプロジェクトでははるかに優れたアプローチでした。

ご覧のとおり、今はあまり覚えていません :/ しかし、彼らが使用した議論には本当に説得力があったことを覚えています。あなたの誰かがそのようなデザインに出くわしたことがあるのだろうか、いつ、それは役に立つと思いますか? それとも全然ないと思いますか?

4

4 に答える 4

10

コンストラクターの代わりに静的ファクトリー メソッドを検討する—<em>Joshua Bloch

于 2010-02-04T01:15:34.643 に答える
8

おそらく、静的ファクトリ メソッド パターンについて話していたのでしょう (オブジェクトを動的に作成するためのリフレクション API メソッドについてではありませんでした)。

コンストラクgetInstanceOf()ターやnew. 静的ファクトリ メソッドは次のことができます。

  1. 特定の場合に望ましい場合は、メイン クラスの別のサブクラスを作成することを選択します (プロパティや他のオブジェクト/シングルトン、またはメソッド パラメーターなどの環境条件に基づく)。

  2. オブジェクトを作成するのではなく、既存のオブジェクトを返すことを選択します。この例については、Java API のBoolean.valueOf(boolean)を参照してください。

  3. コンストラクターと同じことを行います - クラス自体の新しいインスタンスを返すだけです。

  4. 新しいオブジェクトを構築し、それらのメソッドに名前を付けるためのさまざまな種類の方法を提供して、混乱を少なくします (たとえば、コンストラクターでこれを試してみると、すぐに多くの異なるオーバーロードができます)。2 つの異なる方法でインスタンスを作成できるようにする必要があるが、同じタイプのパラメーターのみが必要な場合、コンストラクターではこれが不可能な場合もあります。例:

    // This class will not compile!
    public class MyClass {
        public MyClass(String name, int max) {
            //init here
        }
        public MyClass(String name, int age) {
            // init here
        }
    }
    
    // This class will compile.
    public class MyClass2 {
        private MyClass2() {
        }
        public static MyClass2 getInstanceOfMax(String name, int max) {
            MyClass2 m2 = new MyClass2();
            // init here
            return m2;
        }
        public static MyClass2 getInstanceOfAge(String name, int age) {
            MyClass2 m2 = new MyClass2();
            // init here
            return m2;
        }
    }
    
  5. 上記の任意の組み合わせを実行します。

  6. さらに、インスタンスのインスタンス化の詳細を他のクラスから隠しているため、将来変更することができます (構造のカプセル化)。

コンストラクターは、要求された正確な型のオブジェクトの新しいインスタンスのみを作成できます。後で変更することはできません。

このパターンのいくつかの欠点は次のとおりです。

  1. ファクトリ メソッドは静的であるため、サブクラスで継承することはできません。親コンストラクターは、サブクラスから簡単にアクセスできます。

  2. ファクトリ メソッドの名前は大きく異なる可能性があり、一部の (新しい) 開発者にとっては混乱を招く可能性があります。

あなたはまた、個人的な経験を求めました。はい、どちらのパターンもよく使います。ほとんどのクラス コンストラクターでは、より高度なニーズがある場合は、静的ファクトリを使用します。私は、この形式の構築が義務付けられている他の言語 (専売ですが、Java に似ています) のプロジェクトにも取り組んでいます。

于 2010-02-04T04:36:32.510 に答える
1

ClassクラスのnewInstanceメソッドを意味しているのではないかと思います。次のように呼び出します。 MyClass foo = MyClass.newInstance();

この形式のオブジェクトのインスタンス化は、作成パターンで人気があります。プロパティやXMLファイルなど、オブジェクトの具体的な実行時タイプを外部で指定する場合に便利です。

于 2010-02-03T21:37:52.247 に答える
1

Drew が正しければnewInstance()、Java Reflection API の一部です。したがって、コンストラクタを使用するほど自然ではありません。

大規模なプロジェクトでこれを使用することが推奨される理由は、それがJava Bean プログラミング スタイルにつながり、オブジェクトの作成が明らかに特別なものになるという事実に付随する可能性があります。大規模なプロジェクトでは、オブジェクトの作成は横断的な関心事ではなく、明確に特定された責任である必要があります。多くの場合、1 つのソース/ファクトリからのものです。しかし、私見では、 IoC patternを使用すると、これらすべての利点とさらに多くの利点が得られます。

于 2010-02-03T22:09:31.253 に答える