2008-08-15 19 views
2

私が現在取り組んでいるデータベースアプリケーションは、あらゆる種類の設定をデータベースに保存します。これらの設定のほとんどは、特定のビジネスルールをカスタマイズするためのものですが、そこには他にもいくつかのものがあります。グローバルアプリケーション設定へのアクセス

アプリには、特定のタスク(具体的には複雑な計算など)を行うオブジェクトが含まれています。これらの非UIオブジェクトはユニットテストされていますが、それらのグローバル設定の多くにもアクセスする必要があります。これを実装したのは、実行時にApplication Controllerによって満たされるオブジェクトのプロパティを与えることです。テスト時には、テストでオブジェクトを作成し、テスト用の値を入力します(データベースからではありません)。

これはすべてのオブジェクトにグローバルが必要な場合よりも優れています設定オブジェクト---もちろん、ユニットテストは不可能です:)短所は、それらのプロパティをサブオブジェクトに '浸透させる'必要があるかどうかを判断する必要があります。

一般的な質問はです:グローバル変数を必要とせずに、プロジェクト内のグローバルアプリケーション設定にどのようにアクセスして、コードを単体テストできますか?これは100の時代に解決された問題でなければなりません...

(注:経験豊かなプログラマーではありませんが、気づいたことがありますが、私は学ぶことが大好きです!

答えて

1

Martin Fowlers ServiceLocatorパターンを使用できます。 PHPでは、次のようになります。

class ServiceLocator { 
    private static $soleInstance; 
    private $globalSettings; 

    public static function load($locator) { 
    self::$soleInstance = $locator; 
    } 

    public static function globalSettings() { 
    if (!isset(self::$soleInstance->globalSettings)) { 
     self::$soleInstance->setGlobalSettings(new GlobalSettings()); 
    } 
    return self::$soleInstance->globalSettings; 
    } 
} 

本番のコードは、このようなサービスロケータを初期化:テストコードで

ServiceLocator::load(new ServiceLocator()); 

を、あなたはこのようなあなたのモック設定を挿入します

ServiceLocator s = new ServiceLocator(); 
s->setGlobalSettings(new MockGlobalSettings()); 
ServiceLocator::load(s); 

テスト目的で交換できるシングルトンのリポジトリです。

0

これは、通常、iniファイルまたはXML設定ファイルによって処理されます。次に、あなたはちょうどneeed時の設定を読み込むクラスを持っています。

.NETにはConfigurationManagerクラスが組み込まれていますが、実装が簡単で、テキストファイルを読み込んだり、XMLをDOMに読み込んだり、コードで手作業で解析したりするのは簡単です。

データベースに設定ファイルを置いても問題はありませんが、データベースに結び付けて、ini/xmlファイルで解決されるアプリケーションの依存関係を追加します。

0

私はこれをしなかった:

public class MySettings 
{ 
    public static double Setting1 
     { get { return SettingsCache.Instance.GetDouble("Setting1"); } } 

    public static string Setting2 
     { get { return SettingsCache.Instance.GetString("Setting2"); } } 
} 

私は、円形の依存関係を持つすべての問題を取り除くために別のインフラストラクチャモジュールでこれを置きます。
これを行う特定の設定方法に縛られておらず、アプリケーションコードに大混乱を引き起こす文字列がありません。

1

サービスロケータパターンの設定アクセスをモデル化するのが好きです。これにより、私が必要とする設定値を得るための単一のポイントが得られ、別のライブラリのアプリケーションの外に置くことで、再利用とテスト容易化が可能になります。ここでいくつかのサンプルコードですが、私はあなたが使用している言語がわからないが、私はC#でそれを書いた。

まず、私は自分のConfigurationItemをモデリングするジェネリッククラスを作成します。

public class ConfigurationItem<T> 
{ 
    private T item; 

    public ConfigurationItem(T item) 
    { 
     this.item = item; 
    } 

    public T GetValue() 
    { 
     return item; 
    } 
} 

次に、構成アイテムのパブリック静的読み取り専用変数を公開するクラスを作成します。ここでは、ちょうどxmlである設定ファイルからConnectionStringSettingsを読み込んでいます。もちろん、より多くのアイテムについては、任意のソースから値を読み取ることができます。

ConfigurationItems.ConnectionSettings.GetValue(); 

そして、それは私がその後、キャッシュできるタイプの安全な値を返すか、私がやりたいだろう:私が使用するConfigurationItemを必要とするとき

public class ConfigurationItems 
{ 
    public static ConfigurationItem<ConnectionStringSettings> ConnectionSettings = new ConfigurationItem<ConnectionStringSettings>(RetrieveConnectionString()); 

    private static ConnectionStringSettings RetrieveConnectionString() 
    { 
     // In .Net, we store our connection string in the application/web config file. 
     // We can access those values through the ConfigurationManager class. 
     return ConfigurationManager.ConnectionStrings[ConfigurationManager.AppSettings["ConnectionKey"]]; 
    } 
} 

はその後、私はこのようにそれを呼び出します。

ここでサンプルテストです:

[TestFixture] 
public class ConfigurationItemsTest 
{ 
    [Test] 
    public void ShouldBeAbleToAccessConnectionStringSettings() 
    { 
     ConnectionStringSettings item = ConfigurationItems.ConnectionSettings.GetValue(); 
     Assert.IsNotNull(item); 
    } 
} 

は、この情報がお役に立てば幸いです。

関連する問題