Singleton

V

VK

The solution is unnecessary convoluted by extra closures not bearing
any functional load. That is IMHO and OK if someone just loves
closures so collecting different species of them like orchids :)

The possible failure point is in "not allowed" checks like:
if( this == window )
{
alert( 'This is no function!' );
return;
}
// else if( this.prototype != SingletonClass.prototype )
else if( ! ( this instanceof SingletonClass ) )
{
alert( 'Che cavolo stai dicendo Willis!' );
return;
}

If a function is called as constructor, thus in the context "new
SingletonClass" or "new DerivedSingletonClass", then the return value
_must_ be an object. If it tries to return a primitive value then such
return value will be silently disregarded and the current value of
"this" will be returned instead. This behavior is by design and by
ECMAScript specs.
This way say having:
else if (
!!($isInstantiated.flag) &&
((this instanceof MySingleton) ||
(MySingleton.isPrototypeOf(this)))
) {
window.alert('Only one instance is allowed');
// WRONG:
return;
}
}
your constructor doesn't return undefined as one would possibly expect
but "this" value, so still a new instance just not fully initialized
by properties and methods.

To overcome that in "not allowed" situations you have either:
1) return a reference to the constructor:
return SingletonClass;
2) throw Error _and_ return a reference to the constructor to
eliminate any possible "resume next" attempts.
3) return false wrapped into Boolean object for further condition
checks:
return new Boolean;
 
L

Lasse Reichstein Nielsen

Ugo said:
In addition, I wanted to adopt the guide lines of GoF's pattern, and
parhaps I succeed:


var SingletonClass;
(function()
{
var instance;
SingletonClass = function( )
{
if( this == window )
{
alert( 'This is no function!' );
return;
}
// else if( this.prototype != SingletonClass.prototype )
else if( ! ( this instanceof SingletonClass ) )
{
alert( 'Che cavolo stai dicendo Willis!' );
return; ....
SingletonClass.getInstance = function( )
{
return instance || ( instance = new SingletonClass( ) );
}
})();

Seems like massive overkill, probably due to not having stated
your requirements precisely.

I'd just do:

var SingletonClass = (function(){
var instance = { $ : 'hi', f : function() { alert(this.$); } };
return function() {
return instance;
}
})();

Or, if you really, really require lazy construction:

var SingletonClass = (function() {
var instance;
function createInstance() {
return {
$: 'hi',
f: function f() { alert(this.$); }
};
}
// or SingletonClassConstructor.prototype.f = function(){alert(this.$);};
return function() {
return instance || (instance = createInstance());
};
})();


You are trying to use class based patterns in a prototype based
language. A singleton type is only necessary in a class based language
because objects needs a type. In a prototype based language, you
can create an object directly, so there is no need to introduce
an otherwise unnecessary type for a single object.

/L
 
L

Lasse Reichstein Nielsen

Lasse Reichstein Nielsen said:
I'd just do:
Ok, I too would actually just do:

var singleton = {
$: 'hi,
f: function() { alert(this.$); }
}

Notice that this is how the Math object works: just a plain object,
no constructor, "type" or "class" at all.
(As opposed to how, e.g., Java does it, where there is a Class with
all static methods).

You want a single object. You don't need a "type" with a single
instance for that. That's what comes from thinking in classes,
and wanting every object to have a class. Javascript does not
need that.

/L
 
V

VK

In a prototype based language, you
can create an object directly, so there is no need to introduce
an otherwise unnecessary type for a single object.

From a clean pattern point of view it is arguable IMHO. If there is an
object distinctly different from the generic Object then why not to
introduce a specific constructor for it? Besides, the singleton can be
the privileged consumer of other objects' methods where it would be
more convenient to check if (Consumer instanceof MySingleton) rather
than using some workaround checks.

About the overwhelming "closuring" I do agree but it is just the Java/
C-way AFAIK. "The encapsulation is above everything else" -
inheritance, memory leaks, resource consuming - nothing is matter as
long as it is possible to encapsulate yet another chunk into
something. With a CS graduate - so full 4-6 years cycle of such
"training" - not too much possible to do besides nice side advises to
be disregarded :)
 
L

Lasse Reichstein Nielsen

VK said:
From a clean pattern point of view it is arguable IMHO. If there is an
object distinctly different from the generic Object then why not to
introduce a specific constructor for it?

How is it different from a generic object? It has properties, and
that's all that really matters. The Math object does fine in this way.
No need for a constructor, because there is no need to construct
any more!
Besides, the singleton can be the privileged consumer of other
objects' methods where it would be more convenient to check if
(Consumer instanceof MySingleton) rather than using some workaround
checks.

Why check at all? Just call the method and document that objects
passed here should have such a method.
(An it's not like you can't circumvent the singleton'ness anyway,
if you really want to, or change the properties of the singleton
object).


The problem with the Singleton (anti-)pattern is that it shouldn't
be visible. If it makes sense to have a type, then there is no
reason to restrict to just one instance at the design level.
The implementation might only need one (but experience tells me
that, e.g., testing usually requires alternatives).

The singleton idea combines two concerns into one class: The behavior
of the class and that there should be a single designated instance
that an application should use.

These two concerns could just as easily be separated into two
classes: the class itself and a toolbox/factory class for controlling
instancing.
<URL:http://www.ibm.com/developerworks/webservices/library/co-single.html>

Hmm, guess I'm just rambling against singletons in general.

/L
 
V

VK

How is it different from a generic object? It has properties, and
that's all that really matters. The Math object does fine in this way.
No need for a constructor, because there is no need to construct
any more!

Well, it doesn't always do _everything_ what one needs, let's do not
exaggerate ;-)
Just off my head it is often irritating that some important math
values are stored in Number and some in Math. In a rush coding I keep
mixing where to get what. So one can have a Math based derivative for
say BigMath calculations:

