By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,816 Members | 2,151 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,816 IT Pros & Developers. It's quick & easy.

using the "static" keyword to implement the Singleton pattern

P: n/a
To call I would do something like:

$headline = McSelectJustOneField::callDatastore("cbHeadline");

Is this the correct use of the static keyword, to implement a
Singleton design?

class McSelectJustOneField extends McSelect {
/**
* 11-21-03 - getter
* @param - $infoToBeSought, in this case, is the name of the field
whose contents are wanted.
* returns mixed (could be string or integer or whatever was in the
field)
function static callDatastore($infoToBeSought) {
$this->setQueryObject("GetJustOneField");
$this->setInfoToBeSought($infoToBeSought);
$this->getInfo();
$row = $this->getRowAsArrayWithStringIndex($this->dsResultPointer);
$field = $row[0];
return $field;
}

}
Jul 17 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a
With total disregard for any kind of safety measures
lk******@geocities.com (lawrence) leapt forth and uttered:
To call I would do something like:

$headline = McSelectJustOneField::callDatastore("cbHeadline");

Is this the correct use of the static keyword, to implement a
Singleton design?


Pretty much, regardless of whether you're using the Singleton
pattern, you're still calling a static method. So the 'static'
keyword is perfectly acceptable.

You ARE using PHP5 I assume?

--
There is no signature.....
Jul 17 '05 #2

P: n/a
With total disregard for any kind of safety measures
lk******@geocities.com (lawrence) leapt forth and uttered:
To call I would do something like:

$headline = McSelectJustOneField::callDatastore("cbHeadline");
Is this the correct use of the static keyword, to implement a
Singleton design?


Actually, ignore my previous follow-up. No this is not correct. In
PHP5 the correct usage is:

<?php
class Foo {
public static function aStaticMethod() {
// ...
}
}

Foo::aStaticMethod();
?>

But this is only available in PHP5
--
There is no signature.....
Jul 17 '05 #3

P: n/a
With total disregard for any kind of safety measures
lk******@geocities.com (lawrence) leapt forth and uttered:
To call I would do something like:

$headline = McSelectJustOneField::callDatastore("cbHeadline");

Is this the correct use of the static keyword, to implement a
Singleton design?


P.P.S: (sorry, I'm a dumbass and my server doesn't refresh quick
enough), the variable $this does not exist within static methods.

--
There is no signature.....
Jul 17 '05 #4

P: n/a
Phil Roberts <ph*****@HOLYflatnetSHIT.net> wrote in message news:<Xn***********************@206.127.4.22>...
With total disregard for any kind of safety measures
lk******@geocities.com (lawrence) leapt forth and uttered:
To call I would do something like:

$headline = McSelectJustOneField::callDatastore("cbHeadline");

Is this the correct use of the static keyword, to implement a
Singleton design?


Pretty much, regardless of whether you're using the Singleton
pattern, you're still calling a static method. So the 'static'
keyword is perfectly acceptable.

You ARE using PHP5 I assume?

No, sorry, I'm not using PHP 5. I'm trying to make this work in PHP 4.
Jul 17 '05 #5

P: n/a
Phil Roberts <ph*****@HOLYflatnetSHIT.net> wrote in message news:<Xn***********************@206.127.4.22>...
With total disregard for any kind of safety measures
lk******@geocities.com (lawrence) leapt forth and uttered:
To call I would do something like:

$headline = McSelectJustOneField::callDatastore("cbHeadline");

Is this the correct use of the static keyword, to implement a
Singleton design?


P.P.S: (sorry, I'm a dumbass and my server doesn't refresh quick
enough), the variable $this does not exist within static methods.

Actually, I'm using the static keyword all wrong. I looked up an old
example that I had almost forgotten. Thank god for Google. This is
what someone suggested to me 8 months ago. I didn't understand it at
the time, but now that I look at it, I realize static is being used
here in a clever way, to get around the limitations of PHP 4.
All this data should only reference one single object. Having only one Object (called Singleton Pattern) can be done by a Mediator (Pattern).
A mediator looks basically like this:

class mediator{

function &instance(){

static $instance;
if (!isset($instance)){
$instance = new object;
}

return $instance;
}
}

Which should be referenced absolutely everywhere by

$ins =& mediator::instance();

You will then have exactly one object always. Also, you can get rid of all global statements with this.


Brilliant.

Jul 17 '05 #6

P: n/a
Hi !

(...)

Actually, I'm using the static keyword all wrong. I looked up an old
example that I had almost forgotten. Thank god for Google. This is
what someone suggested to me 8 months ago.


wasn't that long ago.

Jochen
--
Jochen Daum - CANS Ltd.
PHP DB Edit Toolkit -- PHP scripts for building
database editing interfaces.
http://sourceforge.net/projects/phpdbedittk/
Jul 17 '05 #7

P: n/a
Hi...

lawrence wrote:
Is this the correct use of the static keyword, to implement a
Singleton design?


Why do you need a singleton? Singletons are only a short step up from
globals in causing trouble. They are a right royal pain when testing as
one test can influence another. I wrote an article on the PHP Patterns
site (http://www.phppatterns.com/) on how to get around this issue, and
it involves some serious extra work.

Can you do without it or are you just trying it out as a learning exercise?

yours, Marcus
--
Marcus Baker, ma****@lastcraft.com, no***@appo.demon.co.uk

Jul 17 '05 #8

P: n/a
Marcus Baker wrote:
Singletons are only a short step up from globals in causing trouble.
Singletons IMHO avoid the major drawbacks of global objects (which is
the motivation for the pattern if I remember right). They initialize
themselves when first used and they can't be deleted or overwritten by
accident.
They are a right royal pain when testing as one test can influence another.


That depends on the design of your classes and your tests. I usually use
a Factory Method in the client object to get the singleton instance. For
testing I swap that Factory Method out against one that returns a mock
of the Singleton. (I use your Partial Mocks for that.)

Having Singletons carry data that changes after initialization to
reflect the state of the application is indeed problematic, because it
leeds to temporal coupling, which is near impossible to test well. I use
Singletons mainly for "stateless" things that don't change after
initialization. A database connection is a prime example.

Jochen

Jul 17 '05 #9

P: n/a
Marcus Baker <ma****@lastcraft.com> wrote in message news:<3F**************@lastcraft.com>...
Hi...

lawrence wrote:
Is this the correct use of the static keyword, to implement a
Singleton design?


Why do you need a singleton? Singletons are only a short step up from
globals in causing trouble. They are a right royal pain when testing as
one test can influence another. I wrote an article on the PHP Patterns
site (http://www.phppatterns.com/) on how to get around this issue, and
it involves some serious extra work.


Can you give a more specific link? Your article is no longer on the
front page. I'd like to read it over.
Jul 17 '05 #10

P: n/a
Marcus Baker <ma****@lastcraft.com> wrote in message news:<3F**************@lastcraft.com>...
Hi...

lawrence wrote:
Is this the correct use of the static keyword, to implement a
Singleton design?


Why do you need a singleton? Singletons are only a short step up from
globals in causing trouble. They are a right royal pain when testing as
one test can influence another. I wrote an article on the PHP Patterns
site (http://www.phppatterns.com/) on how to get around this issue, and
it involves some serious extra work.


What I wanted to do was this:

$headline = McSelectJustOneField::callDatastore("cbHeadline");

I want this mostly for convenience. I do realize it is a bit like
having a global function. I'm aware some people criticize this kind of
thing in Java for being "not really OO". Damned convenient though.

Point me to your article so I can get some sense of the downside.
Jul 17 '05 #11

P: n/a
lawrence wrote:
What I wanted to do was this:

$headline = McSelectJustOneField::callDatastore("cbHeadline");
This doesn't really look like a singleton to me, but rather like a class
with static methods. But then again I don't know what
McSelectJustOneField looks like inside. Does callDatastore() return a
reference to the singleton object? If it does what it looks like (return
a string?) that's not a singleton by my book...
Point me to your article so I can get some sense of the downside.


The article is on phpclasses.com in the "Design" section, entitled
"Singleton Registry". There's also an article about the Singleton
pattern by Harry way down on the page. Read that one first to find out
if what you're doing is really a singleton.

Jochen

Jul 17 '05 #12

P: n/a
Hi...

Jochen Buennagel wrote:
Singletons IMHO avoid the major drawbacks of global objects (which is
the motivation for the pattern if I remember right). They initialize
themselves when first used and they can't be deleted or overwritten by
accident.
Well I wouldn't go so far as to say they are the end of the world, and
they do solve the initialisation problem. I even have a couple in my
current main app (don't tell anybody). The trouble is that they can get
damaged by any part of the code. Also if you ship some with a library,
because of the global scope they can affect any part of that library.
This makes understanding things just a little bit harder. It's little
bit less encapsulation.
That depends on the design of your classes and your tests. I usually use
a Factory Method in the client object to get the singleton instance. For
testing I swap that Factory Method out against one that returns a mock
of the Singleton. (I use your Partial Mocks for that.)
A factory is almost always a superior approach. This is not so much a
singleton though, as you have to get access to the holding class to call
the factory method and, as you say, that can be mocked or switched by
subclassing. I am not against a cached instance. That is just normal
coding. It's the static global access and single instance in combination.

Actually I am going off of static methods as well, but that's another
story :).

Having Singletons carry data that changes after initialization to
reflect the state of the application is indeed problematic, because it
leeds to temporal coupling, which is near impossible to test well. I use
Singletons mainly for "stateless" things that don't change after
initialization. A database connection is a prime example.
That is a common one; PEAR uses it for example. In my current main job
(Wordtracker) we have one for the SessionPool (for PHP $_SESSION handler
access) and a Registry class (not surprisingly). That is just under 1%
of the total number of classes. When I see half a dozen in an
application I see it as a symptom of possible problems.

One that has caused me particular problems in the past is some kind of
Singleton "Auth" class. It often means you have to log in just to run
your tests. Given that such a class exists pretty near the top of the
application hierarchy (unlike a database connection) there really is no
excuse for not passing the object as a parameter.

Jochen


yours, Marcus

p.s. I'll try to do some PHP::Duploc work this holiday. Not finding much
time right now.
--
Marcus Baker, ma****@lastcraft.com, no***@appo.demon.co.uk

Jul 17 '05 #13

P: n/a
Marcus Baker wrote:
Jochen Buennagel wrote:
That depends on the design of your classes and your tests. I usually
use a Factory Method in the client object to get the singleton
instance. For testing I swap that Factory Method out against one that
returns a mock of the Singleton. (I use your Partial Mocks for that.)
A factory is almost always a superior approach. This is not so much a
singleton though, as you have to get access to the holding class to call
the factory method and, as you say, that can be mocked or switched by
subclassing.


No, I didn't mean a factory class that returns the singleton. The
factory method in the client object is usually private, and fetches the
singleton only for internal use by the class. If I don't discard it
right after use, the member variable that holds it is privat too.
One that has caused me particular problems in the past is some kind of
Singleton "Auth" class. It often means you have to log in just to run
your tests. Given that such a class exists pretty near the top of the
application hierarchy (unlike a database connection) there really is no
excuse for not passing the object as a parameter.


Funny: We have a Auth object that gets created on every page and passed
into every object, even though there are circumstances where it will not
be used at all. I'm now trying to convince my team that we should turn
it into a singleton, so it will be initialized only when actually
needed. (Auth is expensive, as our application authenticates against a
remote SOAP service.)

Jochen

Jul 17 '05 #14

P: n/a
Hi Jochen.

Jochen Bünnagel wrote:
No, I didn't mean a factory class that returns the singleton. The
factory method in the client object is usually private, and fetches the
singleton only for internal use by the class. If I don't discard it
right after use, the member variable that holds it is privat too.
No I meant factory in that sense too. To me a Singleton is a single
instance with global access. If you can make the access non-global, you
are in the clear in my book. I would call what you are doing as caching.
Funny: We have a Auth object that gets created on every page and passed
into every object, even though there are circumstances where it will not
be used at all. I'm now trying to convince my team that we should turn
it into a singleton, so it will be initialized only when actually
needed. (Auth is expensive, as our application authenticates against a
remote SOAP service.)
Sods law you would be doing just that :).

If efficiency is a concern you could either lazy proxy the class or the
resources in it. The most highly factored approach would be to have a
separate Authoriser and Authorisation. The Authoriser::login method is a
factory for the Authorisation here. I am a big fan of factory methods
and factory classes if you haven't already guessed.

I read somewhere that it is advisable to separate authentication
(identifying the user) from authorisation (handing them a set of
permissions), but I haven't yet needed that level of sophistication.

Jochen


yours, Marcus
--
Marcus Baker, ma****@lastcraft.com, no***@appo.demon.co.uk

Jul 17 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.