0

以下の私のファクトリメソッドコード:

public class DBFactory {
    protected DBFactory() {}
    protected static DataBase createDB() { return null; }
}

public class MySQLFactory extends DBFactory{
    private MySQLFactory() {}

    public static DataBase createDB() {
        return new MySQL();
    }
}

public class SQLServerFactory extends DBFactory{
    private SQLServerFactory() {}

    public static DataBase createDB() {
        return new SQLServer();
    }
}    

public class Test {
    public static void main(String[] args) {
        DataBase db = SQLServerFactory.createDB();
        db.connect();
    }
}

そして、私はそれが以下のクライアントコードと違いがないことを発見しました:

package factorymethod;

import db.DataBase;

public class Test {
    public static void main(String[] args) {
        DataBase db = new MySQL();
        db.connect();
    }
}

問題は、なぜファクトリメソッドを使用しなければならないのかということです。もっと冗長になると思います...

4

6 に答える 6

3

仮想コンストラクターが必要な場合は、ファクトリメソッドを使用します。実行時にさまざまなタイプを使用します。

の呼び出しでnewは、1つのタイプしか作成できません。

ファクトリは、渡されたパラメータに応じて、共通のインターフェイスまたは親クラスを持っている限り、さまざまなタイプを作成できます。

于 2012-11-01T18:17:28.350 に答える
3

クラスAbstractFactoryを作成し、ファクトリメソッドを非静的にした場合、実行時にクライアントに抽象ファクトリを提供できるため、より理にかなっています。

public interface DBFactory { // Note: interface, not abstract class
    public DataBase createDB();
}

public class MySQLFactory implements DBFactory {
    public DataBase createDB() {
        return new MySQL();
    }
}

public class SQLServerFactory extends DBFactory{
    public DataBase createDB() {
        return new SQLServer();
    }
} 

それから

DBFactory factory = // provide whichever based on runtime settings
DataBase dataBase  = factory.createDB(); // client uses whatever is returned
于 2012-11-01T18:21:20.003 に答える
1

ファクトリメソッドは、クラスの家族のような分類法のインスタンス化を実装するのに役立つソフトウェアデザインパターンです。

1つのクラスのみをインスタンス化していて、新しいクラスに対応するためにコードが将来変更されることを予期しない場合は、パターンの適用を安全に回避できます。これは、実際には過度に冗長で不要なためです。

于 2012-11-01T18:17:26.850 に答える
0

ファクトリメソッドを使用して、シングルトンデザインパターンを実装できます。

たとえば、アプリケーションの存続期間中はいつでも複数のMySQL()オブジェクトを持つ必要がないとします。ファクトリメソッドを使用して、複数のMySQL()オブジェクトを作成しないようにすることができます。次の(psuedoesq)コードについて考えてみます。

public class MySQLFactory extends DBFactory{
    private MySQLFactory() {}
    private MySQL myObject;

    public static DataBase createDB() {
        if(myObject == null) {
             myObject = new MySQL();
        } 

        return myObject;
    }
}

このコードを使用すると、そのオブジェクトのインスタンスが複数作成されないことがほぼ保証されます。これは、コストがかかる可能性のある新しいオブジェクトを作成するときにリソースを節約するのに役立ちます。

編集:私はあなたの元の質問の範囲から外れたと信じています。

于 2012-11-01T18:21:21.077 に答える
0

ファクトリメソッドパターンを使用すると、基本クラスに触れることなく、特定の具象オブジェクトを割り当てることができます。これにより、オープン/クローズド原則依存性逆転の原則が促進されます。この後者は、「コンクリートのクラスに依存することはありませんが、低レベルの要素(コンクリートオブジェクト)を高レベルの要素(抽象オブジェクト)に依存させる」ことを示しています。

実際、3種類のデータベースがあると想像してください。ファクトリパターン(または抽象ファクトリパターン)がないと、次のコードになります。

protected DBFactory(String database) {
   if (database.equals("MySQL")) {
       this.database = new MySql();
   } else if (database.equals("PostgreSQL") {
       this.database = new PostgreSQL();
   }
   else{
       this.database = new Oracle();
   }
} 

ファクトリテンプレートメソッドを使用すると、継承を通じてこのサブタイプを指定できます。抽象ファクトリパターンとは異なり、インスタンス化時に修正され、実行時に変更することはできません。

したがって、ファクトリがないと、新しい種類のデータベースを追加するやいなや、Open / Closedの原則に違反する必要があり、したがって、基本クラスの既存の動作機能が壊れる可能性があります。

とにかく、あなたの特定のケースでは、それを使用する意味はありません。なんで ?これは、ファクトリがプログラム(ビジネスロジックを含むプログラムの中心)によって使用され、「メイン」メソッドや、これらのロジックコンポーネントをまとめてフィードし、操作する他のプロセスフローによって使用されない場合に特に便利です。

于 2012-11-01T18:26:05.007 に答える
0

@user984444と@Mik378がポイントを取得します。ファクトリメソッドは次のことができます。1。インスタンスがシングルトンであることを保証します。2.さまざまなメソッド/パラメータを使用してさまざまな具象インスタンスを作成します。また、サブクラス/実装を確認する必要はありません。

ファクトリメソッドパターンをよりよく理解するには、ファクトリにいて、製造プロセスがわからないと仮定しますが、必要な製品を入手できます。クラス図を見てみましょう。MealFactory factory = new ChineseMealFactory(); factory.prepareDessert()はChineseDessertを返します。それでおしまい。

于 2012-11-02T16:38:19.160 に答える