アプリケーションのブラウザ実装クラスを定義しているとしましょう:
class InternetExplorerBrowser : IBrowser {
private readonly string executablePath = @"C:\Program Files\...\...\ie.exe";
...code that uses executablePath
}
executablePath
これは、データがそれを使用するコードの近くにあるため、一見すると良いアイデアのように見えるかもしれません。
問題は、外国語の OSexecutablePath
を搭載した別のコンピューターでこの同じアプリケーションを実行しようとしたときに発生します。値が異なります。
AppSettings シングルトン クラス (またはそれに相当するもの) を使用してこれを解決できますが、私のクラスが実際にこの AppSettings クラスに依存していることを誰も知りません (これは DI アイデアに反します)。単体テストにも問題が生じる可能性があります。
executablePath
コンストラクターを介して渡されることで、両方の問題を解決できました。
class InternetExplorerBrowser : IBrowser {
private readonly string executablePath;
public InternetExplorerBrowser(string executablePath) {
this.executablePath = executablePath;
}
}
しかし、これは私のComposition Root
(必要なすべてのクラスの配線を行うスタートアップメソッド)で問題を引き起こします.
class CompositionRoot {
public void Run() {
ClassA classA = new ClassA();
string ieSetting1 = "C:\asdapo\poka\poskdaposka.exe";
string ieSetting2 = "IE_SETTING_ABC";
string ieSetting3 = "lol.bmp";
ClassB classB = new ClassB(ieSetting1);
ClassC classC = new ClassC(B, ieSetting2, ieSetting3);
...
}
}
これは簡単に大きな混乱になります。
代わりにフォームのインターフェースを渡すことで、この問題を回避できます
interface IAppSettings {
object GetData(string name);
}
何らかの設定が必要なすべてのクラスに。次に、これを、すべての設定が埋め込まれた通常のクラスとして実装するか、XML ファイルからデータを読み取るクラスとして実装します。これを行う場合、システム全体の一般的な AppSettings クラス インスタンスを用意する必要がありますか?それとも、AppSettings クラスを必要とする各クラスに関連付ける必要がありますか? それは確かに少しやり過ぎのようです。また、すべてのアプリケーション設定を同じ場所に置くことで、プログラムを別のプラットフォームに移行しようとするときに必要なすべての変更を簡単に確認できます。
この一般的な状況にアプローチする最善の方法は何でしょうか?
編集:
またIAppSettings
、すべての設定がハードコードされた を使用する場合はどうでしょうか。
interface IAppSettings {
string IE_ExecutablePath { get; }
int IE_Version { get; }
...
}
これにより、コンパイル時の型安全性が可能になります。インターフェイス/具象クラスが大きくなりすぎた場合は、フォームの他の小さなインターフェイスを作成できますIMyClassXAppSettings
。中規模/大規模プロジェクトでは負担が大きすぎますか?
また、AOP と、分野横断的な懸念に対処するその利点についても読んだことがあります (これはその 1 つだと思います)。この問題の解決策も提供できませんでしたか? たぶん、次のような変数のタグ付け:
class InternetExplorerBrowser : IBrowser {
[AppSetting] string executablePath;
[AppSetting] int ieVersion;
...code that uses executablePath
}
次に、プロジェクトをコンパイルするときに、コンパイル時の安全性も確保します (データを織り込むコードを実際に実装したことをコンパイラーにチェックさせます)。もちろん、これにより、API がこの特定のアスペクトに結び付けられます。