CSC/ECE 517 Fall 2010/ch3 3f lj: Difference between revisions
(29 intermediate revisions by 2 users not shown) | |||
Line 2: | Line 2: | ||
=Singleton pattern= | =Singleton pattern= | ||
A [http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29| design pattern], like singleton, is a way for a software developer to handle situations using a known solution that has been proven to be effective in the past. Design patterns also make communicating ideas and concepts between programmers more efficient and understandable. | |||
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=== | ===Class Diagram=== | ||
[[Image:IC73826.gif|500px|center]] | [[Image:IC73826.gif|500px|center]] | ||
This diagram is a Universal Modeling Languages (UML) diagram of how a Singleton class would look if implemented in Java. | |||
===Sequence Diagram=== | ===Sequence Diagram=== | ||
[[Image:CR2.gif|500px|center]] | [[Image:CR2.gif|500px|center]] | ||
This diagram illustrates how the Singleton class creates an instance of the Singleton object. The client classes then create instances of the Singleton class which handles access to the Singleton object. | |||
=Implementation= | =Implementation= | ||
Line 21: | Line 27: | ||
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=== | ===Late Instantiation=== | ||
The instance of the class can be created after class loading. This can be done by only allocating the instance on the first access of the instance variable. | The instance of the class can be created after class loading. (See the C++ example) This can be done by only allocating the instance on the first access of the instance variable. | ||
==Accessing the instance== | ==Accessing the instance== | ||
Line 44: | Line 50: | ||
} | } | ||
</pre> | </pre> | ||
[[#References|[1]]] | |||
==Ruby== | ==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. | 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. [[#References|[6]]] | ||
<pre> | <pre> | ||
Line 54: | Line 61: | ||
end | end | ||
</pre> | </pre> | ||
[[#References|[1]]] | |||
<pre> | |||
class Logger | |||
def initialize | |||
@log = File.open("log.txt", "a") | |||
end | |||
@@instance = Logger.new | |||
def self.instance | |||
return @@instance | |||
end | |||
def log(msg) | |||
@log.puts(msg) | |||
end | |||
private_class_method :new | |||
end | |||
Logger.instance.log('message 1') | |||
</pre> | |||
[[#References|[6]]] | |||
==C++== | ==C++== | ||
Line 77: | Line 109: | ||
} | } | ||
</pre> | </pre> | ||
[[#References|[ | [[#References|[3]]] | ||
=Benefits= | |||
*This pattern allows the programmer to control the instances of a particular object, it ensures that all objects use the same instance of a class.[[#References|[3]]] | |||
*The Singleton class has the ability to control the instantiation process since it implements the instantiation functionality.[[#References|[3]]] | |||
=Drawbacks= | =Drawbacks= | ||
*Unit tests are much harder to write when using the Singleton pattern | *Unit tests are much harder to write when using the Singleton pattern.[[#References|[3]]] | ||
*This pattern reduces the potential for parallelism within a program since the threads must be serialized. | *This pattern reduces the potential for parallelism within a program since the threads must be serialized.[[#References|[3]]] | ||
*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. | *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. [[#References|[3]]] | ||
*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. | *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.[[#References|[3]]] | ||
*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. | *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|[3]]] | ||
=References= | =References= | ||
Line 97: | Line 135: | ||
[[#References|[2]]] Freeman, Eric, Elisabeth Freeman, Kathy Sierra, and Bert Bates. (October 2004) Head First design patterns. [Print.] | [[#References|[2]]] Freeman, Eric, Elisabeth Freeman, Kathy Sierra, and Bert Bates. (October 2004) Head First design patterns. [Print.] | ||
[[#References|[3]]]http://www.c-sharpcorner.com/UploadFile/susanabraham/CreationalPatterns06042005050058AM/CreationalPatterns.aspx | [[#References|[3]]] C# Corner (2010, October) Creational Patterns - Singleton. [Online]. http://www.c-sharpcorner.com/UploadFile/susanabraham/CreationalPatterns06042005050058AM/CreationalPatterns.aspx | ||
[[#References|[4]]] Source Making (2010, October) Singleton Design Pattern. [Online]. http://sourcemaking.com/design_patterns/singleton | |||
[[#References|[5]]] JavaBeginner.com (2010, October) Java Singleton Design Pattern. [Online]. http://www.javabeginner.com/learn-java/java-singleton-design-pattern | |||
[[#References|[6]]] Dalibor Nasevic (2010, October) Ruby Singleton Pattern Again. [Online]. http://dalibornasevic.com/posts/9-ruby-singleton-pattern-again |
Latest revision as of 02:30, 14 October 2010
Singleton Pattern in Static and Dynamic languages
Singleton pattern
A design pattern, like singleton, is a way for a software developer to handle situations using a known solution that has been proven to be effective in the past. Design patterns also make communicating ideas and concepts between programmers more efficient and understandable.
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
This diagram is a Universal Modeling Languages (UML) diagram of how a Singleton class would look if implemented in Java.
Sequence Diagram
This diagram illustrates how the Singleton class creates an instance of the Singleton object. The client classes then create instances of the Singleton class which handles access to the Singleton object.
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
The instance of the class can be created after class loading. (See the C++ example) This can be done by only allocating the instance on the first access of the instance variable.
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. [6]
class genericFactory include Singleton end
class Logger def initialize @log = File.open("log.txt", "a") end @@instance = Logger.new def self.instance return @@instance end def log(msg) @log.puts(msg) end private_class_method :new end Logger.instance.log('message 1')
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; }
Benefits
- This pattern allows the programmer to control the instances of a particular object, it ensures that all objects use the same instance of a class.[3]
- The Singleton class has the ability to control the instantiation process since it implements the instantiation functionality.[3]
Drawbacks
- Unit tests are much harder to write when using the Singleton pattern.[3]
- This pattern reduces the potential for parallelism within a program since the threads must be serialized.[3]
- 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. [3]
- 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.[3]
- 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.[3]
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.]
[3] C# Corner (2010, October) Creational Patterns - Singleton. [Online]. http://www.c-sharpcorner.com/UploadFile/susanabraham/CreationalPatterns06042005050058AM/CreationalPatterns.aspx
[4] Source Making (2010, October) Singleton Design Pattern. [Online]. http://sourcemaking.com/design_patterns/singleton
[5] JavaBeginner.com (2010, October) Java Singleton Design Pattern. [Online]. http://www.javabeginner.com/learn-java/java-singleton-design-pattern
[6] Dalibor Nasevic (2010, October) Ruby Singleton Pattern Again. [Online]. http://dalibornasevic.com/posts/9-ruby-singleton-pattern-again