構成クラス/構造:パターンまたはアンチパターン?代替案?


10

プログラムに新しい構成オプションを追加すると、多くの場合、オプションを実行する必要がある場所にオプションを取得するという点で、大量の波及効果が生じる可能性があります。私が認識しているこれに対処する3つの基本的な方法があります。

  1. すべての構成設定を、プリミティブとして明示的に必要とするプログラムの部分に渡します。これは最も明示的な方法であり、物事を最も分離する方法です。欠点は、これが冗長であり、もろいことです。

  2. 最も頻繁に使用される構成設定をグローバル/静的にします。これは最も簡単な方法ですが、距離を置いてアクションを導入し、テスト性を妨げ、構成が本当にグローバルであると仮定します(常に1つの構成のみが必要である)。

  3. プログラム全体またはプログラム内の主要な懸念事項のすべての構成オプションを含む構成クラス/構造体を作成し、これを明示的に渡します。これは、(1)より明確ではありませんが、(2)より明確です。1つの関数呼び出しのみの設定を変更する場合は、構成オブジェクトを複製して、この1つの値を変更できます。これは、テストと実際の両方で役立ちます。ただし、必要のない関数に大量の情報を渡す可能性があり、configクラス/構造体の値を変更すると、離れた場所でアクションが発生する可能性があります。

(3)パターンとアンチパターンのどちらを検討しますか?アンチパターンの場合、代わりに何をしますか?


3のバリエーションはどうですか- 複数の構成クラスがあり、適切なクラスを必要な場所に渡しますか?
2010年

@Oded:可能性を強調するつもりでした。編集。
dsimcha '18年

回答:


4

最善の解決策は、いくつかの構成インターフェースを作成し、あなたが望むようにそれらを実装することです。これにより、アクセシビリティが制限され、ローカライズが維持されます。ただし、すべての構成を1つのクラスにまとめて、さらに多くの問題が発生する問題に進むよりも、それだけの価値があるほど多くの努力が必要です。これはUtterlyCrucialAlwaysChangingClassではなく構成です。ほとんど同じままです。すべてをグローバルにせず、実装に一貫性がある限り、心配する必要はありません。


4
+1は、理論的には理想的なデザインではないものの、単純さと変更の可能性(またはその欠如)を考慮した場合、実際には優れている可能性があることを示すための+1。
dsimcha

私は4つの引数を破棄し、それを設定クラスに置き換えました。それは正しいことのように感じました。
Martin Ueding、2014年

3つのオプションのうちどれを推奨しているのかわかりません。指定していただけますか?
DBedrenko 2015

1

デカップリングによりテストが容易になり、オブジェクトが依存する構成設定が明示的にされるため、オプション1を選択します。オブジェクトが構成設定を必要とする場合は、コンストラクター引数またはセッターメソッドによってオブジェクトに明示的に提供します。依存関係注入フレームワークを使用してこれらの構成設定をオブジェクトに注入することにより、冗長性を減らします。


あなたは自分と矛盾しています。つまり、オプション1を使用すると言いますが、「依存関係注入フレームワークを使用して、これらの構成設定をオブジェクトに注入することにより、冗長性を減らします」と言います。これはオプション3:コンストラクターインジェクションです。
DBedrenko 2015

0

構成ファイルがXMLで記述されていると想像してください。次に、このXMLのフラグメントを各コンポーネントに渡すだけで、コンポーネントが構成データを取得できます。

.NETを使用している場合、DataContractsを使用してクラスを作成し、XmlSerialiserを使用して構成Xmlからオブジェクト階層を作成し、これらのオブジェクトを構成として渡すことができます。

次に、次の問題を紹介します。構成データには、3つの異なる部分があります。この特定の製品として動作するようにコードライブラリを編成する構造的なアプリケーション構成。インストール固有の設定とシステムの各ユーザーによって異なるユーザー設定/設定データを含むサイト構成設定。

どの部分がどの部分であるかを把握し、これらのデータ設定を別々にしておくと、更新を簡単にインストールできます(顧客の設定を失うことはありません)。


0

オプション#3のクラスを静的にします。だから代わりに

//create SomeCl
Foo f = new Foo();
f.setConfigInst(cfg);
...
...
//Inside Foo
public void setConfig(MyAppConfig c) { localCfg = c; }
...
//somewhere else:
x = localCfg.getConfigForX();

あなたはただ持つことができます:

//Inside Foo
x = MyAppConfig.getConfigForX();

構成データのロード/保存の詳細をMyAppConfigクラス内で発生させます。そしてもちろん、異なる目的のための異なるクラスなど、より複雑なバリエーションを持つこともできます。

このアプローチが問題となる唯一のケースは、何らかの理由で、異なる構成の複数のインスタンスを同時に処理する必要がある場合ですが、私はまだそのような状況に遭遇していません。


1
これは、一部のテストフレームワークで単体テストを実行するときにほとんど何が起こるかです...しかし、明示的な並列単体テストがなくても、グローバル状態に依存するオブジェクトを単体テストするのは面倒です。
ペーテルTörök

0

「3層(インターフェース、ビジネスロジック、データアクセス)」アプローチを使用しているプロジェクトに取り組んでいます。アプリケーションは、マルチユーザーWebサーバーまたはクライアントサーバーにすることができます。

私たちは、ユーザーが作業しているPCに最初に固有の3つの異なる構成で作業します。2番目は現在のユーザーに固有、3番目はすべてのユーザーとクライアントアプリのグローバル構成です。

各構成は、アプリケーションの各インスタンスでオブジェクトによって表されます。

このアプローチは、プロジェクトに役立つ場合があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.