Implementing the Singleton Design Pattern in Delphi without Global Variables

The purpose of this post is NOT to cover the insights and applicability of the Singleton pattern, instead  I just pretend to give you a Delphi code snipped that implements it. This implementation is focused in avoiding variables that are global to the unit (or Unit Global Variables).

Fist of all, I am borrowing the definition and UML diagram of the Singleton Design Pattern, as written in the Design Patterns: Elements of Reusable Object-Oriented Software book. I strongly suggest you to read this book if you want to have a deeper understanding of the classic design patterns.

Singleton: “Ensure a class only has one instance, and provide a global point of access to it.”

UML diagram:

UML diagram of the Singleton Design Pattern
For all Delphi versions previous to Delphi 7, the only way to implement this pattern is by using a Unit Global Variable, instead of a class static field. Fortunately, Delphi 7 featured class variables long time ago and this way, we can implement the pattern avoiding global scoped variables. For some reason, I have never seen an implementation of the Singleton pattern in Delphi using class variables, so here is my own:

unit Singleton;

interface

type
  TSingleton = class
  private
    //Private fields and methods here...
   
    (****************************************************)
    (*** Class variables were introduced in Delphi 7. ***)
    (*** Older Delphi versions should implement       ***)
    (*** this field as a unit global variable         ***)
     class var _instance: TSingleton;   
    (****************************************************)
  protected
    (*** Constructor is protected!!! ***)
    constructor Create;

    //Other protected methods here...
  public
    destructor Destroy; override;

    (********************************************)
    (*** Client code should use this function ***)

    (*** ("Instance"), instead of the         ***)
    (***
"constructor" to create (or access)  ***)
    (*** a singleton instance.                ***)
    class function Instance: TSingleton;
    (********************************************)
    

    class function NewInstance: TObject; override;

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

implementation

{ TSingleton }

constructor TSingleton.Create;
begin
  inherited Create;
end;

destructor TSingleton.Destroy;
begin
  _instance:= nil;
  inherited;
end;

class function TSingleton.Instance: TSingleton;
begin
  if (_instance = nil) then
    _instance:= TSingleton.Create;

  result:= _instance;
end;



class function TSingleton.NewInstance: TObject;
begin
  if (_instance = nil) then
    _instance:= inherited NewInstance as Self;

  result:= _instance;

end;

end.


