それらが何であるか、なぜ私たちがそれらを持っているのかを自問してください。どちらもオブジェクトのインスタンスを作成するために存在します。
ElementarySchool school = new ElementarySchool();
ElementarySchool school = SchoolFactory.Construct(); // new ElementarySchool() inside
これまでのところ違いはありません。ここで、さまざまな学校の種類があり、ElementarySchool の使用から HighSchool (ElementarySchool から派生するか、ElementarySchool と同じインターフェイス ISchool を実装する) に切り替えたいとします。コードの変更は次のようになります。
HighSchool school = new HighSchool();
HighSchool school = SchoolFactory.Construct(); // new HighSchool() inside
インターフェースの場合、次のようになります。
ISchool school = new HighSchool();
ISchool school = SchoolFactory.Construct(); // new HighSchool() inside
このコードが複数の場所にある場合、ファクトリ メソッドを変更すると作業が完了するため、ファクトリ メソッドを使用する方がかなり安価であることがわかります (インターフェイスで 2 番目の例を使用する場合)。
そして、これが主な違いと利点です。複雑なクラス階層を扱い始め、そのような階層からクラスのインスタンスを動的に作成したい場合、次のコードが得られます。ファクトリ メソッドは、どの具象インスタンスをインスタンス化するかをメソッドに指示するパラメーターを受け取る場合があります。MyStudent クラスがあり、対応する ISchool オブジェクトをインスタンス化して、生徒がその学校のメンバーになるようにする必要があるとします。
ISchool school = SchoolFactory.ConstructForStudent(myStudent);
これで、さまざまな IStudent オブジェクトに対してどの ISchool オブジェクトをインスタンス化するかを決定するビジネス ロジックを含む、アプリ内の 1 つの場所ができました。
したがって、単純なクラス(値オブジェクトなど)の場合、コンストラクターは問題ありませんが(アプリケーションを過度に設計したくない場合)、複雑なクラス階層の場合はファクトリメソッドが推奨される方法です。
このようにして、4 冊の本のギャングからの最初の設計原則「実装ではなくインターフェイスへのプログラム」に従います。