Showing posts with label singleton. Show all posts
Showing posts with label singleton. Show all posts

Wednesday, May 25, 2011

javascript design patterns - singleton

Design patterns are not language specific(Or i should say not OOP language specific). They apply to all OOP languages.

Javascript is a plasticine language, it can mimic OOP, and design patterns apply too.

When we use the object literal to create an object, we are actually getting a singleton.

//get a connection instance, a singleton
var connection = {
    type : 'sqlite',
    db: 'test',
    user: 'user',
    pwd : 'pwd'
};

In JavaScript, objects are never equal unless they are the same object, so even if you create an identical object with the exact same members, it won't be the same as the first one:

var conn = {
    type : 'sqlite',
    db: 'test',
    user: 'user',
    pwd : 'pwd'
};
//false
console.log(conn === connection);
//false
console.log(conn == connection);

Well, but that seems not that kindof singleton we are familiar with when programming with PHP or Java, doesn't it?

Singleton means we should have only one instance of a specific resource anytime, anywhere in the application scope. Database connection is a typical example of singleton. In PHP, you probably can only get a db resource in this way: DB::getInstance(). You cannot use 'new' operator to get an instance, and you can't clone this instance either. If you assign the instance to multiple variables, the variables are actually pointing to the same instance, for example:

//$one and $two point to the same instance!
//if somehow you change the status of $one, $two get affected too
$one = DB::getInstance();
$two = DB::getInstance();

Back to our javascript singleton examples. Although both connection and conn are singletons, we actually can have two instances of same resource. I don't think that is the singleton we want to have.

In javascript, we can use object literal to create an object, also we can use 'new' operator(constructor function) to create an object. So probably in a javascript project, we should set the convention that a singleton resource could only be created through 'new' operator, and we ensure the constructor function returns same instance:

//that is what we want to achieve
var connection = new Connection();
var conn       = new Connection();
//should be true
console.log(connection === conn);

So let's see how can we do it in the easiest and simplest way: using function property

var Connection = function() {

    if (typeof Connection.instance === "object") {
        return Connection.instance;
    }
    this.type = 'sqlite';
    this.db   = 'test';
    this.user = 'user';
    this.pwd  = 'pwd';

    Connection.instance = this;
}
var connection = new Connection();
var conn       = new Connection();
//should be true
console.log(connection === conn);

It is clean and easy. But the only drawback is Connection.instance is publicly accessible, so other codes might accidently change it.

To fix the drawback, we can use javascript's self-defining function

var Connection = function() {

    // the cached instance
    var instance = this;

    this.type = 'sqlite';
    this.db   = 'test';
    this.user = 'user';
    this.pwd  = 'pwd';

    // rewrite the constructor
    Connection = function () {
        return instance;
    };
}

This should serve well enough. But, you probably know that there is a drawback by using self-defining function, although that could rarely happen in practice. 

The third solution: using self-invoking function
var Connection;
(function () {
    var instance;
    //constructor
    Connection = function() {
        if (instance) {
            return instance;
        }
        instance = this;
        // all the functionality
        this.type = 'sqlite';
        this.db   = 'test';
        this.user = 'user';
        this.pwd  = 'pwd';
    };
}());

var connection = new Connection();
var conn       = new Connection();

Wednesday, March 23, 2011

PHP singleton inheritance

Prior to PHP 5.3, here is how we implement singleton:
class Service
{
private static $_instance = null;
private function __construct(){};
private function __clone(){};

public static function getInstance()
{
if (self::$_instance === null) {
self::$_instance = new self;
}
return self::$_instance;
}
}

However, we all know that it is very tricky if we want to extend/inherit this singleton class.
PHP 5.3 introduces LSB, which stands for Late Static Binding. It solves our problem of inheriting a singleton class. In PHP 5.3, we implement singleton in this way
class Service
{
private static $_instance = null;
private function __construct(){};
private function __clone(){};

public static function getInstance()
{
if (static::$_instance === null) {
static::$_instance = new static;
}
return static::$_instance;
}
}

Simply replace the 'self' keyword with 'static', we can inherit a singleton just like usual inheritance.

The difference is self keyword is bound to the referenced property or method at compile time. The self keyword points to the containing class and is unaware of subclasses. The static keyword forces PHP to bind to the code implementation at the latest possible moment.

Wednesday, February 23, 2011

static methods VS singleton

Well this is an old topic but i've never seriously thought about it. We can grab a lot articles from internet, but here is what i agree most:

1. singleton is an instance, instance is an object. so, you can pass it as a parameter. If you were using static classes, the other function would have to use the class statically too and if you ever needed to change the behavior, you would need to rewrite parts of that function too instead of just having the first one pass a different class as the parameter.

