皆さんこんにちは。長い間更新していませんでしたが、今日は最も基本的なデザイン パターンであるシングルトン パターンを追加します。このシングルトン モデルは本当に私の心の結び目です. 2021 年末頃に Jingdong アルゴリズムの投稿にインタビューしました. インタビュアーは私にシングルトンを書くように頼みました. ハハハハ, すべてが最良の配置であることを覚えておいてください. この記事では、シングルトン モードについて簡単に紹介し、シングルトン モードのログの実装について説明します。
目次
第二に、ロギングを実現するためのシングルトンモード(Singleton Logger)
1.シングルトンモードの簡単な紹介
1.1 基本的な紹介
シングルトン モードでは、プログラム内にインスタンスが 1 つだけ存在することが保証され、そのインスタンスにアクセスするためのグローバル アクセス ポイントが提供されます. 実際、シングルトン モードではクラス オブジェクトは 1 つしか存在できません. マルチスレッドの考え方とは逆です.リソースの運用を確保するため。たとえば、ログシステムは時間を記録する必要があり、マルチスレッドの場合は面倒です。
Singleton パターンを実装するための鍵は、外部コードが複数のインスタンスを作成するのを防ぐために、コンストラクターを非公開にする必要があることです。同時に、インスタンスを取得する静的メソッドを提供する必要があります. このメソッドは、インスタンスが既に存在するかどうかをチェックし、存在する場合はこのインスタンスを返し、存在しない場合は新しいインスタンスを作成して返します.
以下は、単純な C++ シングルトン パターンのサンプル コードです。
class Singleton {
public:
static Singleton* GetInstance() {
if (instance_ == nullptr) {
instance_ = new Singleton();
}
return instance_;
}
void DoSomething() {
// ...
}
private:
Singleton() {
// ...
}
static Singleton* instance_;
};
Singleton* Singleton::instance_ = nullptr;
1.2 シングルトン モードの使用シナリオ
- 構成マネージャー: アプリケーションでは、複数の場所で構成情報にアクセスする必要がある場合があり、これらの構成情報は通常読み取り専用です。シングルトン モードを使用すると、構成情報が 1 回だけ読み込まれると同時に、構成情報にアクセスするためのグローバル アクセス ポイントが提供されます。
- ロガー: アプリケーションでは、ログ情報を複数の場所に記録する必要がある場合があります。通常、ロガーは 1 つだけです。シングルトン パターンを使用すると、ロガーが 1 つだけ作成され、ログ情報を記録するためのグローバル アクセス ポイントが提供されます。
- データベース接続プール: アプリケーションでは、データベースに接続する必要がある場所が多数ある場合があり、データベース接続は通常、限られたリソースです。データベース接続プールは、シングルトン モードを使用して実装できます。これにより、接続が 1 回だけ作成され、接続を取得するためのグローバル アクセス ポイントが提供されます。
- カウンター: アプリケーションでは、イベントまたは操作をカウントする必要がある場合があります。通常、これらのカウンターは 1 つだけです。シングルトン パターンを使用すると、カウンターが 1 回だけ作成されるようになり、カウントするためのグローバル アクセス ポイントが提供されます。
- キャッシュ マネージャー: アプリケーションでは、一部のデータをキャッシュする必要があり、通常、キャッシュされたデータの容量は制限されています。シングルトン パターンを使用してキャッシュ マネージャーを実装すると、キャッシュが 1 回だけ作成されるようになり、キャッシュされたデータにアクセスするためのグローバル アクセス ポイントが提供されます。
第二に、ロギングを実現するためのシングルトンモード(Singleton Logger)
#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
using namespace std;
class Logger {
private:
static Logger* instance;
ofstream logFile;
Logger() {
string filename = "log.txt";
logFile.open(filename.c_str(), ios::out | ios::app);
}
public:
static Logger* getInstance() {
if (instance == NULL) {
instance = new Logger();
}
return instance;
}
void log(string message) {
time_t now = time(0);
char* dt = ctime(&now);
logFile << dt << ": " << message << endl;
}
};
Logger* Logger::instance = NULL;
int main() {
Logger* logger = Logger::getInstance();
logger->log("Hello World!");
return 0;
}
上記のコードでは、Logger クラスにプライベート コンストラクターとプライベートな静的メンバー変数インスタンスがあります。getInstance() 関数は、Logger クラスの一意のインスタンスを返す public static メンバー関数です。インスタンスが存在しない場合は、新しいインスタンスが作成されます。log() 関数は、ログ ファイルにメッセージを書き込むために使用されます。
メイン関数では、最初に Logger インスタンスを取得し、次に log() 関数を呼び出してログを記録します。Logger クラスはシングルトン モードであるため、プログラムの実行中に存在する Logger インスタンスは 1 つだけです。そのため、log() 関数を複数回呼び出すと、同じファイルにログが記録されます。
シングルトン パターンはマルチスレッド環境で問題が発生する可能性があるため、スレッドセーフに処理する必要があることに注意してください。この例では、スレッド セーフの問題を無視し、シングル スレッド環境での実装のみを提供します。
3. まとめ
シングルトンモードは非常に難しく寂しいので、シングルトンモードを大切に扱ってください。
素敵な週末をお過ごしください。