There was a problem with my original implementation. In Delphi:
  • Constructors are inherited (this doesn't happen in C++, Java, C#, etc.)
  • All classes inherit from TObject ultimately.
As TObject has its own constructor, the consumers of the TSingleton class can call it directly, allowing this way the creation of more than one instance. Ali, writer of the first comment in this article, pointed me in the right direction.  Thanks Ali.

I traduced Ali’s words into the source code above. The strikethrough text can be removed and the text in blue was added. This implementation ensures the singleness of the Singleton Design Pattern in Delphi.

Rethinking over this once again:

The implementation above ensures the class only has one instance; but it does not provide a global point of access to it. Instead of that, we now have two points of access. Take a look at the following code snipped:

  //Point of access ONE
  SingletonObject1:= TSingleton.Create;
 
  //Point of access TWO
  SingletonObject2:= TSingleton.Instance; 

Yes, two point of access: TSingleton.Create and TSingleton.Instance.

Rethinking this many times, I figured out the simplest implementation. We don’t even need to deal with the evil NewInstance class function. It looks like this:

unit Singleton;

interface

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

     class var _instance: TSingleton;
  protected
    //Other protected methods here...
  public
    //Global point of access to the unique instance
    class function Create: TSingleton;

    destructor Destroy; override;

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

implementation

{ TSingleton }

class function TSingleton.Create: TSingleton;
begin
  if (_instance = nil) then
    _instance:= inherited Create as Self;

  result:= _instance;
end;

destructor TSingleton.Destroy;
begin
  _instance:= nil;
  inherited;
end;

end.

The only point of access to the singleton instance is the class function “Create”, which hides the TObject.Create parameterless constructor (more details here). Now we have only one instance and a global point of access to it.

The comments inside the above code are self-explanatory. Furthermore, for those stuck with older Delphi versions, the Singleton pattern should be implemented as follows:

unit Singleton;

interface

type
  TSingleton = class
  private
    //Private fields and methods here...
  protected
    //Other protected methods here...
  public
    //Global point of access to the unique instance
    class function Create: TSingleton;

    destructor Destroy; override;

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


var
  _instance: TSingleton;
//Unit Global Variable.
 

implementation
...................

As a conclusion, I would suggest avoiding unit global variables as much as possible; in fact, as a rule of thumb, I would suggest to make your variables' scope as local as possible. This applies not only to this example (implementation of the Singleton Design Pattern), but to programming in general. Furthermore, the class variables in Delphi are equivalent to static member variables in C++, Java, C#...Class variables were introduced  in Delphi 7; so, previous versions should use global variables to implement a Singleton class.

Note:
There are three books about Design Patterns I would suggest you to read:

How to implement a tag cloud. Learn by example

A tag cloud [1] is a list of terms in which each item has a corresponding weight. The weight represents the importance or popularity of each term.

Tag clouds usually have a visual representation, and the weight can be translated into a different font size, color, style, text orientation and others. Changing the appearance of each tag in the cloud allows the readers to perform a quick scan and detect the most ranked terms in the cloud.

One final consideration is that tags are generally linked to some related content. This can be achieved for example, by means of a hypertext link (...a href=...) anchored to the affine content.

There are several algorithms to implement a tag cloud; however, right now I'm going to use a fairly simple one: it just changes the font size of the tag depending on the number of occurrences per tag. The general formula (taken from Wikipedia and adjusted by me) is:

Si = |Fmax*(Ti - Tmin)/ (Tmax - Tmin)|

for |Fmax*(Ti - Tmin)/ (Tmax - Tmin)| > 90%;

else Si =90%.

Where:
  • i: is an index ranging from 1 to the total number of tags in the cloud.
  • Si: is the display font size of tag i. You need to calculate Si for each tag in the cloud.
  • Fmax: is the maximum font size value to display. This value is chosen by the user.
  • Ti: is the number of occurrences of tag i.
  • Tmin: is the minimum of all Ti values.
  • Tmax: is the maximum of all Ti values.
Too difficult to understand? Patience, you'll get there:

Consider the following list of twenty tags. The number of occurrences is shown inside red square brackets "[...]":

linda evangelista [9]
toaster [12]
brad richards [7]
max talbot [13]
fireworks [10]
library of congress [12]
bohemian grove [15]
declaration of independence [2]
17 day diet [16]
independence day [10]
white sox [5]
blaise pascal [4]
ewan mcgregor [10]
kate moss [6]
princess diana [10]
traffic [1]
janet jackson [11]
canada day [8]
scott pilgrim vs. the world [10]
paul newman [18]

For the list of tags above, the corresponding Ti values are: T1=9; T2=12; T3=7; T4=13; T5=10; T6=12; T7=15; T8=2; T9=16; T10=10; T11=5; T12=4; T13=10; T14=6; T15=10; T16=1; T17=11; T18=8; T19=10; T20=18.

Now, it's easy to see that Tmax=T20=18 and Tmin=T16=1. Finally, let's set Fmax=300% [2] and let's calculate each Si:

S1 = |300% * (9 -1) /(18-1)| = 141.17% = 141%

S2 = |300% * (12 -1) /(18-1)| = 194.11% = 194%

S3 = |300% * (7 -1) /(18-1)| = 105.88% = 106%

S4 = |300% * (13 -1) /(18-1)| = 211.76% = 212%

S5 = |300% * (10 -1) /(18-1)| = 158.82% = 159%

S6 = |300% * (12 -1) /(18-1)| = 194.11% = 194%

S7 = |300% * (15 -1) /(18-1)| = 247.05% = 247%

S8 = |300% * (2 -1) /(18-1)| = 17.64% = 18%;
as S8 = 18% < 90%, then S8 = 90%.

S9 = |300% * (16 -1) /(18-1)| = 264.70% = 265%

S10 = |300% * (10 -1) /(18-1)| = 158.82% = 159%

S11 = |300% * (5 -1) /(18-1)| = 70.58% = 71%;
as S11 = 71% < 90%, then S11 = 90%.

S12 = |300% * (4 -1) /(18-1)| = 52.94% = 53%;
as S12 = 53% < 90%, then S12 = 90%.

S13 = |300% * (10 -1) /(18-1)| = 158.82% = 159%

S14 = |300% * (6 -1) /(18-1)| = 88.23% = 88%;
as S14 = 88% < 90%, then S14 = 90%.

S15 = |300% * (10 -1) /(18-1)| = 158.82% = 159%

S16 = |300% * (1 -1) /(18-1)| = 0% = 0%;
as S16 = 0% < 90%, then S16 = 90%.

S17 = |300% * (11 -1) /(18-1)| = 176.47% = 176%

S18 = |300% * (8 -1) /(18-1)| = 123.52% = 124%

S19 = |300% * (10 -1) /(18-1)| = 158.82% = 159%

S20 = |300% * (18 -1) /(18-1)| = 300% = 300%

Using the information above we can generate HTML code like this (the line feeds were added just for readability purposes):

<a href="http://www.yanniel.info/search?q=linda+evangelista" rel="tag" style="font-size: 141%;">linda evangelista</a>

<a href="http://www.yanniel.info/search?q=toaster" rel="tag" style="font-size: 194%;">toaster</a>

<a href="http://www.yanniel.info/search?q=brad+richards" rel="tag" style="font-size: 106%;">brad richards</a>

<a href="http://www.yanniel.info/search?q=max+talbot" rel="tag" style="font-size: 212%;">max talbot</a>

<a href="http://www.yanniel.info/search?q=fireworks" rel="tag" style="font-size: 159%;">fireworks</a>

<a href="http://www.yanniel.info/search?q=library+of+congress" rel="tag" style="font-size: 194%;">library of congress</a>

<a href="http://www.yanniel.info/search?q=bohemian+grove" rel="tag" style="font-size: 247%;">bohemian grove</a>

<a href="http://www.yanniel.info/search?q=declaration+of+independence" rel="tag" style="font-size: 90%;">declaration of independence</a>

<a href="http://www.yanniel.info/search?q=17+day+diet" rel="tag" style="font-size: 265%;">17 day diet</a>

<a href="http://www.yanniel.info/search?q=independence+day" rel="tag" style="font-size: 159%;">independence day</a>

<a href="http://www.yanniel.info/search?q=white+sox" rel="tag" style="font-size: 90%;">white sox</a>

<a href="http://www.yanniel.info/search?q=blaise+pascal" rel="tag" style="font-size: 90%;">blaise pascal</a>

<a href="http://www.yanniel.info/search?q=ewan+mcgregor" rel="tag" style="font-size: 159%;">ewan mcgregor</a>

<a href="http://www.yanniel.info/search?q=kate+moss" rel="tag" style="font-size: 90%;">kate moss</a>

<a href="http://www.yanniel.info/search?q=princess+diana" rel="tag" style="font-size: 159%;">princess diana</a>

<a href="http://www.yanniel.info/search?q=traffic" rel="tag" style="font-size: 90%;">traffic</a>

<a href="http://www.yanniel.info/search?q=janet+jackson" rel="tag" style="font-size: 176%;">janet jackson</a>

<a href="http://www.yanniel.info/search?q=canada+day" rel="tag" style="font-size: 124%;">canada day</a>

<a href="http://www.yanniel.info/search?q=scott+pilgrim+vs.+the+world" rel="tag" style="font-size: 159%;">scott pilgrim vs. the world</a>

<a href="http://www.yanniel.info/search?q=paul+newman" rel="tag" style="font-size: 300%;">paul newman</a>

That HTML code renders a tag cloud like the one below:


Notice that if you click on a tag it will search any related content withing my blog. Try it!

Notes:
[1] A tag cloud is also referred as a word cloud or weighted list. In this context, tag is a synonym of term; sometimes even a synonym of word. Nevertheless, I don't like the latest assumption, because the practical experience shows that a tag can be formed using two words or more.
[2] You can chose whatever value you want for this parameter. However, depending on what you set, the appearance of the tags in the cloud might vary.

Configuring a Dynadot's domain for a Blogger's blog

In the very beginning, this blog was published on blogspot.com. The original Blog*Spot Address was something like this: subdomain.blogspot.com. At some point, I decided to publish this blog on my own domain and so I registered www.yanniel.info at Dynadot.

After registering my domain, I needed to configure both my Blogger and Dynadot (DNS) settings. This is how:

Configuring Dynadot settings:
  1. Log into your  Dynadot account using your username and password.
  2. Click the DOMAINS tab in the main menu. The main menu looks like this: SUMMARY | DOMAINS | SEARCH | WEB HOSTING | SSL | MY INFO| MESSAGES| MARKET PLACES| FORUMS.
  3. Mark the checkbox next to your domain name (in my case yanniel.info) and then click the "Set Name Servers" button in the the "Domain settings" section.
  4. In the new page, make sure you are located in the DNS tab menu. The menu looks like this: NAME SERVERS | PARKING | FORWARDING | STEALTH FORWARDING | DYNADOT HOSTING | DNS | FREE HOSTING | EMAIL FORWARDING.
  5. In the "Domain Record" section: select "Forward" in the "Record Type" combobox and write http://www.yourdomainname.ext (in my case http://www.yanniel.info) as your "IP Address or Target Host".
  6. In the "Subdomain Records" section: write www as your first "subdomain"; select "CNAME" in the "Record Type" combobox and write ghs.google.com as your first "IP Address or Target Host". This CNAME record value (ghs.google.com) is  particular to Blogger...so, if your are NOT using Blogger your should use the corresponding CNAME record. 
  7. Finally, click "Use Dynadot DNS" button.
Your setting should correspond to something like this:
Configuring a Dynadot's domain for a Blogger's blog

After your Dynadot settings are set, expect a delay of one to three days, before all the DNS servers have been updated. I suggest that you wait this time before proceeding to configure the Blogger settings.

Configuring Blogger settings:
  1. Tell blogger to use your custom domain. For that go to: Dashboard-> Settings -> Publishing ---> Custom domain ---> Switch to advanced settings.
  2. Enter "Your Domain" name (in my case www.yanniel.info) and the captcha "Word Verification".
  3. Finally, click the "Save Settings" button.
 This is how it looks:
    Configure a custom domain in Blogger

      Well, this is all there is! Is your blog now alive in your custom domain? If it is, then I 'am happy ;-)

      For a more general guideline to configure a custom domain in Blogger refer to How do I use a custom domain name on my blog?

      SERVICE FEE – 7EPMT/WD/TFR@$.150 at Royal Bank of Canada (RBC)

      The other day I was surfing my savings account's details and I noticed a withdrawal of $10.50 (CAD) that I never did. The description was SERVICE FEE - 7EPMT/WD/TFR@$1.50 and was done on September 2nd, 2010. See the red rectangle in the picture below:

      SERVICE FEE - 7EPMT/WD/TFR@$1.50

      Going back in time a little bit, I noticed that I also had a SERVICE FEE – 4EPMT/WD/TFR@$1.50 on August 2nd, 2010. At that time I was charged with $6.00 (CAD).

      I found a pattern in those withdrawals:
      1. They apply always on the second day of every month.
      2. The amount of the fee is the result of multiplying $1.50 by the number preceding “EPMT” in the description.
      See the relation below for a trivial mathematical calculation of the fees:

      Description:                                                                Fee value:
      SERVICE FEE - 1EPMT/WD/TFR@$1.50       =>   $1.50 (CAD)
      SERVICE FEE - 2EPMT/WD/TFR@$1.50       =>   $3.00 (CAD)
      SERVICE FEE - 3EPMT/WD/TFR@$1.50       =>   $4.50 (CAD)
      SERVICE FEE - 4EPMT/WD/TFR@$1.50       =>   $6.00 (CAD)
      SERVICE FEE - 5EPMT/WD/TFR@$1.50       =>   $7.50 (CAD)
      SERVICE FEE - 6EPMT/WD/TFR@$1.50       =>   $9.00 (CAD)
      SERVICE FEE - 7EPMT/WD/TFR@$1.50       =>  $10.50 (CAD)
      …...............................................................................................
      SERVICE FEE - NEPMT/WD/TFR@$1.50      =>  $1.50 * N (CAD)

      At this point I decided to go to the nearest branch of the RBC and ask about the reason for those fees. They said I was charged because I had withdrawn money from my “savings account”, which is intended for “saving” and not for “making payments”. So, if you plan to pay for anything, don't use directly your “savings account”, instead use your “checking account”.

      Most Canadian institutions do unfair tricks like the one described above to eat your money. Fortunately, I found a bank in Canada (Tangerine) that does not seem to trick you and eat your money. If you are interested, you might take a look at the link below:


      Note: I am a client of Tangerine. These guys conduct a very clear business. They don’t trick, they don’t hide stuff and above all, they don’t charge any fees.

      Please, if this article was helpful, then share it by clicking the Google Plus (G+) button at the beginning of this post. 

      RBC online banking: Choose the right Savings Account type

      Savings accounts are intended to save... or so RBC [1] says. There's one golden rule: the money that goes into the savings account should stay there. If you don't follow this norm, you will be charged $1.50 per each transaction you make directly from your savings account.These charges are named service fees.

      Service fees apply in most situations that you have moved money out from your savings account. For example, whether you withdraw money in an ATM machine, pay with your debit card or make any kind of transaction using your savings account, you are busted and then you should pay the corresponding service fee.

      If you need to use the  money in your savings account, first, transfer that money to your checking account by means of the RBC online banking. Then use your checking account to make the payments or withdraw the amount you need.

      Even this way you might be charged, because sometimes transferring from savings to checking is penalized with $1.50 per transaction. This depends on the type of savings account your are using. My advice: use RBC High Interest eSavings™ account, which gives you higher savings interests and also allows you to transfer money from savings to checking without being charged.

      A better advice, do you banking with an institution that is not waiting for you to make a “mistake” in order to fine you for it. So far, my best candidate is Tangerine. I outlined some of the benefits of banking with Tangerine and how to open a checking account at this institution in almost no time and from the comfort of your home. The details can be found here: How to open a checking account at Tangerine?.

      If you decide to remain at RBC, this is how you can change your savings account type:

      1.) Login into your online banking account.
      2.) Expand your savings account details by clicking on the corresponding link.
      3.) Click Personal Accounts --> Change Account Type or Add Owners in the left column of the page.
      4.) At his point, follow the instructions your are given, but make sure to choose RBC High Interest eSavings™ as your new account type. [2]

      Hopefully you can achieve more freedom with your new RBC High Interest eSavings™ account. It will give you the ability to move money from your savings account to your checking account  without being penalized by the unpleasant service fees. [3]

      Notes:
      [1]: RBC stands for Royal Bank of Canada.

      [2]: There are 7 types of account by default:
      • RBC High Interest eSavings™
      • RBC VIP Banking™
      • RBC Signature No Limit Banking™
      • RBC No Limit Banking™
      • RBC Day to Day Banking™
      • RBC Enhanced Savings™
      • RBC Day to Day Savings™
      [3]: Important: The money being moved (transferred) is extent of charge only if you use online banking.

      A SEO advice for Blogger: Remove the blog title from the post title

      This topic has been covered many times on the Internet, but bloggers don't to pay much attention to it. So, in this article, I am bringing some light to this matter (AGAIN), even if my post is labeled by Google as “duplicate content”.

      If you create a new blog in Blogger,  this is what you should expect for the pages of your baby blog:
      1. Blog Home Page Title: corresponds to your blog title. For example: the home page title of this blog is “Yanniel's notes”.
      2. Post Page Title:  is formed by concatenating your blog title, a colon-space (“: ”) and your current post title. For example: the page title for this post would have been by default “Yanniel's notes: A SEO advice for Blogger: Remove the blog title from the post title”.
      The pattern followed in point number 2 is really bad from the SEO point of view. The page title is one of the most (if not the most)  important aspects for Search Engine Optimization; which is why, replicating the blog title on each post title is not wise.

      That  behavior leads Google, Yahoo, Bing and other major search engines to depreciate your post entries, because they find “duplicate content” in all the titles of your blog pages.

      I really don't see any benefit in prefixing each post title with the blog title.

      A way to change this situation is to remove the blog title from the title of each post. To achieve this follow the steps below:
      1. Open your Blog Template HTML editor, available thought Menu->Template -> Edit HTML.
      2. Find the string <title><data:blog.pageTitle/></title>
      3. Replace it with:
            <b:if cond='data:blog.pageType == "index"
        '>
              <title><data:blog.title/></title>
            <b:else/>
              <title><data:blog.pageName/></title>
            </b:if>
      4. Click the Save Template button. Done!
      Notice that my post title is no longer: “Yanniel's notes: A SEO advice for Blogger: Remove the blog title from the post title".

      The strikethrough part was removed!

      Hope this helps!

        Free help for immigrants and political refugees in Toronto, Canada

        I was in the subway two days ago and suddenly I heard one person saying to another: "la luz de alante es la que alumbra" [1]. As the only people in the word using such a phrase are Cubans, I interrupted the lady that was chatting with a rhetoric question: Are you Cuban?

        Leticia looked at me with a familiar smile and answered affirmatively. Shortly after, I was introduced to Mario, a fine Argentine man, which surprised me due to his deep understanding of the Cuban culture [2].

        After a quick catch-up with Leticia [3], Mario gave me his card and explained to me that both of them work for Mennonite New Life Centre of Toronto (MNLCT).

        MNLCT is a non-profit organization that helps and guides immigrants and political refugees in the Toronto area. Although there are other well-known organizations like YMCA, MNLCT differs in the fact that it not only assists "legal Canadian residents": Suppose you are a Cuban escaping from Cuba, where would you go without money and without papers? Well, I suggest you give MNLCT a try. At the very least, they will point you in the right direction for FREE.

        One final quotation: MNLCT welcomes newcomers, immigrants and political refugees from all nationalities, not only Cuban guys.

        Notes:
        [1]: A similar idiom in English would be: "a bird in hand is worth more than two in the bush".

        [2]: It is worth mentioning that Mario Bianchi was closely involve with the relocation (in Canada) of 17 Cuban political prisoners, released after the visit of the Venerable Pope John Paul II to Cuba in 1998.

        [3]: Cubans are very friendly or like we usually say: "guarosos". So, if you find an unknown Cuban in the middle of Toronto and talk to him/her, there's a 99% chance that he/she will tell you his/her life :-D