9

シングルトンとそれがなぜ悪いのかについて多くの議論があることを私は認識しています。それはこの質問の目的ではありません。シングルトンの欠点を理解しています。

シングルトンを使用するのが簡単で、理にかなっているように見えるシナリオがあります。ただし、多くのオーバーヘッドなしで必要なことを達成できる代替手段が必要です。

私たちのアプリケーションは、通常、現場のラップトップで実行され、バックエンド サーバーと通信するクライアントとして設計されています。メイン アプリケーションの下部にステータス バーがあります。さまざまな像や情報、およびいくつかのアイコンを表示するいくつかのテキスト領域が含まれています。アイコンのイメージが変わり、状態が示されます。接続されているかどうか、およびエラー状態を示す GPS アイコンなど。

メイン クラスは MobileMain と呼ばれます。ステータス バー領域を所有し、その作成を担当します。次に、StatusBarManager クラスがあります。StatusBarManager は現在静的クラスですが、シングルトンになることもあります。さあ、授業の始まりです。

public static class StatusBarManager
{
    static ScreenStatusBar StatusBar;

    /// <summary>
    /// Creates the status bar that it manages and returns it.
    /// </summary>
    public static ScreenStatusBar CreateStatusBar()
    {
        StatusBar = new ScreenStatusBar();
        return StatusBar;
    }

MobileMain は StatusBarManager に StatusBar を要求します。次に、StatusBar を使用します。他のクラスは StatusBar を認識せず、StatusBarManager のみを認識します。

ステータス バーの更新は、アプリケーションのほぼどこからでも行うことができます。ステータス バーのテキスト領域を更新できる約 20 のクラスと、アイコンの状態を更新する追加のクラスがあります。

StatusBar と StatusBarManager はそれぞれ 1 つだけです。

より良い実装のための提案はありますか?

私が持っていたいくつかの考え:

StatusBarManager をインスタンス クラスにします。私の MobileMain クラスでは、StatusBarManager クラスの静的パブリック インスタンスを保持します。次に、ステータス バーの更新を行うには、MobileMain.StatusBarManager.SetInformationText またはマネージャーの他のメソッドを呼び出します。StatusBarManager はシングルトンではありませんが、MobileMain はその静的インスタンスを作成するだけです。ここでの問題は、MobileMain が StatusBar と StatusBarManager を持つようになったことです。これは、所有する StatusBar を管理するだけです。また、所有者が異なるだけで、StatusBarManager へのグローバルに利用可能な静的インスタンスも保持しています。

もう 1 つのアイデアは、EventEggregator クラスのようなものを使用することでした。私は一度も使用したことがありませんが、それらについて読んだことがあります。コンセプトは、それがグローバルに利用可能なクラスになるということだと思います。ステータス バーを更新する各クラスでは、StatusBarUpdate イベントを発行します。StatusBarManager は、StatusBarUpdate イベントをサブスクライブする唯一のクラスであり、すべての通知を受け取ります。オブジェクトをクリーンアップするときにイベントからの登録解除に注意しないと、このアプローチでリークが発生する可能性があることを読んだことがあります。このアプローチは検討する価値がありますか?

4

5 に答える 5

3

オブジェクトを保持する静的クラスを好みます。したがって、アクセスできるオブジェクトの量は、静的クラスが提供するインターフェースによって制限されます。アプリケーションがまだスケーリングしている限り、静的は悪くありません。

シングルトンに代わるもう 1 つの優れた方法は、Monostate パターンです。このパターンでは、「シングルトン」の動作を表すプライベートな静的フィールドを実装するクラスがあります。

参照:
モノステート モノ
ステートとシングルトン

更新: 内部プログラム構造であっても、API のような REST を念頭に置いておくと役立つことがよくあります。どこからでも更新され、全員に通知を送信する 1 つのクラスを持つことは、昇格条件と無限ループ (更新 -> イベント -> 更新 -> ...) に関して制御が困難です。

必要な場所にアクセスできる (静的または非静的) ステータス バー インターフェイスを構築します。ステータス バー インターフェイスにアクセスする Static クラスを使用するか、依存性注入を使用する場合はそのような手法を使用します (小規模なプロジェクトにはお勧めしません)。ステータス バー インターフェイスへのすべての呼び出しは、ステータス バーによって発生する可能性のあるイベントから独立している必要があります。これにより、発生条件に関するさらなる問題が回避されます。ステータス バー インターフェイスは、プログラムの他の部分から呼び出して情報をプッシュおよびプルできる Web サイトのようなものだと考えてください。

于 2012-05-02T12:21:45.223 に答える
2

StatusBar クラスまたは StatusBarManager クラスがあるかどうかは大した問題ではありません。しかし、多くのクラスに StatusBars と StatusBarManagers を認識させることは、悪い考えです。強い結合が発生し、いつか痛みを伴う可能性があります。

どのように?

現在ステータス バーにステータスを報告しているコンポーネントを、テキスト コンソールを使用してステータスを報告する別のアプリで再利用する必要があると想像してみてください。- 複数の場所にステータスを報告しますか? または - ステータスがまったく報告されない!

最良の代替手段: -イベントのリッスン。クラス (コールバックを使用できます)、またはおそらくクラスが共通に持つ既存の共有リソースで Status Changed イベントを公開します。ステータス バーなどの他の関係者は、イベントをサブスクライブできます。そして、あなたが言及したように、リークを防ぐために、サブスクリプションが不要/有効でなくなったときはいつでもサブスクリプションを解除する必要があります!

-WPFにタグを付けたので、依存関係プロパティ「StatusText」を持つWPFは、別の魅力的なオプションのように見えるかもしれません.複数のステータスプロパティがある場合、このアプローチでは、どれが最も多くを伝えているかを把握する方法が必要です.今すぐステータス バーに表示する必要がある興味深いステータスです。バインディング、マルチバインディング (blech、複雑さ)、または依存関係プロパティが変更されたイベント ハンドラーである可能性があります。

ただし、DependencyObjects と DependencyProperties をできるだけ UI レイヤーに限定することをお勧めします。その理由は、UI スレッドの Dispatcher に暗黙的に依存しているため、UI 以外の雑用には簡単に適応できないためです。

アプリには多くの異なる部分があるため、ある場所と別の場所を使用して、これらの両方を組み合わせた方が合理的であることに気付くかもしれません。

于 2012-05-03T07:17:47.203 に答える
1

Observerパターンを使用StatusBarして、20個のオブジェクトにリスナーとして追加するだけです。これにより、シングルトンが排除され、SRPとDIPに準拠するようになりますが、努力する価値があるかどうかを検討する必要があります。間接参照によって複雑さが増し、依存性注入が不可能な場合は、シングルトンの方が適している可能性があります。

public class StatusBar implements StatusListener {
}

public interface StatusListener {
   public statusChanged(String newStatus)
}
于 2012-05-02T13:38:05.307 に答える
0

クラスは、暗黙的にシングルトンの使用に依存し、コンストラクター内のパラメーターに明示的に依存します。シングルトンにインターフェイスを追加することをお勧めします。そうすれば、必要なメソッドだけがIStatusBarを使用してクラスに公開されます。これはより多くのコードですが、単体テストが容易になります。

于 2012-06-18T15:29:14.907 に答える
-1

アプリケーションのアーキテクチャを詳しく知らずにアドバイスを与えることは困難ですが、おそらく依存性注入を検討する必要があります。たとえば、StatusBar インスタンスを直接使用する各クラスのコンストラクターに渡します。

于 2012-05-02T13:16:25.650 に答える