CSE 432 Presentation GoF: Factory Method PH: “To Kill a Singleton” Michael Gardner March 20, 2006
Factory Method Defer instantiation to subclasses Define interface for creating objects Subclasses decide which class to instantiate
Applicability Use Factory Method when: A class can’t anticipate the class of objects it must create A class wants its subclasses to specify the objects it creates Classes delegate to one of several helper subclasses, and you want to localize knowledge about which is the delegate
Participants Product ConcreteProduct Creator Defines interface of objects to be created ConcreteProduct Implements Product interface Creator Declares factory method Returns object of type Product May define default implementation May call factory method to create Products
Structure
An Example Application framework App subclasses “Application,” “Document” Framework creates Document, hands it to Application Doesn’t know what type of Document to create Factory Method moves knowledge about specific Document subclass out of framework
Consequences Eliminates need to bind creation code to specific subclasses May need to subclass Creator for each ConcreteProduct Provides hooks for subclasses Connects parallel class hierarchies
To Kill a Singleton GoF makes no mention of Singleton destructors Who deletes a Singleton?
Who Kills a Singleton? Could make clients handle deletion Annoying & error-prone Dangling references Since Singleton carries creational responsibility, have it delete as well Protected destructor (for subclassing)
When do Singletons Die? Singletons are long-lived Usually live until program termination Care about orderly shutown rather than deletion of Singleton instance 2 alternatives for program-scope Singletons: Class-static pointer w/ static guard Destructor implcitly called at program end Function-static instance
Static Guard: Sample Code static Singleton * instance; static SingletonGuard guard; ... Singleton::getInstance() { if (instance == 0) guard.setSingleton(instance = new Singleton()); return instance; } SingletonGuard::setSingleton(Singleton s) { singleton = s; SingletonGuard::~SingletonGuard() { delete singleton;
Static Guard: Caveats Dependent Singletons Destructor ordering for statics undefined in C++ Can’t use multiple guards if Singletons’ destructors depend on each other Use multifunctional guard or atexit()
Function Static Singleton Make Singleton instance function-static instead of class-static: Singleton & Singleton::getInstance() { static Singleton s; return s; } Problems: Hard to extend Not thread-safe
Singleton Class Templates Create Singletons by wrapping existing classes in Singleton class template Problems: Doesn’t prevent creation of more instances Compiler issues with class template static data members Can make existing classes “true” Singletons by subclassing: class User: public Singleton<User> {...};
Summary Factory Method To Kill a Singleton Defer object creation to subclasses via “hook” methods and overriding Creation code need not know about specific subclasses To Kill a Singleton Non-public destructor makes Singleton responsible for deletion Static guard can delete instance implicitly