私の会社では、configクラスのDictionariesを使用してプログラムの構成と状態を追跡する複数のC#プログラムがあります。
例えば、
bool isFoo = config.GetBool("Foo");
これは、いくつかの理由で私には不格好に見えます。まず、辞書に何があるかを簡単に知る方法はありません。 ( "Foo"は有効なキーですか?まだ設定されていますか?スペルが正しいですか?ブール値ですか?)
これらのプログラムはオブジェクト指向ではありません。コーディングスタイルは、手続き型(?)に似ているようです。一般に、キーの数は多く(100程度)、2から3個の辞書がさまざまなデータ型を保持しています。
これらのプロパティを作成しない理由はありますか?例えば。 isFoo = config.Foo;
完全に書き換えずにこのコードを改善する方法はありますか?
辞書を拡張して、両方の長所を活用できます。
class ConfigDictionary : Dictionary
{
bool getFoo()
{
return getBool("Foo");
}
}
これで、メインプログラムは古い構文を使用するか、専用の事前バインドされたプロパティを使用できます。
まず、辞書に何があるかを簡単に知る方法はありません。
何故なの? if(!config.ContainsKey("Foo"))
は正常に動作するはずです。
「Foo」は有効なキーですか?
このためには、どこかに有効なキーのリストが必要です。このメタ情報をどこから取得するかは、構成のソースとそれが定義されている場所に大きく依存します。このメタ情報を構成クラスのコンテキストで1回定義するのに役立つと言う場合は、それをプロパティにすることで役立ちます。
もう設定されていますか?
そうでない場合、config.Foo
がプロパティFoo
が初期化されていないときに例外をスローするのと同じように、コードは実行時に「キーが見つかりません」例外をスローします。
スペルは正しいですか?
プロパティFoo
は、定義された場所で正しいスペルを持つと、コードの他の場所でのスペルミスを回避するのに役立ちます。
ブールですか?
繰り返しになりますが、これはプロパティが役立つことです。
これらのプロパティを作成しない理由はありますか?
理由があり、それらがあなたのケースに当てはまるかどうかを確認する必要があります。プロパティを追加すると、構成のタイプごとに個別のクラスが必要になります。そのため、さまざまなタイプの構成で機能する一般化されたコードを作成することが難しくなります。さらに、キー文字列を動的に作成するコードがある場合(たとえば、他の2つの文字列を連結する場合)、これを直接プロパティに直接マッピングすることはできません。
これは問題であるか、ケースではない可能性があります。確認する必要があります。
このような場合、私は最良の解決策は次のようなものだと思います:
_bool getBool(String key, bool defaultValue);
int getInt(String key, int defaultValue);
_
等...
これは「存在しない」という懸念をカバーします。スペルミスが懸念される場合は、キーが列挙型である可能性があります。
追加 @Robert Harveyのコメントに応じて、はい、これはあなたが「デフォルトは何であるか」を決定することを要求します。 (または、nullになる可能性のある型を使用します(例:Java Integer
の代わりにint
を使用))しかし、他の2つの解決策も同様に行います。結果のボイラープレートチェックがさらに多くなります。プロパティが存在しない場合、最終的には、デフォルトにフォールバックするか、失敗/例外をスローする必要があります。明示的にして、設計者に合理的なデフォルトを考えさせることは良いことだと思います。
言語によっては、ジェネリックなどを利用できる場合があります。たとえば、Javaでは、いくつかの型について、次のように使用できます。
<T> getConfig(String key, T defaultValue);
絶対に不可欠な構成設定の場合、例外をスローするgetRequiredValue(key)
メソッドを追加できます。
**追加**別の方法として、ディクショナリにデフォルト値を事前に入力すると、DocまたはJohnのソリューションが機能します。私の利点(または欠点)は、フォールバックのデフォルト値が動的に変化する可能性があることです。