function BigMath() {
this.MAX_VALUE = Number.MAX_VALUE;
this.MIN_VALUE = Number.MIN_VALUE;
// other properties
}
BigMath.prototype = Math;

var m = new BigMath;
alert(m.MAX_VALUE);
alert(m.PI);
Why check at all?

Because some methods have to be called only in a certain way and from
certain consumers. Such need happens, at least to me.
Just call the method and document that objects
passed here should have such a method.
(An it's not like you can't circumvent the singleton'ness anyway,
if you really want to, or change the properties of the singleton
object).

Oh definitely, anything can be broken or reverse-engineered. I do not
agree though that it is the reason to have everything as generic
Object instances and just keep dumping / removing properties as the
need goes. It may be fine for some form validator, but for a rich
application it will soon become a maintenance nightmare IMO.

....
Hmm, guess I'm just rambling against singletons in general.

Looks like to me too :) Bad life experience with them?
 
P

Peter Michaux

[cut]
I believe I have presented several options that I think are better and
actually are standard JavaScript patterns?
What is it you want from the group?

Sorry, I didn't want to seem ungrateful :(
I'm very happy about "several options" were listed...

In addition, I wanted to adopt the guide lines of GoF's pattern, and
parhaps I succeed:

[snip convoluted code]

I read in the last few days that, when asked, Eric Gamma says the two
patterns he would no longer include in "Design Patterns" are the
Visitor and Singleton patterns. I don't have a reference for this.
Search Reddit. The justification is these patterns are too complex for
what they provide. In the case of the Singleton, a global variable can
do the job. JavaScript is particularly well suited for a global
singleton pattern. I think if you don't have extraordinary
circumstances then it is always best to program a language in a way
that is natural for that language. The other option is imposing design
patterns from languages that have deficiencies. JavaScript doesn't
have singleton deficiencies but does have class-based inheritance
deficiencies, for example.

Peter
 
R

Richard Cornford

Peter said:
I doubt that is what Richard meant by "what it is you are trying
to do". You are more likely trying to "implement a tabbed pane
widget" or "send user data to the server".

Those would not be the types of things that I meant. They are too far
detached from their own implementation details to say anything about
what is wanted from this 'singleton' object that might constrain its
implementation.
Unless this is just an academic exercise.

It would not mater if it was an academic exercise.
A generic way to create a singleton object with global access
is to use a object literal.

var someSingleton = {
someProperty: function() {},
someOtherProperty: 55
};

Quite right. From that simplest possible starting point there is a huge
spectrum of possible implementations running up to the ludicrously
elaborate and complex. For every step away from that simple starting
point there should be a purpose/justification/reason, and it should be
possible for the person taking that step to state what that was. And so
is it what is wanted from the object that becomes the guide as to which
steps are taken to achieve it.

Richard.
 
R

Richard Cornford

Ugo said:
i wanted a function/object which restricts the instantiation
of one my object one time and which it ables one global access

Which, as Peter pointed out, is actually extremely simple to achieve.
A generic way to create a singleton object

Why a "generic way"? Are you writing a javascript code generator that
needs to insert other code into a structure that will accommodate all
possibilities? Otherwise being generic is probably not that good an
idea.
(and if it's possible I'd like
to adopt the GoF's "roles" - applyed to JS)

Generally it seems to be possible to do anything you can imagine with
javascript, but being able to do something is not a good enough reason
for doing it in itself.
IMHO, (new myClass()) can not be null|false|undefined..
so that initialization was good
<snip>

I cannot tell what you mean from that. Assigning null is a pointless
thing to do in this case.

Richard.
 
R

Richard Cornford

Ugo wrote:
Sorry, I didn't want to seem ungrateful :(
I'm very happy about "several options" were listed...

In addition, I wanted to adopt the guide lines of GoF's pattern,
and parhaps I succeed:

var SingletonClass;
(function()

Separating the global variable declaration from the code that
initialises it is probably not a good idea in this case. In copying this
code from place to place you risk the two becoming separate.
{
var instance;
SingletonClass = function( )
{
if( this == window )
{
alert( 'This is no function!' );
return;
}
// else if( this.prototype != SingletonClass.prototype )
else if( ! ( this instanceof SingletonClass ) )
{
alert( 'Che cavolo stai dicendo Willis!' );
return;
}

What utter nonsense. If you must have a constructor (which itself does
not make much sense if it is you intention that only one object will
ever be instantiated) and you don't want it called from other/external
code, and you are already using the inline execution of a function
expression to create a private scope, then don't mess around writing all
this code to check for misuse. Just leave the constructor in the private
scope were the external code cannot see and so cannot call it.

this.$ = 'hi';
<snip>

The language specification for javascript (ECMA 262) states that the $
symbol "is intended for use only in mechanically generated code".

Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,600
Members
45,179
Latest member
pkhumanis73
Top