2. You can also give a singleton some parameters. When working with static classes, you may need to pass a lot of parameters to the methods of the class because you aren't "constructing" it

3. singleton can become multiton(read db connection, write db connection)

4. If you use the reference in your class and decide that you won't need a singleton anymore, but a normal class, you will just need to change the behavior of the class itself and perhaps replace the line which gets an instance of it to constructing a new one or such. If you were using a static class, you would have to rewrite a lot of the code to use the new reference to the class instead of the static class name. A singleton class should also work almost out of the box as a normal class too. If you had a static class and wanted to convert it to a normal one, you would have to rewrite many parts of it.

6. You can't extend static classes, but singletons you can. Except it doesn't work very well in PHP due to some issues with static method inheritance, but it's not the only language in the world and it can be done but slightly hackily

7. Last and least:D dude, you can find many singleton in Zend Framework. Could you find any static class there?

So to the end, where is the place for static methods? Well, they definitely have their places too:
For example for library code they can be nice, such as the static System.Math class in C#

Wednesday, December 24, 2008

singleton discussions

Why I Hate Singletons
http://www.ds-o.com/archives/77-Why-I-Hate-Singletons.html

Singletons are not evil
http://www.mattberther.com/2004/05/27/singletons-are-not-evil/

Why Singletons are Evil
http://blogs.msdn.com/scottdensmore/archive/2004/05/25/140827.aspx

Wednesday, October 22, 2008

More about Singleton and static

Below is from 'http://my.opera.com/zomg/blog/2007/09/17/singleton-pattern-vs-static-classes'

Singleton also gives a reference/pointer to the class instance. You can then pass this reference as a parameter for some other function for example. If you were using static classes, the other function would have to use the class statically too and if you ever needed to change the behavior, you would need to rewrite parts of that function too instead of just having the first one pass a different class as the parameter.

There's also an another side to the reference thing. If you use the reference in your class and decide that you won't need a singleton anymore, but a normal class, you will just need to change the behavior of the class itself and perhaps replace the line which gets an instance of it to constructing a new one or such. If you were using a static class, you would have to rewrite a lot of the code to use the new reference to the class instead of the static class name. A singleton class should also work almost out of the box as a normal class too. If you had a static class and wanted to convert it to a normal one, you would have to rewrite many parts of it.


You can't extend static classes, but singletons you can. Except it doesn't work very well in PHP due to some issues with static method inheritance, but it's not the only language in the world and it can be done but slightly hackily.



So if we think about it with all this, why would you use static classes at all?
They have their uses too - For example for library code they can be nice, such as the static System.Math class in C#.

Saturday, October 4, 2008

singleton, static, defensive programming

below quoted from PHP 5 CMS Framkwork Development.
"The singleton appears repeatedly, especially for the handler objects described later. In theory, handlers could be implemented as class methods, but in PHP5 a class is not itself a first class object and it is more effective to use singleton objects. Other objects are naturally singletons, such as the session object, since PHP5 handles only a single request at a time.

They(signleton classes) arise naturally in designing systems where a range of related services is needed. Sometimes, this is done by creating a class that consists only of static methods. But that is both inefficient, and inflexible. Dealing with an instance of a class is generally more efficient than dealing with static methods, and in many cases a singleton object will know quite a lot of potentially complex information. Since a class of this kind is a manager or handler, there should never be a need for more than a single instance of the class, hence the name singleton. "

Friday when i was looking into the codes of our system, i found piece of codes like below:

public function f($keyword, $country)
{
if ($keyword === 'a') {
$keyarray = $config[$country]['a'];
} elseif ($keyword == 'b') {
$keyarray = $config[$country]['b'];
}

foreach($keyarray as $key) {
......
}
}

What is the problem of the above code? First, $keyarray is not initialised! if $keyword is neither 'a' nor 'b', the program will still try to run the next codes and throw a notice: Undefined variable and a warning 'Warning: Invalid argument supplied for foreach()'.

In the above case, at lease we should put one more 'else{$keyarray = array()}' at the end to ensure $keyarray is initialised. It is better to check with isset to make sure $config is set up correctly. However, since many php programmers don't do this in practice.

My friend who was working in GE told me that none of PHP programmers are professionals, or all PHP programmers are amateur because PHP is designed for amateur to develop simple database driven website quickly. However, since PHP plays increasingly important role in web app development, enterprises tends to employ PHP developers for their web applications. As usual, they define the criteria like 3-5 years experiences, etc, etc. They never thought that PHP programmers with 3,5 years experiences means they don't have any formal, scientific software development methodology. Probably they know more detail of PHP language. They know more functions in PHP manual. But they don't have OOP in mind. They don't have design patterns in mind. They don't have refactoring in mind.