CS 635: Advanced Object-Oriented Design & Programming |
---|
...References | slide # 1 |
...Singleton | slide # 2 |
......Intent | slide # 2 |
......Motivation | slide # 2 |
......Applicability | slide # 2 |
......Implementation | slide # 5 |
......Singleton and Inheritance | slide # 6 |
.........C++ Solution 1 | slide # 8 |
.........C++ Solution 2 - Registry | slide # 9 |
.........Java Solution | slide # 11 |
......Structure | slide # 16 |
......Participants | slide # 16 |
......Collaborations | slide # 16 |
Logging the activity of a server
// Only one object of this class can be created class Singleton { private static Singleton _instance = null; private Singleton() { fill in the blank } public static Singleton getInstance() { if ( _instance == null ) _instance = new Singleton(); return _instance; } public void otherOperations() { blank; } }
class Program { public void aMethod() { X = Singleton.getInstance(); } }
// Only one object of this class can be created class Singleton { private: static Singleton* _instance; void otherOperations(); protected: Singleton(); public: static Singleton* getInstance(); }
Implementation
Singleton* Singleton::_instance = 0; Singleton* Singleton::getInstance() { if ( _instance == 0 ) _instance = new Singleton; return _instance; }
Each subclass needs to be a singleton
A program can have one copy of each class
Solution
Singleton* Singleton::getInstance() { if ( _instance == 0 ) _instance = new SingletonSubclass; return _instance; }
Singleton* Singleton::getInstance() { if ( _instance == 0 ) { const char* singletonStyle = getenv( "singletonStyle" ); if ( strcmp( singletonStyle, "A" ) == 0 ) _instance = new A; else if ( strcmp( singletonStyle, "B" ) == 0 ) _instance = new B; else _instance = new Singleton; } return _instance; }
class Singleton { private: static Singleton* _instance; static ListOfSingletonNamePairs _registry; static Singleton* getSingletonFromName( char* name); protected: Singleton(); public: static Singleton* getInstance(); static void Register( char* name, Singleton* registerer); void otherOperations(); }
Singleton* Singleton::getInstance() { if ( _instance == 0 ) { const char* singletonName = getenv( "singletonStyle" ); _instance = getSingletonFromName(singletonName); return _instance; }
Have the subclass constructor register!
A::A() { Singleton.Register( "A", this ); }
Create a static instance of subclass in file that contains the
subclass implementation
static A theSingleton;
Java can not create a static instance of subclass in file that contains the subclass implementation
Protection level problem with constructor
Keeping Singleton classes in different package from clients allows constructors to be protected
Will give solution assuming constructors must be private
Solution when constructors can be protected is simpler
class Example { public String toString() { return "This is a simple class"; } } class Test { public static void main( String args[] ) throws Exception { Class which = Class.forName( "Example" ); Object whichOne = which.newInstance(); System.out.println( whichOne.toString() ); } }
abstract class Singleton { private static Singleton _instance = null; public static void setInstance( Singleton registerer) { if ( _instance != null ) _ instance =registerer ; } public static void setInstance( String className ) { Class aSingleton = Class.forName( className ); if ( isSubclassOfSingleton( aSingleton ) ) { Class[] noArgs = new Class[0]; Method register = aSingleton.getMethod( "register", noArgs ); register.invoke( null, noArgs); } } public static Singleton getInstance() { if ( _instance == null ) _instance = getDefaultSingleton(); return _instance; } }Java Solution part 1B
class Child extends Singleton { public static void register() { Singleton.setInstance( new Child() ); } private Child() { what ever you need to do; } }
Answer - Properties
Persistent properties class. This class is basically a hashtable
that can be saved/loaded from a stream. If a property is not
found, a property list containing defaults is searched. This
allows arbitrary nesting.
Structure