ソフトウェアエンジニアリングにおいて、マルチトンパターンはシングルトンパターンを一般化したデザインパターンです。シングルトンパターンではクラスのインスタンスを1つしか作成できませんが、マルチトンパターンではマップを使用して複数のインスタンスを制御された状態で作成できます。
アプリケーションごとに単一のインスタンスを持つ(例えば、Javaプログラミング言語java.lang.Runtimeのオブジェクト)のではなく、マルチトンパターンはキーごとに単一のインスタンスを保証します。
マルチトンパターンは、高く評価されているオブジェクト指向プログラミングの教科書である『デザインパターン』[ 1 ]にはパターンとして明示的に記載されていません。しかし、この本では、シングルトンのレジストリを使用してシングルトンのサブクラス化を可能にする方法について説明されており[ 2 ] 、これは本質的にマルチトンパターンです。
マルチトンは同期アクセスを備えたハッシュテーブルのように見えるかもしれませんが、重要な違いが2つあります。まず、マルチトンではクライアントがマッピングを追加することはできません。次に、マルチトンはnullまたは空の参照を返すことはなく、代わりに、関連付けられたキーを持つマルチトンインスタンスを最初の要求時に作成して格納します。同じキーを持つ後続の要求では、元のインスタンスが返されます。ハッシュテーブルは単なる実装の詳細であり、唯一のアプローチではありません。このパターンは、アプリケーションにおける共有オブジェクトの取得を簡素化します。
オブジェクトプールは一度だけ作成され、クラスに関連付けられたメンバー(インスタンスではなく)であるため、マルチトンはツリー構造に進化するのではなく、フラットな動作を維持します。
マルチトンは、マルチトンの単一ディレクトリ(つまり、すべてのキーが同じ名前空間にある)への集中アクセスを提供するという点で独特です。このディレクトリでは、プール内の各マルチトンインスタンスが独自のステートを持つことができます。このようにして、このパターンは、システムにとって不可欠なオブジェクト(例えば、 LDAPシステムが提供するようなもの)のインデックス付きストレージを推奨しています。ただし、マルチトンは、多数の分散システムではなく、単一システムでの広範な利用に限定されます。
このパターンは、シングルトンパターンと同様に、アプリケーションにグローバル状態を導入するため、単体テストをはるかに困難にします[ 3 ] 。
ガベージコレクション機能を持つ言語では、オブジェクトへのグローバルな強い参照が導入されるため、メモリリークの原因となる可能性があります。
Javaでは、マルチトンパターンは列挙型を用いて実装でき、その型の値はインスタンスに対応します。単一の値を持つ列挙型の場合は、シングルトンパターンになります。
C#では、次の例に示すように、列挙型を使用することもできます。
名前空間Wikipedia.Examples ;using System ; using System.Collections.Generic ;public enum MultitonType { Zero , One , Two }public class Multiton { private static readonly Dictionary < MultitonType , Multiton > instances = new ();private MultitonType型;private Multiton ( MultitonType type ) { this.type = type ; }public static Multiton GetInstance ( MultitonType type ) { // 遅延初期化 (記述どおりではスレッドセーフではありません) // スレッドセーフが必要な場合は、ダブルチェックロックの使用を推奨しますif ( ! instances . TryGetValue ( type , out Multiton instance )) { instance = new ( type );インスタンス.Add ( type , instance ) ; }return instance ; }public override string ToString () { return $"私の型は{this.type}です" ; }// 使用例public static void Main ( string [] args ) { Multiton m0 = Multiton . GetInstance ( MultitonType . Zero ); Multiton m1 = Multiton . GetInstance ( MultitonType . One ); Multiton m2 = Multiton . GetInstance ( MultitonType . Two );Console.WriteLine ( m0 ) ; Console.WriteLine ( m1 ) ; Console.WriteLine ( m2 ) ; } }