5

私は真剣にシングルトンを検討している私の設計のポイントに到達しました。

goto誰もが知っているように、"一般的な" 議論は "絶対にやらないでください! ひどい!" であり、あたかもコードにたくさんのステートメントを散らかしたかのようです。

ServiceStackは素晴らしいフレームワークです。私自身と私のチームはそれを気に入っており、複雑な Web サービス ベースのインフラストラクチャを実装する必要があります。私は非同期設計を奨励しており、可能な場合SendAsyncはサービス スタック クライアントで使用しています。

これらすべての異なるシステムが異なることを行っていることを考えると、共通のロガーが必要だと思いました (Web サービスが利用できない場合、ローカル テキスト ファイルへのフォールバックを備えた、実際にはそれ自体が Web サービスです)。 - 例えば、何人かの悪魔が建物に忍び寄っている)。私は依存性注入の大ファンですが、「このロガークライアントを使用する」への参照をすべての非同期リクエストに渡すことは (少なくとも私には) クリーンではないようです。

ServiceStack の失敗のシグネチャがFunc<TRESPONSE, Exception>(そして私はこれに問題はありません) であることを考えると、最初に呼び出しを行った外側のメソッドが有効なハンドルを持っているかどうかさえわかりません。

ただし、この時点で単一のロガーがあった場合、世界のどこにいても、どのスレッドにいても、無数の無名関数のどの部分にいても問題ありません。

これは受け入れられた有効なケースですか、それとも非引数ですか - シングルトンでダウンですか?

4

4 に答える 4

3

ロギングは、シングルトンにするのが理にかなっている領域の 1 つであり、コードに副作用を与えるべきではなく、ほとんどの場合、同じロガーをグローバルに使用する必要があります。Singleton を使用する際に最初に考慮する必要があるのは ThreadSafety です。これは、ほとんどの Logger の場合、デフォルトで ThreadSafe になっています。

ServiceStack の Logging APIを使用すると、次のように App_Start でグローバルに構成することにより、代用可能な Logging 実装を提供できます。

LogManager.LogFactory = new Log4NetFactory(configureLog4Net:true);

この時点で、すべてのクラスが上記の Factory で定義された Log4Net のロガーにアクセスできるようになります。

class Any
{
    static ILog log = LogManager.GetLogger(typeof(Any));
}

すべてのテスト プロジェクトで、すべてをコンソールに記録したいので、次のように一度設定するだけです。

LogManager.LogFactory = new ConsoleLogFactory();

デフォルトでは、ServiceStack.Logging は、各ログ エントリを無視する無害な NullLogger にログを記録します。

于 2013-04-24T21:18:51.813 に答える
3

シングルトンの従来の実装には 1 つだけ問題があります。簡単にアクセスでき、直接使用を誘発し、強い結合や神のオブジェクトなどにつながります。

古典的な実装では、私はこれを意味します:

class Singleton
{
   public static readonly Singleton Instance = new Singleton();
   private Singleton(){}
   public void Foo(){}
   public void Bar(){}
}

オブジェクトのライフサイクル戦略の観点からのみシングルトンを使用し、IoC フレームワークにこれを管理させ、疎結合を維持する場合、アプリケーションの存続期間全体でクラスのインスタンスを「1 つだけ」持つことに問題はありません。スレッドセーフであることを確認してください。

于 2013-04-24T21:05:53.083 に答える
0

いつものように、私は工場を持つことを好みます。このようにして、将来実装を変更し、クライアント契約を維持できます。

シングルトンの実装も変更される可能性があると言えますが、ファクトリはより一般的です。たとえば、ファクトリは任意の有効期間ポリシーを実装し、時間の経過またはニーズに応じてこのポリシーを変更できます。一方、これはシングルトンに異なるライフタイム ポリシーを実装することは技術的に可能ですが、その場合に得られるものはおそらく「シングルトン」ではなく、「特定のライフタイム ポリシーを持つシングルトン」と見なされるべきです。そして、これはおそらくそれと同じくらい悪いことです。

シングルトンを使用するときはいつでも、最初にファクトリを検討します。ほとんどの場合、ファクトリはシングルトンよりも優先されます。ファクトリが本当に気に入らない場合は、静的クラス (静的メソッドのみを持つステートレス クラス) を作成します。おそらく、オブジェクトは必要なく、メソッドのセットだけが必要です。

于 2013-04-24T20:59:03.083 に答える
0

アプリケーション コードが呼び出す静的ファサードの背後に共通のログを配置する場合は、そのコードを実際に単体テストする方法を自問してください。これは依存性注入が解決しようとしている問題ですが、アプリケーション ロジックを静的クラスに依存させることで、この問題を再導入しています。

他に 2 つの問題が発生している可能性があります。私があなたに質問したいのは、ログを取りすぎていないということですか、それとも SOLID の原則に違反していないということですか。

私は、これらの 2 つの質問について説明する SO 回答を 1 年前に書きました。読むことをお勧めします。

于 2013-04-24T20:58:12.313 に答える