В розробці програмного забезпечення, шаблон проєктування мультитон або пул одинаків схожий на шаблон одинак, який дозволяє створювати лише один екземпляр об’єкта, але розширює його можливістю впорядковувати декілька екземплярів у вигляді іменованих пар ім'я-значення.
Замість того, щоб забезпечувати наявність лише одного об'єкта в програмі, мультитон гарантує існування лише одного входження з відповідним ключем.
Мультитон можна використовувати в випадку, коли необхідно забезпечити доступ до конкретного набору даних із різних місць програми. Інший випадок - взаємодія з апаратним обладнанням через екземпляри одного і того самого класу. Наприклад, обмін даними з мережею контролерів, опитування серверів або робочих станцій в мережі. Всі ці приклади об'єднує одне: кількість екземплярів може бути обмежена (і навіть повинна бути обмежена) і вони глобальні для всієї програми.
Даний шаблон можна розглядати навіть як об'єднання ідеї шаблону одинака і пулу об'єктів. Виходячи з цього можна визначити його властивості:
Порівняння з іншими подібними шаблонами проєктування:
using System.Collections.Generic; using System.Collections.Concurrent; namespace MyApplication { public class Multiton<T> // generic multition. { private static readonly ConcurrentDictionary<object, T> _instances = new ConcurrentDictionary<object, T>(); private Multiton() { } public static T GetInstance(object key) { return _instances.GetOrAdd(key, (k) => new Multiton()); } } }
Реалізація взята з StackOverflow [Архівовано 27 серпня 2014 у Wayback Machine.]
#ifndef MULTITON_H #define MULTITON_H #include <map> #include <string> template <typename T, typename Key = std::string> class Multiton { public: static void destroy() { for (typename std::map<Key, T*>::const_iterator it = instances.begin(); it != instances.end(); ++it) delete (*it).second; instances.clear(); } static T* getPtr(const Key& key) { typename std::map<Key, T*>::const_iterator it = instances.find(key); if (it != instances.end()) { return (T*)(it->second); } T* instance = new T(); instances[key] = instance; return instance; } static T& getRef(const Key& key) { return *getPtr(key); } protected: Multiton() {} ~Multiton() {} private: Multiton(const Multiton&) {} Multiton& operator= (const Multiton&) { return *this; } static std::map<Key, T*> instances; }; template <typename T, typename Key> std::map<Key, T*> Multiton<T, Key>::instances; #endif // приклад використання class Foo : public Multiton<Foo> {}; Foo& foo1 = Foo::getRef("foobar"); Foo* foo2 = Foo::getPtr("foobar"); Foo::destroy();
Алан Шаллоуей, Джеймс Р. Тротт. Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию = Design Patterns Explained: A New Perspective on Object-Oriented Design. — М. : «Вильямс», 2002. — 288 с. — ISBN 0-201-71594-5.