まさるblog

越後在住子持ちプログラマー奮闘記 - Author:まさる(高野 将、TAKANO Sho)

目次

Blog 利用状況

ニュース

著書

2010/7発売


Web掲載記事

@IT

.NET開発を始めるVB6プログラマーが知るべき9のこと

CodeZine

実例で学ぶASP.NET Webフォーム業務アプリケーション開発のポイント

第1回 3層データバインドを正しく活用しよう(前編)

ブログパーツ


書庫

日記カテゴリ

コミュニティ

デザインパターンを学ぶ~その20:Singletonパターン(3)~

前回は二重チェックを用いた方法で、マルチスレッド下で正常に動作するSingletonを説明しました。

今回はもう一つの、staticコンストラクタを用いた方法を紹介します。

 

それでは、まずはいつものようにコードを掲載します。

C#

/// <summary>
/// ログ出力クラス
/// </summary>
public class SingletonLogger
{
  /// <summary>
  /// ログ出力パス
  /// </summary>
  private string _logPath;

  /// <summary>
  /// プロパティ ログ出力パス
  /// </summary>
  public string LogPath
  {
    get
    {
      return _logPath;
    }
  }

  /// <summary>
  /// コンストラクタ
  /// </summary>
  /// <remarks>new でインスタンス化できないよう、privateでコンストラクタを定義</remarks>
  private SingletonLogger()
  {
    // 重い初期化処理  
    for (var i = 0; i < 1000000000; i++)
    {
    }
    _logPath = DateTime.Now.ToString("yyyyMMddhhmmssfff") + ".log";
  }

  /// <summary>
  /// 自身の唯一のインスタンス
  /// </summary>
  private static SingletonLogger _uniqueLogger = new SingletonLogger();

  /// <summary>
  /// プロパティ インスタンス
  /// </summary>
  /// <remarks>自身の唯一のインスタンスを返す</remarks>
  public static SingletonLogger Instance
  {
    get
    {
      return _uniqueLogger;
    }
  }

  /// <summary>
  /// ログ出力
  /// </summary>
  /// <param name="message"></param>
  public void WriteLog(string message)
  {
    // ログ出力処理
    // ・・・
  }
}

VB

''' <summary>
''' ログ出力クラス
''' </summary>
''' <remarks></remarks>
Public Class SingletonLogger

  ''' <summary>
  ''' ログ出力パス
  ''' </summary>
  ''' <remarks></remarks>
  Private _logPath As String

  ''' <summary>
  ''' プロパティ ログ出力パス
  ''' </summary>
  ''' <value></value>
  ''' <returns></returns>
  ''' <remarks></remarks>
  Public ReadOnly Property LogPath() As String
    Get
      Return _logPath
    End Get
  End Property

  ''' <summary>
  ''' コンストラクタ
  ''' </summary>
  ''' <remarks>new でインスタンス化できないよう、privateでコンストラクタを定義</remarks>
  Private Sub New()
    ' 重い初期化処理  
    For i As Integer = 0 To 1000000000
    Next i
    _logPath = DateTime.Now.ToString("yyyyMMddhhmmssfff") & ".log"
  End Sub

  ''' <summary>
  ''' 自身の唯一のインスタンス
  ''' </summary>
  ''' <remarks></remarks>
  Private Shared _uniqueLogger As New SingletonLogger()

  ''' <summary>
  ''' プロパティ インスタンス
  ''' </summary>
  ''' <value></value>
  ''' <returns></returns>
  ''' <remarks>自身の唯一のインスタンスを返す</remarks>
  Public Shared ReadOnly Property Instance() As SingletonLogger
    Get
      Return _uniqueLogger
    End Get
  End Property

  ''' <summary>
  ''' ログ出力
  ''' </summary>
  ''' <param name="message"></param>
  Public Sub WriteLog(ByVal message As String)
    ' ログ出力処理
    ' ・・・
  End Sub

End Class

では、コードについて説明しましょう。ポイントは

  1. Singleton自身のインスタンス変数の宣言箇所で初期化も行う。
  2. Instanceプロパティでは、チェックを行わないで良い。

の2点です。

前回、前々回の方法ではInstanceプロパティにアクセスしたときに、その中で自身のインスタンスを作成しました。これを遅延初期化といいます。

しかし、今回は変数宣言時に初期化しており、このコードが実行されるのは、初めてSingletonのメンバにアクセスしようとした際に実行される、staticコンストラクタ(クラスコンストラクタ)の内部になります。そして、CLRではstaticコンストラクタはスレッドセーフであることが保証されるため、必ず1つしかインスタンスが作られないことになります。

ですので、2.のようにInstanceプロパティ内でのチェックは不要になります。

 

ところで、この方法は二重チェックの方法に比べて単純ですし、積極的に利用したほうが良いと感じるかもしれません。ただ一点、Singletonのメンバにアクセスしようとした際、それがInstanceプロパティでない場合でも初期化がおこなわれるため、実行時のオーバーヘッドが問題になる場合は使うべきでないときもあります。

が、最近はマシンの性能も上がっていますし、このオーバーヘッドはほぼ無視して良いでしょう。

 

ということで、Singletonについては、複雑になる二重チェックの方法ではなく、今回のstaticコンストラクタで初期化を行う手法を使っておけば、ほぼ間違いないと考えて良いのではないでしょうか。

 

さて、Singletonについて3回にわたりお送りしてきました。次回からはCommandパターンを取り上げようと思います。

投稿日時 : 2008年8月10日 23:13

Feedback

# re: デザインパターンを学ぶ~その20:Singletonパターン(3)~ 2008/08/11 8:04 さかもと

本にしたいなー、本にしてほしいなー・・・。

# re: デザインパターンを学ぶ~その20:Singletonパターン(3)~ 2008/08/11 15:35 まさる

>画伯
つ【プリントアウト】

#正直な話、私なんかよりよっぽどしっかりまとめてあるところも多いと思いますが。

# 誕生日プレゼント 2020/05/13 12:41 izdsybcejtv@live.com

ブランド偽物(コピー商品)激安市場

━…━…━…━…━…━…━…━…━…━…━…
ルイ.ヴィトン、シャネル、グッチ、エルメス、クロエ、ブラダ、ブルガリ ドルチェ&ガッバ―ナ、バレンシアガ、ボッテガ.ヴェネタ偽物(コピー商品)のブランドのバッグ、財布の販売、通販。
━…━…━…━…━…━…━…━…━…━…━…
○各種のブランド偽物(コピー商品)の指輪.ネックレス
○各種のブランド偽物(コピー商品)のベルト
○各種のブランド偽物(コピー商品)のマフラー
○ スタイルが多い、品質がよい、価格が低い!
○ S品質 シリアル付きも有り 付属品完備!
○必ずご満足頂ける品質の商品のみ販売しております.
○ 品質を最大限本物と同等とする為に相応の材質にて製作している為です.
○ 絶対に満足して頂ける品のみ皆様にお届け致します.

人気の売れ筋商品を多数取り揃えております。全て激安特価でご提供.お願いします。
誕生日プレゼント https://www.cocoejp1.com/ProductDetail.aspx?Id=202003040335325795

タイトル  
名前  
Url
コメント