不変/ステートレスシングルトンは悪いですか?


12

最近、シングルトンに対する何らかの革命がありましたが、それらがステートレスである場合、シングルトンに何か問題がありますか?

私は酷使の話とすべてを知っています...これはシングルトンだけでなくすべてに適用されます。


1
いいえ。シングルトンは原則として悪くはありませんが、過度に使いすぎています。
バートヴァンインゲンシェナウ

3
最近どういう意味ですか?
マノジR

5
@Joachim Sauer:なぜ交換する必要があるのですか。ステートレスであれば、直接テストできます。
m3th0dman

1
ステートレスシングルトンを使用している場合、基本的に静的ユーティリティクラスがあり、これはゴッドクラスのアンチパターンに成長する傾向があります。通常、使用するコンテキストで代わりに静的メソッドを使用できます(または、C#で拡張メソッドを使用します)。
スポイケ

回答:


12
  > Are immutable/stateless singletons bad?
  • 他の外部システムに依存していない場合は、いいえ
    • 例:文字列内でhtmlをエスケープするStringutility。
    • 理由:ユニットテストでは、これをモック/シミュレーターに置き換える必要はありません。
  • 不変/ステートレスシングルトンが他の外部システム/サービスに依存しており、ユニットテスト(分離でのテスト)を実行する場合は、 はい
    • 例:外部Tax-Calculator-Webserviceに依存するサービス。
    • 理由:このサービス(単体)で単体テストを実行するには、外部のシステム/サービスをシミュレート/モックする必要があります。

詳細については、-onion-architectureを参照してください


  • Singleton-sは、単体テストを(単独で)より困難/不可能にし、
  • 隠された依存関係/カップリングは、@ yBeeによって説明されているように問題と見なすことができます。

シングルトンを使用しない他の理由はわかりません。


クラスを(ステートレス)シングルトンでなくても、クラスをテストする場合は、その外部Webサービスをモックする必要があります。
m3th0dman

@ m3th0dman私は同意します
k3b

10

それは常に使用法に依存します。私はすべてのプログラマは、このパターンを学習することを、革命は事実から来ていると思いますオブジェクト指向のパターン。ほとんどの人は、それが理にかなっている場所とそうでない場所について考えることを忘れています。 もちろん、これはすべてのパターンに当てはまります。パターンを使用するだけでは、優れたコードや優れたソフトウェアを作成できません。

ステートレスシングルトンがある場合、静的メソッドのみを提供するクラスを使用する(または静的クラスを使用する)のはなぜですか?

ここでは、一般的なグローバル変数とシングルトンに関する投稿があります。

私は著者ほど厳しくはありませんが、シングルトンが必要だと思われるほとんどの場合、それは本当に必要ないことを示しています。


1
クラスを静的メソッドで使用しないのはなぜですか?たとえば継承
...-m3th0dman

3
@ m3th0dman:継承のための良い場所のように聞こえません。
ビリーONeal

あなたはドメインモデルを知っていればその何かが相続のために良いか悪いかであると言うことができます@BillyONeal、...そのようにモデル化されるものです
m3th0dman

2
@ m3th0dman:えー、いや。ドメインモデルについて何も知らなくても、かなり前向きになれます。継承は、多態的な動作のためのものです。しかし、シングルトンとしては、ポリモーフィックな振る舞いをするつもりはありません。
ビリーONeal

1
@ m3th0dman:シングルトンオブジェクトを取得するには、呼び出しサイトでシングルトンの名前を指定する必要があるためです。つまり、多態的な動作を使用していないということです。つまり、構成は継承よりもはるかに柔軟です。
ビリーONeal

7

静的なクラスができない不変のステートレスシングルトンができることは何もありません。

-> Instance()が作成する余分なレベルの複雑さを追加する理由はまったくありませんが、静的メソッドの単純な呼び出しはより明確で、リソースの面でより保守的で、おそらくより高速になります。

間違っているわけではありません。それを行うためのより良い方法があるということです。通常の(「ステートフル」)シングルトンが正しい方法であるシナリオがあります。シングルトンの悪さは、グローバル変数と同じ悪い結果でしばしば悪用されることですが、シングルトンの使用が単に正しい場合があります。ステートレスの場合にはそのようなケースはありません。


シングルトンにいくつかの利点があるいくつかのケースを構築できると思います。シナリオとプログラミング言語に応じて(たとえば、遅延読み込みを利用するなど)。
StampedeXV

1
@StampedeXV:はい、確かにステートフルなシングルトンです。ステートレスで不変なもの-例を聞いてみたいのですが、息を止めていません。
SF。

わかりました、ポイントがあります。そこで少し答えを一般化しました。不変のステートレスの場合、利点もありません。
StampedeXV

1
静的関数のみを持つクラスでは、大きな制限である継承/ポリモーフィズムを使用できません
...-m3th0dman

1
静的なクラスができない不変のステートレスシングルトンができることは何もありません。まあ、静的メソッドは、シングルトンができるインターフェイスを実装することはできません
Michal M

3

シングルトンの主な問題は、横断的関心事のシナリオで使用される場合、依存性と結合を特に隠蔽することです。詳細については、「シングルトンは病理学的嘘つきである」または「シングルトンが悪である理由」を参照してください。

反対側から、シングルトンの少ない状態は、乱用されていない場合に役立ち、パフォーマンスを改善します。例を考えてみましょう:

interface Interface
{
    void Method();
}

class StatelessSingleton : Interface
{
    public static readonly StatelessSingleton Instance = new StatelessSingleton();
    private StatelessSingleton() { }

    public void Method() { }
}

class User
{
    public User(Interface i) { /* ... */ }
}

ここで、StatelessSingletonはInterfaceのデフォルト実装として機能し、Userコンストラクターに配置されます。ハードコーディングされたカップリングや非表示の依存関係はありません。基礎となるインターフェースのために静的クラスを使用することはできませんが、デフォルトのインスタンスを複数作成する理由はありません。そのため、ステートレスシングルトンが適切な選択のようです。

ただし、デフォルトの実装には別のパターンを使用する必要があります。

class Implementation : Interface
{
    private readonly Action _method;

    public Implementation()
    {
        _method = new Action(() => { /* default */ });
    }

    public Implementation(Action custom)
    {
        _method = custom;
    }

    public void Method()
    {
        _method();
    }
}

StatelessSingletonに関してはパフォーマンスに影響しますが、インターフェイスの一般的な実装を構成します。IProgressインターフェイスでも同様のソリューションが使用されます。

繰り返しますが、なぜデフォルトの振る舞いの実装を複数作成できるのですか?ただし、次の2つを組み合わせることができます。

class Implementation : Interface
{
    public readonly Implementation Default = new Implementation();

    private readonly Action _method;

    private Implementation()
    {
        _method = new Action(() => { /* default */ });
    }

    public Implementation(Action custom)
    {
        _method = custom;
    }

    public void Method()
    {
        _method();
    }
}

結論として、シングルトンが役立つ場所(デフォルトとして示されている)があると思います。シングルトンの主な定義では、クラスの複数のインスタンスを作成することは許可されていません。それは原子力です。エネルギーまたは爆弾を生成できます。それは人間次第です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.