CSC/ECE 517 Fall 2010/ch3 3f lj: Difference between revisions
Line 14: | Line 14: | ||
==Creating the instance== | ==Creating the instance== | ||
===Early Instantiation=== | |||
The instance can be created with a static constructor in static languages. (See the java example below) This means that the single instance is created on program start up and all new methods are private and never used except by the singleton class itself. | The instance can be created with a static constructor in static languages. (See the java example below) This means that the single instance is created on program start up and all new methods are private and never used except by the singleton class itself. | ||
Line 19: | Line 20: | ||
In dynamic languages, this is done by changing the access level of the constructor to prevent use outside the class just as in the static patterns. | In dynamic languages, this is done by changing the access level of the constructor to prevent use outside the class just as in the static patterns. | ||
===Late Instantiation=== | |||
==Accessing the instance== | ==Accessing the instance== |
Revision as of 01:48, 14 October 2010
Singleton Pattern in Static and Dynamic languages
Singleton pattern
In the Singleton design pattern we create a single instance of a Singleton class. Any instantiation of that Singleton class references the same instance of the class. The pattern also provides a global point of access for the functionality contained in the sole instance of the class.
Class Diagram
Sequence Diagram
Implementation
When this pattern is implemented then it must only have one instantiation of a class and that class must satisfy the global access principles. The pattern requires a mechanism to access the singleton class without instantiating another class object and a mechanism to persist the value of class members among class objects. [1]
Creating the instance
Early Instantiation
The instance can be created with a static constructor in static languages. (See the java example below) This means that the single instance is created on program start up and all new methods are private and never used except by the singleton class itself.
In static languages, this is accomplished by setting the constructors to private and controlling creation of instance of the object from within the object itself.
In dynamic languages, this is done by changing the access level of the constructor to prevent use outside the class just as in the static patterns.
Late Instantiation
Accessing the instance
In static languages, such as Java, the Singleton class will have a method which returns the instance of the Singleton class so that the other classes can use the functionality encapsulated in the Singleton class.
In dynamic languages, such as Ruby, if a class needs to access the functionality within the Singleton class then it simply needs to access the instance variable @instance and all the functionality therein.
Examples
Java
Java's API includes a Singleton class which implements the static version of the Singleton pattern. Java's implementation of the Singleton pattern only allows the programmer to create one instance of the Singleton class. The Singleton class automatically creates INSTANCE when it is initialized. The getInstance() method returns the single instance of the class that has been initialized. Java also utilizes a constructor to initialize the Singleton class.
private static final Singleton INSTANCE = new Singleton(); // Private constructor prevents instantiation from other classes private Singleton() { } public static Singleton getInstance() { return INSTANCE; }
Ruby
Ruby implements the Singleton pattern by privatizing the "new" method and creates an instance variable called @instance. This implementation guarantees that the class will not be able create more than one instantiation of itself and that the system will have the global access privileges since the @instance variable has a global scope.
class genericFactory include Singleton end
C++
// Declaration class Singleton { public: static Singleton* Instance(); protected: Singleton(); private: static Singleton* _instance; } // Implementation Singleton* Singleton::_instance = 0; Singleton* Singleton::Instance() { if (_instance == 0) { _instance = new Singleton; } return _instance; }
Drawbacks
- Unit tests are much harder to write when using the Singleton pattern
- This pattern reduces the potential for parallelism within a program since the threads must be serialized.
- The overhead of checking whether there is an instance of a class that already exists every time an objects requests a reference. Although the overhead is minuscule, this could be a serious problem for systems which don't have the resources to waste.
- There may be some development confusion with implementing the singleton class (especially one defined in a class library) because developers may forget that they cannot use the "new" keyword to instantiate the object.
- The singleton design pattern doesn't address the issue of deleting the single object. Some languages implement memory management which means that the Singleton class can only be unallocated by itself since it holds a private reference to the instance of itself. In languages that don't provide memory management, then the single instance can be deleted but it will cause a dangling reference to that object.
References
[1] Wikipedia. (2010, October) Wikipedia - Singleton_Pattern. [Online]. http://en.wikipedia.org/wiki/Singleton_pattern#Traditional_simple_way
[2] Freeman, Eric, Elisabeth Freeman, Kathy Sierra, and Bert Bates. (October 2004) Head First design patterns. [Print.]