Click here to Skip to main content
Click here to Skip to main content

Tagged as

Multiton Design Pattern in Delphi

, 19 Dec 2012
Rate this:
Please Sign up or sign in to vote.
The multiton is somewhat an extension of the singleton pattern.

The multiton is somewhat an extension of the singleton pattern. It is referred as registry of singletons by the GOF. I don’t know for sure who appointed the name multiton: it’s an analogy derived from the term singleton. So, singleton = single + ton; while multiton = multi + ton. The singleton pattern guarantees that a class has only one instance; while the multiton allows keeping multiple instances by maintaining a map of related keys and unique objects. Note that there can be only one instance per key when implementing the multiton pattern. Also, note that the key does not have to be a string value; it can be an object for example. Nonetheless, in our code sniped we will consider the key to be a string. I am going to tweak my singleton class implementation so that I can make it a multiton instead:

unit Multiton;

interface

uses
  Generics.Collections;

type
  TMultiton = class
  private
    //Private fields and methods here...

     class var _registry: TDictionary<string, TMultiton>;
  protected

  public
    class function Create(aName: string): TMultiton;
    class destructor Destroy;
    class function Lookup(aName: string): TMultiton;
   
    destructor Destroy; override;

    //Other public methods and properties here...   
  end;

implementation

{ TMultiton }

class function TMultiton.Create(aName: string): TMultiton;
begin
  if not Assigned(_registry) then
    _registry:= TDictionary<string, TMultiton>.Create;

  if not _registry.TryGetValue(aName, Result) then
  begin
    Result:= inherited Create as Self;
    _registry.Add(aName, Result);
  end;
end;

class destructor TMultiton.Destroy;
begin
   if Assigned(_registry) then
   begin
     _registry.Values.ToArray[0].Free;      
   end;
end;

class function TMultiton.Lookup(aName: string): TMultiton;
begin
  if Assigned(_registry) then
    _registry.TryGetValue(aName, Result);
end;

destructor TMultiton.Destroy;
var
  _instance: TMultiton;
  ValuesArray: TArray<TMultiton>;          
begin
  if Assigned(_registry) then
  begin
    ValuesArray:= _registry.Values.ToArray;

    _registry.Clear;
    _registry.Free;
    _registry:= nil;

    for _instance in  ValuesArray do
      if _instance <> Self then
        _instance.Free;
  end;

  inherited;
end;

end.

A few things I want you to note:

  • Instead of a single instance, we are holding a registry of instances. We do so by introducing the class variable _registry of type TDictionary<string, TMultiton>.
  • We register (create) the different instances by calling the class function Create. This function gets the key name as a parameter. A new instance is only created if no matches to the key name are found in the dictionary. If a match is found, then the corresponding value is returned from the dictionary data structure.
  • The Lookup class function allows retrieving a particular instance by giving its key name. Note that the Create function can also be used for this purpose, but it feels more natural to call Lookup for the searches, and Create for the registration (creation) of instances.
  • We have provided a regular destructor that once invoked releases all the memory: not only the current multiton instance, but the whole registry.
  • We have also provided a class destructor in case that we forget to manually release the memory.
This code was compiled with Delphi XE2, but it should also work for all versions above Delphi 2009. Comments, corrections and suggestions are most welcome.
Consider reading these books about design patterns if you haven’t yet:
Design Patterns: Elements of Reusable Object-Oriented Software Head First Design Patterns Object Models: Strategies, Patterns, and Applications (2nd Edition)

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

yanniel
Software Developer Digital Rapids
Canada Canada
My name is Yanniel Alvarez Alfonso. I was born in San Antonio de los Baños, Havana Province, Cuba on October 24th, 1982.
 
I majored in Information Technology Engineering at José Antonio Echeverría Polytechnic Institute (CUJAE) in Havana City, Cuba (July 2006). After that, I got a Masters Degree in Applied Computer Science at the same University (May 2009).
 
I used to work as a professor of Information Technology at CUJAE. Right now, I work as a Software Developer in Toronto, Canada. I moved to Canada under the Skilled Worker Program on February 26th, 2010.
 
This is my personal blog: Yanniel's notes; in which I write about miscellaneous topics.
 
The link at the end of this sentence compiles an index of all the articles I have written so far about Delphi Programming.

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web01 | 2.8.140827.1 | Last Updated 19 Dec 2012
Article Copyright 2012 by yanniel
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid