あるオブジェクトがアプリ内に1つだけ存在するようにしたいときには、静的クラスを使うかシングルトンパターンを実装する。両者の方法とその違いなどを取り上げる。
「シングルトン」(singleton)とは、一人っ子や独身者など、1つだけの人やものを表す言葉だ。プログラミングでは、稼働中のアプリの中で1つしかないものを指す。
C#やVisual Basic(以降、VB)でシングルトンを実現するには、静的クラスを使う方法と、シングルトンパターンを実装したクラスを作る方法がある。本稿では両方を紹介する。
特定のトピックをすぐに知りたいという方は以下のリンクを活用してほしい。
なお、シングルトンパターンは.NET Frameworkバージョン1.0から利用できるが、本稿に掲載したサンプルコードをそのまま試すにはVisual Studio 2017以降が必要である。また、サンプルコードはコンソールアプリの一部であり、コードの冒頭に以下の宣言が必要となる。
using static System.Console;
Imports System.Console
静的クラス(VBではモジュール)のメンバーはアプリに唯一のものとなる(次のコード)。すなわち、静的クラスを普通に使えばシングルトンと同じことなのである。
// 静的クラス
public static class StaticClass //: BindableBase // ←静的クラスは継承を使えない
{
// 静的プロパティ:このData1はアプリに唯一のものである
public static string Data1 { get; set; }
}
' モジュール
Public Module StaticClass
'Inherits BindableBase ' ←モジュールは継承を使えない
' モジュールのプロパティ:このData1はアプリに唯一のものである
Public Property Data1 As String
End Module
「シングルトンが欲しい」というとき、たいていは静的クラス(モジュール)で代用できるのだ。
ただし、静的クラス(モジュール)では継承が使えないので、そういうときは次に説明するシングルトンパターンの実装を行う。
クラスに以下の3ステップの実装を行えばよい。
次のコードにシングルトンパターンの実装例を示す。静的クラスとの違いは、ずいぶん複雑になる代わりに、継承が使えることだ。
// シングルトンパターンを実装したクラス
public class SingletonClass : BindableBase
{
// このクラスが公開するプロパティ
private string _data1;
public string Data1
{
get => _data1;
set => base.SetProperty(ref _data1, value);
}
// 以下、シングルトンの実装
// 1. 外からはインスタンス化できないように、コンストラクタをプライベートにする
private SingletonClass()
{
// 動作確認用としてコンソールへ出力
WriteLine("SingletonClassのインスタンスが生成されました");
}
// 2. アプリに唯一のインスタンス(このクラスが初めて使われるときに生成される)
private static SingletonClass _theInstance = new SingletonClass();
// 3. インスタンスを外部に公開する静的なメソッドかプロパティを用意する
public static SingletonClass GetInstance() => _theInstance;
public static SingletonClass Current => _theInstance;
}
' シングルトンパターンを実装したクラス
Public Class SingletonClass
Inherits BindableBase
' このクラスが公開するプロパティ
Private _data1 As String
Public Property Data1 As String
Get
Return _data1
End Get
Set(value As String)
MyBase.SetProperty(_data1, value)
End Set
End Property
' 以下、シングルトンの実装
' 1. 外からはインスタンス化できないように、コンストラクタをプライベートにする
Private Sub New()
' 動作確認用としてコンソールへ出力
WriteLine("SingletonClassのインスタンスが生成されました")
End Sub
' 2. アプリに唯一のインスタンス(このクラスが初めて使われるときに生成される)
Private Shared _theInstance As New SingletonClass
' 3. インスタンスを外部に公開する静的なメソッドかプロパティを用意する
Public Shared Function GetInstance() As SingletonClass
Return _theInstance
End Function
Public Shared ReadOnly Property Current As SingletonClass
Get
Return _theInstance
End Get
End Property
End Class
上のSingletonClassクラスの使い方をコンソールアプリの例で示す(次のコード)。外部からはインスタンスが作れないこと、また、繰り返しインスタンスを取得しても同一のインスタンスが返されていることを確認できる。
static void Main(string[] args)
{
//var singleton = new SingletonClass(); // コンパイルエラー(勝手にインスタンスを作れない)
WriteLine("プログラム開始");
// 出力:プログラム開始
// インスタンスを取得
var singleton1 = SingletonClass.Current;
// 出力:SingletonClassのインスタンスが生成されました
singleton1.Data1 = "singleton1に設定した値";
// もう一度、インスタンスを取得
var singleton2 = SingletonClass.Current;
WriteLine(singleton2.Data1);
// 出力:singleton1に設定した値
#if DEBUG
ReadKey();
#endif
}
Sub Main()
'Dim singleton = New SingletonClass() ' コンパイルエラー(勝手にインスタンスを作れない)
WriteLine("プログラム開始")
' 出力:プログラム開始
' インスタンスを取得
Dim singleton1 = SingletonClass.Current
' 出力:SingletonClassのインスタンスが生成されました
singleton1.Data1 = "singleton1に設定した値"
' もう一度、インスタンスを取得
Dim singleton2 = SingletonClass.Current
WriteLine(singleton2.Data1)
' 出力:singleton1に設定した値
#If DEBUG Then
ReadKey()
#End If
End Sub
シングルトンが必要なとき、多くの場合は静的クラスで足りる。継承を使いたいときなど、静的クラスで実現できないときはシングルトンパターンを実装する。
利用可能バージョン:.NET Framework 1.0以降
カテゴリ:C# 処理対象:デザインパターン
カテゴリ:Visual Basic .NET 処理対象:デザインパターン
関連TIPS:構文:メソッドやプロパティをラムダ式で簡潔に実装するには?[C# 6.0/7.0]
関連TIPS:構文:クラス名を書かずに静的メソッドを呼び出すには?[C# 6.0]
関連TIPS:VB.NETでクラス名を省略してメソッドや定数を利用するには?
関連TIPS:数値を右詰めや0埋めで文字列化するには?[C#、VB]
Copyright© Digital Advantage Corp. All Rights Reserved.