2

記事によると、シングルトンを使用しないことをお勧めします。しかし、代替またはより良い方法は何ですか?たとえば、私のGUIには、ログウィンドウがあります。操作後は、どこにいても、シングルトンを使えばログウィンドウに簡単に情報を記録できます。シングルトンは、グローバルルートを経由しますが、ショートカットを提供します。シングルトンを使用していない場合、それを行うための良い方法はありますか?操作はどこにでも散在する可能性があることに注意してください。どうもありがとう!

4

2 に答える 2

3

おそらく機能する可能性のある最も単純なことを行います。私の経験では、ロギングを行う最も簡単な方法は、無料の関数を使用することです。

void logError(const std::string& message);
void logWarning(const std::string& message);
void logInfo(const std::string& message);

たぶん、実装は単なるグローバルであり、そうではないかもしれません。どのように実装するかは問題ではありません。実装方法に基づいて異なるコードを記述しないことが重要です。公開されているインターフェースに焦点を当てます。

IMHO、シングルトンは後で変更するのが難しいので悪いです。それらが実装される方法のためではなく、それらの背後にシングルトンが存在することのみを許可するインターフェースに向かう傾向があるためです。それを変えるのは難しいです。変更が難しい場合は、維持に多くの費用がかかります。

于 2013-01-27T05:00:58.730 に答える
2

シングルトンについては、いくつかの一般的な誤解があります。

1つ目は、償還機能があり、便利であるということです。間違い。それはがらくたです。

2つ目の誤解は、「オブジェクトが1つしかない」という意味です。いいえ。これは、「オブジェクトは1つしか存在できないというルールを適用する」という意味です。それは同じことではありません。

Gang of Four Design Patternsブックのシングルトンパターンは、オブジェクトの作成方法に関連する役割があるため、「作成パターン」です。いわゆるパターンの目的は、オブジェクトの単一のグローバルインスタンスを提供し、他のインスタンスが作成されないようにすることですたとえば、コンストラクターをプライベートにし、 1つのインスタンスのみを作成できる単一の静的関数を提供します。(1つのタイプに2つの責任があるという事実は、それが壊れている手がかりになるはずです。単一責任の原則に違反します。)

単一のグローバルインスタンスが必要な場合は(設計が不十分な場合の兆候かもしれませんが)、作成するだけで非常に簡単に行うことができます。その場合、「ルールを適用できるのは1つだけ」というプロパティは必要ないため、シングルトンの「パターン」は必要ありません。

「1つしかない」という意味で「シングルトンだ」と言う人が多すぎます。これは、「言語規則を使用して、 1つしか存在できないことを保証している」と同じではありません。

または、グローバル変数を持つことを正当化するかのように、「私はシングルトンを持っています」と言います。それに派手な名前を付けることは、がらくたのデザインを許しません。

1つのインスタンスが必要な場合は、1つのインスタンスを作成します。それらをこれ以上作成しないでください。ビンゴ、あなたは1つのインスタンスを持っています。簡単。プログラムの他のビットがそのインスタンスにアクセスする方法を制御できない場合、プログラムはすでに壊れています。コードを修正します。タイプの単一のインスタンスに依存するのをやめます。他のインスタンスが作成されないようにしても、設計上の問題は解決されません。問題が悪化するだけです。

これはJustCreateOneパターンです。

多くのコードがそのオブジェクトにアクセスする必要がある場合は、依存関係が明示的になるように(コンストラクターまたは関数の引数を介して)コードに渡します。これは、上記のパターンからのパラメータ化です。

ロギングモジュールの場合、ログを記録するコードは、「シングルトン」(つまり、複数のインスタンスを持つことができないタイプ)にログを記録することを気にしないでください。渡されたロガーにログを記録するか、次の方法でログを記録する必要があります。「シングルトン」である必要のないグローバル関数またはオブジェクトは、1つしかないグローバルにすることができます。std::coutルールを1つだけ適用して呼び出すコードを記述しますstd::cout::instance()か、それともグローバルであると受け入れて使用しますか?電話をかけるのですprintf::instance()("%s", ...)か、それとも単にprintf実装者にprintfそれがどのように機能するのか心配させますか?

于 2013-01-27T05:00:42.233 に答える