-1

いくつかのプロジェクトで使用される一連のメソッドの設計パターンを探しているので、それらを使用して「ライブラリ」を作成しています。

最初は、それらをすべて静的にして、 Library.methodName() から呼び出せるようにすることを考えました。それだけです。一度設定してからクラス内で使用できるすべてのメソッドに対して、いくつかの定数値を渡していることに気付きました。(この定数値はプロジェクト間で変わります)

今、私はこの値でインスタンス化され、毎回値を渡さずにオブジェクトを介してメソッドにアクセスする必要があるクラスを持つことを考えましたが、毎回「ライブラリ」クラスのオブジェクトの作成を防ぎたいので、シングルトン。

これらすべてでシングルトンを作成しましたsetが、最初にクラス変数を明示的に作成する必要がありますが、このアプローチでは、メソッドを使用する前に値を設定する必要があるため、プログラマーは失敗します確かに最終的には、自分でも。

常に行うSingleton.getInsance(value1, value2).method(...)ことは問題外です。私は最初のアプローチを好みます。また、この変数の「デフォルト」値を定義することはできません。設定する必要があります。

指定された値で初期化でき、常にそれらを渡す必要がないシングルトンを持つのに役立つデザインパターンはありますか?

または、最初のアプローチに固執して、プログラマーに常に値を渡させる必要がありますか?

またはその他のオプション、適合するデザインパターン、またはその他のものも機能する可能性があります。

ありがとう

4

6 に答える 6

0

この道はあなたにとって快適ですか?

public class AreaCalculator {
  private int length = 10;
  private int width = 10;
  private static final AreaCalculator areaCalculator = new AreaCalculator();

  private AreaCalculator() {
    // TODO Auto-generated constructor stub
  }

  public static AreaCalculator getInstance() {
    return areaCalculator;
  }

  public AreaCalculator fillLength(int length) {
    this.length = length;
    return getInstance();
  }

  public AreaCalculator fillWidth(int width) {
    this.width = width;
    return getInstance();
  }

  public AreaCalculator fillAll(int length, int width) {
    this.length = length;
    this.width = width;
    return getInstance();
  }

public int calculateArea() {
    if (!isInit()) {
        throw new RuntimeException("Should Init first!");
    }
    return length * width;
}

public boolean isInit() {
    // add something
    return true;
}

テストコード

public class TestMain {

  public static void main(String[] args) {
    int result = AreaCalculator.getInstance().fillWidth(20).calculateArea();
    System.out.println("10*20=" + result);
    result = AreaCalculator.getInstance().fillWidth(10).fillLength(10).calculateArea();
    System.out.println("10*10=" + result);
    result = AreaCalculator.getInstance().fillAll(10, 30).calculateArea();
    System.out.println("10*30=" + result);
  }

**

構成インターフェースの使用。

**

ConfigInf(lib側)

public interface ConfigInf {

    public static String F_LENGTH = "length";
    public static String F_WIDTH = "width";

    public String getProperty(String key);

}

ConfigFactory(lib側)

public class ConfigFactory {

    private static ConfigInf config = null;

    public static void init(ConfigInf config) {
        ConfigFactory.config = config;
    }

    public static ConfigInf getConfig() {
        if (config == null) {
            throw new NullPointerException("Config should be init first");
        }
        return config;
    }
}

ClientConfig (クライアント側)

public class ClientConfig implements ConfigInf {

    String value = "10";

    @Override
    public String getProperty(String key) {
        // read configFile
        if (ConfigInf.F_LENGTH == key) {
            return value;
        } else {
            return "100";
        }

    }

    public void update() {
        value = "100";
    }

}

AreaCalculatorWithConfig(lib側)

public class AreaCalculatorWithConfig {
    private int length = 10;
    private int width = 10;
    //
    private static final AreaCalculatorWithConfig areaCalculator = new AreaCalculatorWithConfig();

    private AreaCalculatorWithConfig() {
        // TODO Auto-generated constructor stub
    }

    public static AreaCalculatorWithConfig getInstance() {
        return areaCalculator;
    }

    public int calculateArea() {
        ConfigInf config = ConfigFactory.getConfig();
        length = getInt(config.getProperty(ConfigInf.F_LENGTH));
        width = getInt(config.getProperty(ConfigInf.F_WIDTH));
        return length * width;
    }

    public static int getInt(String value) {
        return Integer.parseInt(value);
    }
}

TestMainWithConfig (クライアント側)

public class TestMainWithConfig {
    public static void main(String[] args) {
        // init;
        ClientConfig config = new ClientConfig();
        ConfigFactory.init(config);
        //
        System.out.println("Before update:"
                + AreaCalculatorWithConfig.getInstance().calculateArea());
        config.update();
        System.out.println("After update:"
                + AreaCalculatorWithConfig.getInstance().calculateArea());
    }
}
于 2012-08-29T09:11:18.800 に答える
0

要件に応じてFactory pattern、渡された定数に基づいて Create Library インスタンスを 使用Singletonしてインスタンスを作成できます。

于 2012-08-29T09:11:20.290 に答える
0

最初のアプローチに固執し、プログラマーに常に値を渡させる必要がありますか?

これに代わる唯一の方法は、すべての必須値を保持および設定するコンテキストのコンストラクターを使用することです。可能であれば、ステートフル シングルトンの使用は避けたいと思います。

呼び出し元がオブジェクトを複数回作成することを避けたい場合は、必要に応じてそれをシングルトンにすることができますが、シングルトンの使用を強制するべきではありません。

于 2012-08-29T08:37:18.683 に答える
0

初期化を Config クラスに追加するだけで、確実に 1 回だけ初期化できます。アプリケーションの残りの部分は、初期化が正しく行われることに依存します。おそらく、例外による重複した初期化を避けたいと思うかもしれません。秘訣は、設計によって、または例外のブルートフォースによって、シングルトンを埋める責任があるポイントが1つだけになるようにすることです。ロギングの構成は非常によく似ています。とはいえ、それほど奇妙ではありません。

于 2012-08-29T10:11:00.853 に答える
0

あなたが作成しようとしているライブラリは、オブジェクト指向設計の原則に完全に反しています。関数/メソッドのライブラリを作成しないでください。代わりに、状態と動作を備えたクラスのライブラリを作成する必要があります。

于 2012-09-07T12:52:37.110 に答える
0

または、これらの値はプロジェクト間で変更されますが、プロジェクト内では変更されないため、「ライブラリ」は構成ファイルを読み取って値を提供できるvalue1, value2ため、呼び出しコードが毎回それらを提供する必要はありません。

これは怠惰な読み取り (最初の呼び出しで行われる) であるため、ライブラリが使用される前に初期化されることがさらに保証されます。もちろん、ファイルが存在しない場合は、未チェックの例外をスローすることをお勧めします。

于 2012-08-29T08:40:48.900 に答える