0

コアクラス ライブラリ (ビジネス ロジック、データ レイヤー、およびいくつかのユーティリティ クラスを含む)、Windows サービス プロジェクト、Web サービス プロジェクト、および Web サイト プロジェクトで構成される私の Web アプリケーション (C#、.Net 3.5) には、他のすべてのプロジェクトで使用されるコアライブラリのいくつかの静的クラス。これらのクラス (たとえば、Logクラス) は、使用できるように設定するために、いくつかの初期化 ( Initializeメソッドがあります) が必要です。例として、LogクラスのInitializeメソッドには、ログ ファイルの保存先をLogに伝えるディレクトリ パス パラメーターがあります。または、ログの「設定」をロードすることを考えていました静的コンストラクターの構成ファイルからのクラス。欠点は、単体テストと本番コードで異なる設定が必要なことです。

これを設計するより良い方法はありますか?このアプローチの欠点は、静的クラスのすべてのコンシューマーが Initialize を呼び出そうとすることです。初期化されると、メソッドは Initialize コードを再度実行する代わりにすぐに戻るため、これは実際には問題ではありませんが、設計が少し奇妙に思えます。

私の英語が私が求めているものを説明するのに十分であることを願っています. 質問が十分に明確でない場合は、遠慮なく質問してください。

4

5 に答える 5

6

初期化が必要なものについては、静的クラスを避けようとします。Log クラスを通常のクラスにし、おそらくインスタンスまたは単一のインスタンスを作成するための別のファクトリ クラスを用意します。依存性注入を使用して統計を回避したい場合がありますが、これは非常に普遍的なロギングのようなものでは苦痛になる可能性があります。

特にロギングについては、log4net と log4j の両方 (なんらかの理由で独自のものを作成したことがありますか?) は、名前に基づいて (通常はそれを使用する型の名前に基づいて) ログ インスタンスのファクトリ クラスを要求するイディオムを使用します。これは、ロギングを実行する必要がある各クラスの静的変数に保存されることがよくあります。返されたロギング オブジェクトが、後でロギング サブシステムの初期化によって影響を受ける可能性がある場合、ロギング クライアントが初期化される前に DI コンテナーがロギング フレームワークを初期化する必要があるという順序の問題は発生しません。

静的クラスの代わりに個別のログ オブジェクトを使用すると、テスト容易性が向上します。テスト中にログ オブジェクトをログを記録するオブジェクトに置き換えて、(たとえば) 監査情報が確実にキャプチャされるようにすることができます。ロギング オブジェクトが静的に認識されることの欠点の 1 つは、テストを並行して実行する可能性が低下することです。

ややランダムな考えで申し訳ありません-私はまだ最初のコーヒーを飲んでいません. うまくいけば、それは役に立ちます。

于 2008-10-09T06:34:30.353 に答える
5

初期化に費用がかかる場合は、Singleton を使用することをお勧めします (設計パターンに慣れていない場合は、Google Singleton Design pattern)。インスタンスの構築の一環として、環境に固有の構成ファイルを読み込みます。

このようにして、両方の長所を最大限に活用できます。

于 2008-10-09T06:11:33.003 に答える
0

私はあなたがあなたの質問で与えた解決策のどちらでも大丈夫だと思います。MainメソッドからInitializeを1回呼び出します(または、これをMainから呼び出された別のSetupApplicationInfrastructureメソッドに入れます)。または、コンストラクターで設定を1回ロードします。

インスタンスにアクセスするたびに初期化が必要かどうかのチェックを排除しようとすることを心配する必要はないと思います。これを行うのは悪くありません。

于 2008-10-12T08:50:27.507 に答える
0

Travが言ったことに加えて...

ログのシングルトン実装に加えて、静的クラスをラップすることもできます。このようにして、静的Logクラスをすでに使用している場所を変更する必要はありません。また、単体テスト用にモックロギングフレームワークを交換するのは非常に簡単です。Javaでこの例を示します-次のようなものがあると仮定します:

public class Log
{
    public static void debug(Object o, String message)
    {
        System.out.println(o + " [DBUG] " + message);
    }

    public static void info(Object o, String message)
    {
        System.out.println(o + " [INFO] " + message);
    }
}

これは次のようにリファクタリングできます。

public interface ILoggeer
{
    void debug(Object o, String message);
    void info(Object o, String message);
}

public class Log
{
    private static ILogger log = new ConsoleLogger();

    public static setLogger(ILogger impl)
    {
        log = impl;
    }

    public static void debug(Object o, String message)
    {
        log.debug(o, message);
    }

    public static void info(Object o, String message)
    {
        log.info(o, message);
    }
}

public class ConsoleLogger implements ILogger
{
    public void debug(Object o, String message)
    {
        System.out.println(o + " [DBUG] " + message);
    }

    public void info(Object o, String message)
    {
        System.out.println(o + " [INFO] " + message);
    }
}
于 2008-10-12T17:41:50.617 に答える
-1

ここで難しい質問をする必要があると思います。そのようなものは静的である必要がありますか? シングルトン形式であろうとなかろうと、静的オブジェクトを扱うのは非常に困難です。静的性が本当に必要な場合は、おそらくモノステート パターンのようなものが役立ちます。ポリモーフィックな静的クラスのようなものです。一般に、すべてのメンバー変数は静的ですが、コンストラクターはそうではありません。おそらくこれで、このクラスを継承し、必要に応じてオーバーライドすることができます。ちょっとした考え。

于 2008-10-09T06:24:28.190 に答える