web-dev-qa-db-ja.com

staticを使用して不変オブジェクトを作成する

staticメソッドの使用についてこの ソフトウェアエンジニアリングページ を読んでいました。しかし、私は混乱しています。多分それはstaticについて語っているコンテキストに関するものです。静的というのは、テストには本当に悪いので使用すべきではないということです。

不変クラスを作成するとき、コンストラクターがプライベートであり、静的ファクトリーを使用してオブジェクトを作成する場合があります。 Java独自の documentation でも、不変オブジェクトを作成するときのファクトリの使用をサポートしています。

より洗練されたアプローチは、コンストラクターをプライベートにして、ファクトリーメソッドでインスタンスを構築することです

2
user286462

一連のプロパティをバンドルするだけの不変のDTOを作成する場合は、例のように、それだけです。パブリックコンストラクターを使用します。

ファクトリは、オブジェクトの構築が複雑で費用がかかる場合、入力値に基づいてさまざまなタイプを返す場合、またはその他の「ロジック集約型」の状況向けです。少数の値を単に格納することは、それらの状況の1つではありません。

3
whatsisname

静的というのは、テストには本当に悪いので使用すべきではないということです。

はい、静的コードは単体テストを難しくします(時には不可能です)。 staticは使用しないでください。静的メソッドを使用しても問題がない場合もあります。

これがテストを難しくする理由です。あなたの質問にあるこのコードを考えてみましょう:

public static Weapon Sword(String name, damage){
    return new Weapon(name, damages);
}

そのコードが書かれているところはどこでも永久にWeaponに結合されます。 Weaponクラスがないと、上記のコードをコンパイルできません。 Weaponの代わりにモックオブジェクトを使用して、このコードが表示されるクラスをテストすることはできません。

最も覚えやすいルールは、newキーワードを使用してクラスXのオブジェクトをインスタンス化するとすぐに、クラスがXに結合され、ユニットテストによってクラスXのコードを変更しない限り不可能です(ただし、クラスXのコードを実際のコードに変更する必要があるため、これは非常に奇妙な単体テストになります。本番に送信する前に)。静的コードの単体テストについて詳しくは こちら をご覧ください。

1
CodingYoshi

静的インスタンス(またはいくつかの状態が関連付けられている静的関数)が悪いという考えは、それらを持つことはglobal変数(グローバル状態-理由の詳細については this を参照してくださいそれは悪い)。

コンストラクタは特別な種類の関数にすぎません。この意味でグローバル状態を操作するものではありません。 (プロトタイプベースの言語でも)インスタンスを呼び出すためにインスタンスへの参照を必要としないため、ある意味では、それを静的であると考えるか、静的であるかのように動作させることができます。その観点からは、静的なファクトリー・メソッドを持つことも同じです。したがって、グローバルな状態の引数はここでは適用されません。

1