Skip to Content.
Sympa Menu

patterns-discussion - Re: [patterns-discussion] Singleton Pattern by John Vlissides

patterns-discussion AT lists.cs.illinois.edu

Subject: General talk about software patterns

List archive

Re: [patterns-discussion] Singleton Pattern by John Vlissides


Chronological Thread 
  • From: Jesús Alonso <kenchoweb AT hotmail.com>
  • To: patterns-discussion AT cs.uiuc.edu
  • Subject: Re: [patterns-discussion] Singleton Pattern by John Vlissides
  • Date: Mon, 03 Apr 2006 12:46:59 +0200
  • List-archive: <http://lists.cs.uiuc.edu/pipermail/patterns-discussion>
  • List-id: General talk about software patterns <patterns-discussion.cs.uiuc.edu>

Hello Peter and everyone else,

I'm with James about using Singleton or Monostate patterns for such tasks. Though I often used the method you describe (passing the context as an extra parameter), you save some coupling by reducing drastically the API readability. Adding an extra parameter, often unrelated to the purpose of a method, to every method that might use that context simply reduces the quality of the code in my honest opinion. If I recall correctly, there are some metrics regarding the number of parameters that might be affected by this design decission. Also, the code maintainability is much lesser compared to that with the Singleton pattern. If you make a change in the context when you're using the Singleton pattern, you just need to adjust the Singleton calls. Instead, if you're using the Execution Context parameter, you need to adjust the API of every method using that context, as well as every single call to any of those methods, making a simple refactoring become a tedious task.

Of course, this is my honest opinion, and it ultimately depends on the concrete problem you're facing and the characteristics of the application you're designing. That's where the design patterns knowledge is most helpful.

Best regards,
Jesús Alonso Abad


Hi James, hi all

Siddle, James wrote:
Hi Peter,

Could you recommend an alternative approach to singleton when applying cross
cutting concerns to legacy code?

Let me elaborate...the C++ project I'm currently working provides a nice
framework & general approach to accessing the current 'context', e.g. an
element sitting in the framework can get hold of a variety of objects via a
"framework context". This is an interface that is actually provided by the
overall framework container.

However, the project must also provide exception handling & logging to a
large quantity of legacy code...so we wrote a couple of singleton classes to
fulfil those roles. Are there any alternatives you could recommend to this
approach?
in a similar context we used a Context object passed through all method calls in the framework. This collected all globally needed information. There is also a pattern called Execution Context by Alan Kelly if I remember correctly, describing that mechanism.
see http://www.allankelly.net/patterns/#EncapsulateContext

Using a mock-Context makes testing such code much easier! However, you might need to ajdust your APIs to add this Context parameter.

Yours
Peter.


Thanks,
Jim



-----Original Message-----
From: Peter Sommerlad [mailto:psommerlad AT hispeed.ch] Sent: 03 April 2006 06:00
To: Maheshwari, Nitin
Cc:
patterns-discussion AT cs.uiuc.edu
Subject: Re: [patterns-discussion] Singleton Pattern by John Vlissides

Singleton should be VERBOTEN!

using singleton is like using global variables -> too much coupling, bad testability. The stack and method parameters are your friend!

just my 0.02 CHF
Peter.

Maheshwari, Nitin wrote:
Hello,



I am reading "Pattern Hatching" by John Vlissides (http://www.research.ibm.com/designpatterns/pubs/ph-jun96.txt). And I have come across the Singleton Pattern. The way to use a SingletonDestroyer (SD) class to "KILL a Singleton instance" has fascinated me.



I am a novice in this field as compared to most of the members and based on my limited knowledge I have tried to come up with a slightly different approach of destructing a singleton. So you are more then welcome to send your comments on flaws in my approach.



In John's approach, destructor is made protected so that the user is not allowed to delete the singleton instance explicitly, also as said Singleton class has the responsibility to construct and destruct its instance. For this reason a separate class SD is introduced, which is a friend of class Singleton. Class Singleton also has a static member of SD. So as the SD's instance goes out of scope, it deletes the pointer of Singleton assigned to it. SD has public constructor and a setter function to set the Singleton pointer.



class SingletonDestroyer {

public:

SingletonDestroyer(Singleton* s= 0) { _singleton = s; }

~SingletonDestroyer() { delete _singleton; }



void SetSingleton(Singleton* s) { _singleton = s; }

private:

Singleton* _singleton;

};



class Singleton {

public:

static Singleton* Instance();

protected:

Singleton() { }



friend class SingletonDestroyer;

virtual ~Singleton() { }

private:

static Singleton* _instance;

static SingletonDestroyer _destroyer;

};



Having a public SD constructor give a chance to user to create the SD object explicitly, such as:



Singleton *pSingleton = Singleton::Instance();

SingetonDestroyer explicitSingletonDestroyer(pSingleton);



So the basic purpose of making the destructor of Singleton protected is defeated.



I have made a minor change in John's approach to rectify this problem. Class SD is made the protected inner class of class MySingleton. This prevents the user from creating an instance of SD class explicitly and thus restricting the user to delete the Singleton pointer knowingly or unknowingly.



class CMySingleton

{

protected:

class SingletonDestroyer // Inner Class

{

public:

SingletonDestroyer () {}

~SingletonDestroyer () {

delete _pInstance; // deleting the singleton instance

}

private:

// Prevent users from making copies of a

// Destroyer to avoid double deletion:

SingletonDestroyer(const SingletonDestroyer&);

void operator=(const SingletonDestroyer&);

};



friend class SingletonDestroyer;

protected:

CMySingleton();

virtual ~CMySingleton();

public:

static CMySingleton* GetInstance ();

void DoSomething();

protected: //members

static CMySingleton *_pInstance;

static SingletonDestroyer _destroyer;

int _nSomeVal;

};



It still doesn't help you if you need to delete your singleton *before*
the end of the program. J


Thanks,

Nitin Maheshwari

CA, India


------------------------------------------------------------------------

_______________________________________________
patterns-discussion mailing list
patterns-discussion AT cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/patterns-discussion


--
--
Peter Sommerlad

Erlenstrasse 79
CH-8832 Wollerau
tel +41 1 687 44 74
fax +41 79 432 23 32
mobile +41 79 432 23 32
mailto:psommerlad AT hispeed.ch

_______________________________________________
patterns-discussion mailing list
patterns-discussion AT cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/patterns-discussion






Archive powered by MHonArc 2.6.16.

Top of Page