220 likes | 494 Views
Singleton. …there can be only one…. The Singleton pattern. In some cases, we only want one instance of a class to be created…ever Could be a class which manages access to some critical resource A database manager A device driver A manager of application preferences ….
E N D
Singleton …there can be only one…
The Singleton pattern • In some cases, we only want one instance of a class to be created…ever • Could be a class which manages access to some critical resource • A database manager • A device driver • A manager of application preferences • … RHS – SOC
The Singleton pattern • How can we implement such a restriction? • Should we throw an exception, if someone tries to create a second instance…? DBManager dbm1 = new DBManager(); // OK ... DBManager dbm2 = new DBManager(); // Error! • Not really what we want… RHS – SOC
The Singleton pattern Clients Creator Please give me a reference to the (only) DBManager object OK OK (hey, I already have it! DBManager Please give me a reference to the (only) DBManager object RHS – SOC
The Singleton pattern • A client should not be able to create an object directly (new …) – he must ask a creator for it • Creator creates an object (unless it has already been created), and hands a reference back to the client • How do we prevent clients from creating objects themselves…? RHS – SOC
The Singleton pattern public class DBManager { public DBManager() {} … } RHS – SOC
The Singleton pattern public class DBManager { private DBManager() {} … } RHS – SOC
The Singleton pattern • Private methods can only be invoked by other methods in the same class • The class itself becomes respon-sible for creating objects of itself… RHS – SOC
The Singleton pattern public class DBManager { private DBManager() {} public DBManager createInstance() { return new DBManager(); } } RHS – SOC
The Singleton pattern public class DBManager { private static DBManager theInstance = null; private DBManager() {} publicstatic DBManager getInstance() { if (theInstance == null) theInstance = new DBManager(); return theInstance; } } RHS – SOC
The Singleton pattern • Turning a class T into a Singleton: • Make the constructor for T private • Add a static variable to T, storing a reference to an object of class T • Add a static method to T, which returns a reference to the object pointed to by the static variable. If the reference is null, the method should create an object of type T first, and set the static variable to refer to this object RHS – SOC
The Singleton pattern public class T // T is a Singleton { private static T theInstance = null; private T() {} publicstatic T getInstance() { if (theInstance == null) theInstance = new T(); return theInstance; } } RHS – SOC
Singleton vs global variables • But wait – haven’t we just made a nice wrapping for a global variable? • Why not just do like this: public class T { public static T theInstance = new T(); private T() {} ... } RHS – SOC
Singleton vs global variables RHS – SOC
Singleton vs global variables • A global variable is created when the program starts (eager initialisation) • A Singleton is created when somebody asks for it (lazy initialisation) • If we only need the object sometimes, it is wasteful to create it unconditionally – in particular if it is resource-intensive RHS – SOC
Singleton destruction • We can control when a Singleton is created, but not when it is destroyed • Garbage collector should claim it when noone refers to it anymore • Order of destruction might matter! RHS – SOC
Singleton destruction • Suppose two singletons DataManager and DBManager are dependent: RHS – SOC
Singleton destruction • If the DBManager is destroyed before the DataManager, there might be a problem! • Somewhat difficult to manage the dependen-cies between singletons, but it can be done… RHS – SOC
Singleton– final remarks • Singleton is a useful – but also debated design pattern (see the Net) • Using Singletons in multi-threaded scenarios requires some enhancements • You cannot make a ”generic” Singleton class, and let your class inherit from it – who ”owns” the static object reference…? RHS – SOC
Exercises • Download the NetBeans project SingletonExample from the Website (go to Classes, Week 43) • Examine the code; a class MySingleton is provided. Whenever a MySingleton object is created, the counter instanceCounter is increased by one – it thus counts the number of MySingleton objects which has been created in total. Each MySingleton object also gets an individual number instanceNo • However, the given implementation of MySingleton is not a Singleton. This can be confirmed by running the test in Main. • Try to change the implementation of MySingleton into a Singleton, by following the instructions in the presentation. Run the test to verify this (the test itself must also be changed a bit) • If you are unable to make it work, you can find a suggestion for a solution in the NetBeans project SingletonExampleSolution RHS – SOC