1.1. Intent ¶
ν΄λμ€λ‘ νμ¬κΈ μ€μ§ νλμ μΈμ€ν΄μ€λ§μ κ°μ§κ² νλ©°, μ΄λμλ μ§ μ κ·Ό κ°λ₯νλλ‘ νλ€.
1.2. Motivation ¶
λͺλͺ ν΄λμ€λ€μ λν΄μ μ€μ§ νλμ μΈμ€ν΄μ€ λ§μ κ°μ§λ κ²μ μ€μν μΌμ΄λ€. μλ₯Ό λ€λ©΄, μ΄λ€ μμ€ν
μμ μλ§μ νλ¦°ν°λ€μ΄ μλλΌλ κ±°κΈ°μλ λ¨ νλμ νλ¦°ν° μ€νλ¬λ§μ΄ μμ΄μΌ νλ€. OSμμ λμκ°λ νμΌμμ€ν
μ΄λ μλμ° λ§€λμ μ κ²½μ°λ μ€μ§ νλμ¬μΌ νλ€ (λμμ 2-3κ°μ μλμ°λ§€λμ κ° λμ§ μλλ€.) λμ§νΈ νν°μ κ²½μ°μλ A/D converterλ λ¨ νλλ₯Ό κ°μ§λ€.
μ΄λ»κ² μ°λ¦¬λ ν΄λμ€λ‘ νμ¬κΈ λ¨ νλμ μΈμ€ν΄μ€λ§μ κ°μ§λλ‘ λ³΄μ₯ν΄μ€ μ μμκΉ? κ·Έλ¦¬κ³ κ·Έλ¬ν μΈμ€ν΄μ€λ₯Ό μ½κ² μ κ·Όνκ² ν μ μμ κ²μΈκ°? global λ³μλ‘ λ κ²½μ° μ΄λμλ μ§ μ κ·Όκ°λ₯νκ² μ§λ§, global λ³μλ λ¨μΌ μΈμ€ν΄μ€λ§μ κ°μ§λλ‘ ν μ μλ€.
λ μ’μ λ°©λ²μ ν΄λμ€ μμ μΌλ‘ νμ¬κΈ μκΈ°μμ μ λ¨μΌ μΈμ€ν΄μ€λ₯Ό μ μ§νλλ‘ λ§λλ κ²μ΄λ€. μ΄ ν΄λμ€λ μΈμ€ν΄μ€κ° μμ±λ λ μμ²μ κ°λ‘μ±μΌλ‘μ λ¨μΌ μΈμ€ν΄μ€λ‘ λ§λ€μ΄μ§λ κ²μ 보μ¦νλ€. λν, μΈμ€ν΄μ€μ μ κ·Όνλ λ°©λ²λ μ 곡νλ€. μ΄κ²μ΄ λ°λ‘ SingletonPatternμ΄λ€.
1.3. Applicability ¶
SingletonPatternμ λ€μκ³Ό κ°μ κ²½μ°μ μ¬μ©νλ€.
- ν΄λμ€κ° μ νν μ€μ§ νλμ μΈμ€ν΄μ€λ§μ΄ μ‘΄μ¬ν΄μΌ ν λ. κ·Έλ¦¬κ³ μ μλ €μ§ μμΈμ€ λ°©λ²μΌλ‘ μ΄λμλ μ§ μ κ·Ό ν μ μμ΄μΌ νλ€.
- λ¨μΌ μΈμ€ν΄μ€κ° μλΈν΄λμ±μ μν΄ νμ₯κ°λ₯ν΄μΌ ν κ²½μ°. κ·Έλ¬λ©΄ ν΄λΌμ΄μΈνΈλ κ·Έλ€μ μ½λ μμ μμ΄ νμ₯λ μΈμ€ν΄μ€λ₯Ό μ¬μ©ν μ μμ΄μΌ νλ€.
1.5. Participants ¶
- Singleton
- Instance operation (ν΄λμ€μ λ©μλ)μ μ μνλ€. Instance λ ν΄λΌμ΄μΈνΈμκ² ν΄λΉ Singletonμ μ μΌν μΈμ€ν΄μ€λ₯Ό μ κ·Όν μ μλλ‘ ν΄μ€λ€.
- Singleton μμ μ μ μΌν μΈμ€ν΄μ€λ₯Ό μμ±νλ μ±
μμ κ°μ§λ€.
- Instance operation (ν΄λμ€μ λ©μλ)μ μ μνλ€. Instance λ ν΄λΌμ΄μΈνΈμκ² ν΄λΉ Singletonμ μ μΌν μΈμ€ν΄μ€λ₯Ό μ κ·Όν μ μλλ‘ ν΄μ€λ€.
1.6. Collaborations ¶
- ν΄λΌμ΄μΈνΈλ μ€μ§ Singletonμ Instance operationμΌλ‘λ§ Singleton μΈμ€ν΄μ€μ μ κ·Όν μ μλ€.
1.7. Consequences ¶
SingletonPatternμ μ¬λ¬κ°μ§ μ₯μ μ κ°μ§λ€.
- ν΄λμ€μ λν μ κ·Όμ΄ μ€μ§ νλμ μΈμ€ν΄μ€μκ²λ‘ μ νλλ€. Singleton ν΄λμ€λ μκΈ° μμ μ λ¨μΌ μΈμ€ν΄μ€λ₯Ό μΊ‘μννκΈ° λλ¬Έμ, ν΄λΌμ΄μΈνΈκ° μΈμ , μ΄λ»κ² μ κ·Όνλμ§ κ·Έ μ κ·Όμ΄ μ격νκ² μ μ΄λλ€.
- namespaceλ₯Ό μ€μΈλ€. SingletonPatternμ global variableμ μ€μμΌλ‘μ global variableλ‘ μΈν namespaceμ λλΉλ₯Ό μ€μΈλ€.
- λͺ
λ Ήμ΄μ ννμ νμ₯μν¬ μ μλ€. Singleton classλ subclassλ μ μκ³ , μ΄ νμ₯λ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό κ°μ§κ³ μ΄ν리μΌμ΄μ
μ μ€μ νλ κ²μ μ½λ€. run-timeμ€μ νμν κ²½μ°μλ κ°λ₯νλ€.
- μ¬λ¬κ°μ μΈμ€ν΄μ€λ₯Ό νμ©νλ€. νλ‘κ·Έλλ¨Έμ λ§μμ λ°λΌ μ½κ² Singleton classμ μΈμ€ν΄μ€λ₯Ό νλμ΄μμ λ μλ μλλ‘ ν μ μλ€. κ²λ€κ° μ΄ν리μΌμ΄μ
μ΄ μ¬μ©νλ μΈμ€ν΄μ€λ€μ μ μ΄νκΈ° μν΄ λμΌν μ κ·Όλ°©λ²μ μ·¨ν μ μλ€. λ¨μ§ Singleton μΈμ€ν΄μ€μ μ κ·Όνλ κ²μ 보μ₯νλ operationλ§ μμ νλ©΄ λλ€.
- class operation λ³΄λ€ λ μ μ°νλ€. ν¨ν€μ§μμ Singletonμ κΈ°λ₯μ μννκΈ°μν λλ€λ₯Έ λ°©λ²μ class operationλ€μ μ¬μ©νλ κ²μ΄λ€. (C++μμμ static ν¨μλ Smalltalkμμμ class method λ±λ±) νμ§λ§, μ΄λ¬ν μΈμ΄μ μΈ ν
ν¬λλ€μ μ¬λ¬κ°μ μΈμ€ν΄μ€λ₯Ό νμ©νλ λμμΈμΌλ‘ λ°κΎΈκΈ° νλ€μ΄μ§λ€. κ²λ€κ° C++μμμ static methodλ virtualμ΄ λ μ μμΌλ―λ‘, subclassλ€μ΄ override ν μ μλ€.
1.8. Implementation ¶
SingletonPattern μ μ¬μ©ν λ κ³ λ €ν΄μΌ ν μ¬νλ€μ΄ μλ€.
1. unique instanceμμ 보μ¦νλ κ². SingletonPatternμ κ²½μ°λ μΌλ° ν΄λμ€μ λ§μ°¬κ°μ§λ‘ μΈμ€ν΄μ€λ₯Ό μμ±νλ λ°©λ²μ κ°λ€. νμ§λ§ ν΄λμ€λ λ λ¨μΌ μΈμ€ν΄μ€κ° μ μ§λλλ‘ νλ‘κ·Έλλ°λλ€. μ΄λ₯Ό ꡬννλ μΌλ°μ μΈ λ°©λ²μ μΈμ€ν΄μ€λ₯Ό λ§λλ operationμ class operationsμΌλ‘ λλ κ²μ΄λ€. (static member functionμ΄κ±°λ class method) μ΄ operationμ unique instanceλ₯Ό κ°μ§κ³ μλ λ³μμ μ κ·Όνλ©° μ΄λ μ΄ λ³μμ κ° (μΈμ€ν΄μ€)λ₯Ό 리ν΄νκΈ° μ μ μ΄ λ³μκ° unique instanceλ‘ μ΄κΈ°ν λμ΄μ§λ κ²μ 보μ₯νλ€. μ΄λ¬ν μ κ·Όμ singletonμ΄ μ²μ μ¬μ©λμ΄μ§ μ μ λ§λ€μ΄μ§κ³ μ΄κΈ°νλ¨μΌλ‘μ 보μ₯λλ€.
λ€μμ μλ₯Ό 보λΌ. C++ νλ‘κ·Έλλ¨Έλ Singleton classμ Instance operationμ static member functionμΌλ‘ μ μνλ€. Singleton λν static member λ³μμΈ _instanceλ₯Ό μ μνλ€. _instanceλ Singletonμ μ μΌν μΈμ€ν΄μ€λ₯Ό κ°λ¦¬ν€λ ν¬μΈν°μ΄λ€.
Singleton classλ λ€μκ³Ό κ°μ΄ μ μΈλλ€.
~cpp class Singleton { public: static Singleton* Instance (); protected: Singleton (); private: static Singleton* _instance; };
λμλλ μ€μ ꡬνλΆλ λ€μκ³Ό κ°λ€.
~cpp Singleton* Singleton::_instance = 0; Singleton* Singleton::Instance () { if (_instance == 0) { _instance = new Singleton; } return _instance; }
ν΄λμ€λ₯Ό μ¬μ©νλ Clientλ singletonμ Instance operationμ ν΅ν΄ μ κ·Όνλ€. _instance λ 0λ‘ μ΄κΈ°νλκ³ , static member function μΈ Instanceλ λ¨μΌ μΈμ€ν΄μ€ _Instanceλ₯Ό 리ν΄νλ€. λ§μΌ _instanceκ° 0μΈ κ²½μ° unique instanceλ‘ μ΄κΈ°νμν€λ©΄μ 리ν΄νλ€. Instanceλ lazy-initalizationμ μ΄μ©νλ€. (Instance operationμ΄ μ΅μ΄λ‘ νΈμΆλμ΄μ κΉμ§λ 리ν΄ν unique instanceλ μμ±λμ§ μλλ€.)
μμ±μκ° protected μμ μ£Όλͺ©νλΌ. client κ° μ§μ Singletonμ μΈμ€ν΄μ€ν νλ €κ³ νλ©΄ compile-timeμ μλ¬λ₯Ό λ°μν κ²μ΄λ€. μμ±μλ₯Ό protected λ‘ λ μΌλ‘μ λ λ¨μΌ μΈμ€ν΄μ€λ‘ λ§λ€μ΄μ§λλ‘ λ³΄μ¦ν΄μ€λ€.
λ λμκ°, _instance λ Singleton κ°μ²΄μ ν¬μΈν°μ΄λ―λ‘, Instance member functionμ μ΄ ν¬μΈν°λ‘ νμ¬κΈ Singleton μ subclassλ₯Ό κ°λ¦¬ν€λλ‘ ν μ μλ€.
C++ ꡬνμ λν΄μλ μκ°ν΄μΌ ν κ²μ΄ λ μλ€. singleton μ globalμ΄λ static κ°μ²΄λ‘ λκ³ λ λ€ μλ μ΄κΈ°νλλλ‘ λλλ κ²μΌλ‘ μΆ©λΆνμ§ μλ€. μ΄μ λν΄μλ 3κ°μ§ μ΄μ κ° μλ€.
- (a) static κ°μ²΄μ μ μΌν μΈμ€ν΄μ€κ° μ μΈλμ΄μ§ κ²μ΄λΌκ³ 보μ₯ν μ μλ€.
- (b) λͺ¨λ singletonλ€μ΄ static initialization time λ μΈμ€ν΄μ€λκΈ° μν μΆ©λΆν μ 보λ₯Ό κ°μ§κ³ μμ§ μμμλ μλ€. singletonμ νλ‘κ·Έλ¨μ΄ μ€νλ λ κ·Έλ¬ν μ 보λ₯Ό μ»μ μ μλ€.
- (c) C++ μ global κ°μ²΄μ μμ±μκ° translation unitλ₯Ό ν΅νλ©΄μ νΈμΆλ λμ μμλ₯Ό μ μνμ§ μλλ€ES90. μ΄λ¬ν μ¬μ€μ singleton λ€ κ°μλ μ΄λ ν μμ‘΄μ±λ μ‘΄μ¬ν μ μμμ μλ―Ένλ€. λ§μΌ κ·Έλ΄ μ μλ€λ©΄, μλ¬λ₯Ό νΌν μ μλ€.
Smalltalkμμ unique instanceλ₯Ό 리ν΄νλ functiondμ Singleton ν΄λμ€μ class methodλ‘ κ΅¬νλλ€. λ¨μΌ μΈμ€ν΄μ€κ° λ§λ€μ΄μ§λ κ²μ 보μ₯νκΈ° μν΄μ new operationμ overrideνλ€. The resulting Singleton class might have the following two class methods, where SoleInstance is a class variable that is not used anywhere else:
~cpp new self error: 'cannot create new object' default SoleInstance isNil ifTrue: [SoleInstance := super new]. ^ SoleInstance
2. Singleton classλ₯Ό subclassing νκΈ° κ΄λ ¨. μ£Όλ μ£Όμ λ ν΄λΌμ΄μΈνΈκ° singleton μ subclassλ₯Ό μ΄μ©ν μ μλλ‘ subclassλ€μ unique instanceλ₯Ό μ€μ νλ λΆλΆμ μλ€. νμμ μΌλ‘, singleton μΈμ€ν΄μ€λ₯Ό μ°Έμ‘°νλ λ³μλ λ°λμ subclassμ μΈμ€ν΄μ€λ‘ μ΄κΈ°νλμ΄μ ΈμΌ νλ€. κ°μ₯ λ¨μν κΈ°μ μ Singletonμ Instance operationμ μ¬μ©νκΈ° μνλ singletonμ μ ν΄λλ κ²μ΄λ€. Sample Codeμλ νκ²½λ³μλ€μ κ°μ§κ³ μ΄ κΈ°μ μ μ΄λ»κ² ꡬννλμ§ λ³΄μ¬μ€λ€.
Singletonμ subclassλ₯Ό μ ννλ λ λ€λ₯Έ λ°©λ²μ Instance λ₯Ό Parent classμμ λΉΌ λΈλ€, (e.g, MazeFactory) subclass μ Instanceλ₯Ό ꡬννλ κ²μ΄λ€. μ΄λ C++ νλ‘κ·Έλλ¨Έλ‘ νμ¬κΈ link-timeμμ singletonμ classλ₯Ό κ²°μ νλλ‘ ν΄μ€λ€. (e.g, κ°κ° λ€λ₯Έ ꡬνλΆλΆμ ν¬ν¨νλ κ°μ²΄νμΌμ linkingν¨μΌλ‘μ¨.)
μ΄λ¬ν link-approach λ°©λ²μ link-timeλ singleton class μ μ νμ κ³ μ μμΌλ²λ¦¬λ―λ‘, run-timeμμ singleton classμ μ νμ νλ€κ² νλ€. subclassλ₯Ό μ ννκΈ° μν μ‘°κ±΄λ¬Έλ€ (switch-case λ±λ±)μ νλ‘κ·Έλ¨μ λ μ μ°νκ² ν μ μμ§λ§, κ·Έκ² λν μ΄μ©κ°λ₯ν singleton classλ€μ λ¬Άμ΄λ²λ¦¬κ² λλ€. μ΄ λκ°μ§μ λ°©λ² λ€ κ·Έλ€μ§ μ μ°ν λ°©λ²μ μλλ€.
λμ±λ μ μ°ν μ κ·Ό λ°©λ²μΌλ‘ registry of singletons μ΄ μλ€. κ°λ₯ν Singleton classλ€μ μ§ν©μ μ μνλ Instance operationμ κ°μ§λ κ² λμ , Singleton classλ€μ μ μλ €μ§ registry μ κ·Έλ€μ singleton instanceλ₯Ό λ±λ‘νλ κ²μ΄λ€.
registry λ string name κ³Ό singletons μ mapping νλ€. singletonμ instanceκ° νμν κ²½μ°, registryμ string nameμΌλ‘ ν΄λΉ singleton μ μμ²νλ€. registryλ λμνλ singletonμ μ°Ύμμ (λ§μΌ μ‘΄μ¬νλ€λ©΄) 리ν΄νλ€. μ΄λ¬ν μ κ·Όλ°©λ²μ λͺ¨λ κ°λ₯ν Singleton classλ€μ΄λ instanceλ€μ Instance operationμ΄ μ νμκ° μλλ‘ νλ€. νμν κ²μ registryμ λ±λ‘λ λͺ¨λ Singleton classλ€μ μν μΌλ°μ μΈ interfaceμ΄λ€.
~cpp class Singleton { public: static void Register (const char* name, Singleton*); static Singleton* Instance (); protected: static Singleton* Lookup (const char* name); private: static Singleton* _instance; static List<NameSingletonPair>* _registry; };
Register operationμ μ£Όμ΄μ§ string nameμΌλ‘ Singleton instanceλ₯Ό λ±λ‘νλ€. registryλ₯Ό λ¨μνμν€κΈ° μν΄ μ°λ¦¬λ NameSingletonPair κ°μ²΄μ 리μ€νΈμ instanceλ₯Ό μ μ₯ν κ²μ΄λ€. κ° NameSingletonPairλ nameκ³Ό instanceλ₯Ό mappingνλ€. Lookup operationμ μ£Όμ΄μ§ μ΄λ¦μ κ°μ§κ³ singletonμ μ°Ύλλ€. μ°λ¦¬λ λ€μμ μ½λμμ environment variableμ΄ μνλ singletonμ μ΄λ¦μ λͺ
μνκ³ μμμ μκ°ν μ μλ€.
~cpp Singleton* Singleton::Instance () { if (_instance == 0) { const char* singletonName = getenv("SINGLETON"); // user or environment supplies this at startup _instance = Lookup (singletonName); // Lookup returns 0 if there's no such singleton } return _instance; }μ΄λμμ Singleton classλ€μ΄ κ·Έλ€μ λ±λ‘νλκ°? νκ°μ§ κ°λ₯μ±μ κ·Έλ€μ μμ±μμμλ€. μλ₯Όλ€μ΄ singletonμ subclassμΈ MySingleton μ λ€μκ³Ό κ°μ΄ ꡬνν μ μλ€.
~cpp MySingleton::MySingleton () { // ... Singleton::Register ("MySingleton", this); }λ¬Όλ‘ , μ½λ μ΄λμμ κ° ν΄λμ€λ₯Ό μΈμ€ν΄μ€ννμ§ μμΌλ©΄ μμ±μλ νΈμΆλμ§ μμ κ²μ΄λ€. C++μμλ MySingletonμ static instanceλ₯Ό μ μν¨μΌλ‘μ μ΄ λ¬Έμ λ₯Ό μ ν΄κ²°ν μ μλ€. μλ₯Ό λ€μ΄, MySingleton ν΄λμ€μ ꡬνλΆλ₯Ό ν¬ν¨νλ νμΌμ λ€μκ³Ό κ°μ΄ μ μνλ©΄ λλ€.
~cpp static MySingleton theSingleton;
λ μ΄μ Singleton class λ singleton κ°μ²΄λ₯Ό λ§λ€ μ±
μμ΄ μλ€. κ·Έ λμ μ΄μ Singleton μ μ£Όλ μ±
μμ μμ€ν
λ΄μμ μ νν singleton κ°μ²΄λ₯Ό μ κ·Όκ°λ₯νλλ‘ ν΄μ£Όλ κ²μ΄λ€. static object approachλ μ¬μ ν λ¨μ μ΄ μ‘΄μ¬νλ€. λͺ¨λ κ°λ₯ν Singleton subclassλ€μ μΈμ€ν΄μ€λ€μ΄ μμ±λμ΄μ§λμ§, κ·Έλ μ§ μμΌλ©΄ registerλμ΄μλ μλλ€λ κ²μ΄λ€.
1.9. Sample Code ¶
λ―Έλ‘λ₯Ό λ§λλ MazeFactory ν΄λμ€λ₯Ό μ μνλ€κ³ νμ. MazeFactory λ λ―Έλ‘μ κ°κ° λ€λ₯Έ λΆλΆλ€μ λ§λλ interfaceλ₯Ό μ μνλ€. subclassλ€μ λ νΉλ³νλ product classλ€μ instanceλ€μ 리ν΄νκΈ° μν opeationλ€μ μ¬μ μν μ μλ€. μλ₯Ό λ€λ©΄ BombedWall κ°μ²΄λ μΌλ°μ μΈ Wallκ°μ²΄λ₯Ό λμ νλ€.
μ¬κΈ°μ SingletonPatternκ³Ό κ΄λ ¨ λλ λ΄μ©μ Maze applicationμ λ¨ νλμ maze factoryλ₯Ό νμλ‘ νλ€λ κ²κ³Ό κ·Έ maze factoryμ μΈμ€ν΄μ€λ μ΄λμλ μ§ mazeμ λΆλΆμ λ§λ€ μ μλλ‘ μ‘΄μ¬ν΄μΌ νλ€λ κ²μ΄λ€. μ΄λ¬ν λκ° λ°λ‘ SingletonPatternμ λμ
ν λμ΄λ€. MazeFactoryλ₯Ό SingletonμΌλ‘ ꡬνν¨μΌλ‘μ¨, global variableμ λν μ¬μ λ ¬μ ν νμκ° μμ΄ maze κ°μ²΄λ₯Ό λ§λ€λ νμν MazeFactoryλ₯Ό globalνκ² μ κ·Όν μ μλ€.
μΌλ¨ λ¨μνκ², MazeFactoryμ subclassingμ΄ νμμλ€κ³ κ°μ νμ. (μ μ ν subclassingκ³Ό κ΄λ ¨, λμμ μΈ λ°©λ²μ λν΄ κ³ λ €ν΄ λ³Ό κ²μ΄λ€.) C++ μμλ static operationμΈ Instanceμ unique instanceλ₯Ό μ°Έμ‘°νλ static memberμΈ _instance λ₯Ό μΆκ°ν¨μΌλ‘μ Singleton ν΄λμ€λ₯Ό ꡬνν μ μλ€. μμ Implementationμμλ μΈκΈνλ―μ΄ λ°λμ μμ±μλ protectedλ‘ λ μΌλ‘μ μ°λ°μ μΌλ‘ νλμ΄μμ μΈμ€ν΄μ€κ° μμ±λλ κ²μ λ§λλ€.
~cpp class MazeFactory { public: static MazFactory* Instance (); // existing interface goes here protected: MazeFactory (); private: static MazeFactory* _instance; };
λμλλ ν΄λμ€μ μ€μ ꡬνλΆλΆμ λ€μκ³Ό κ°λ€.
~cpp MazeFactory* MazeFactory::_instance = 0; MazeFactory* MazeFactory::Instance () { if (_instance == 0) { _instance = new MazeFactory; } return _instance; }
μ, μ΄μ MazeFactoryμ subclassingμ λν΄ μκ°ν΄λ³΄μ. MazeFactoryμ subclassκ° μ‘΄μ¬ν κ²½μ°, applicationμ λ°λμ μ¬μ©ν singletonμ κ²°μ ν΄μΌ νλ€. μ¬κΈ°μλ νκ²½λ³μλ₯Ό ν΅ν΄ mazeμ μ’
λ₯λ₯Ό μ ννκ³ , νκ²½λ³μκ°μ κΈ°λ°νμ¬ μ ν©ν MazeFactory subclassλ₯Ό μΈμ€ν΄μ€ννλ μ½λλ₯Ό λ§λΆμΌ κ²μ΄λ€. Instance operationμ μ΄λ¬ν μ½λλ₯Ό ꡬνν μ’μ μ₯μμ΄λ€. μλνλ©΄ Instance operationμ MazeFactoryλ₯Ό μΈμ€ν΄μ€νλ operationμ΄κΈ° λλ¬Έμ΄λ€.
~cpp MazeFactory* MazeFactory::Instance () { if (_instance == 0) { const char* mazeStyle = getenv ("MAZESTYLE"); if (strcmp (mazeStyle, "bombed") == 0) { _instance = new BombedMazeFactory; } else if (strcmp (mazeStyle, "enchanted") == 0) { _instance = new EnchantedMazeFactory; // ... other possible subclasses } else { // default _instance = new MazeFactory; } } return _instance; }μλ‘μ΄ MazeFactoryμ subclassλ₯Ό μ μν λ λ§€λ² Instance κ° λ°λμ μμ λμ΄μΌ νλ€λ κ²μ μ£Όλͺ©νμ. μ΄ applicationμμμΌ λ³λ€λ₯Έ λ¬Έμ κ° λ°μνμ§ μκ² μ§λ§, μ΄λ¬ν ꡬνμ framework λ΄μ μ μλ abstract factoryλ€ λ΄μμλ§ νμ λμ΄λ²λ¦°λ€. (Implementationμ subclass κ΄λ ¨ λΆλΆ μ°Έμ‘°)
κ°λ₯ν ν΄κ²°μ±
μΌλ‘λ Implementationμμ μΈκΈν registry approachλ₯Ό μ¬μ©νλ κ²μ΄λ€. Dynamic linking λ°©λ²λ λν μ μ©ν λ°©λ²μ΄λ€. Dynamic linking μ applicationμΌλ‘ νμ¬κΈ μ¬μ©νμ§ μλ subclass λ μ λΆ loadν΄μΌ ν νμμ±μ λμ΄μ€λ€.
1.10. Known Uses ¶
Smalltalk-80Par90 μ SingletonPatternμ μλ ChangeSet currentλΌλ μ½λμ λν changeλ€ μ§ν©λ€μ΄λ€. λ μ ν©ν μμ λ‘λ ν΄λμ€λ€κ³Ό κ·Έλ€μ metaclass κ°μ κ΄κ³μ΄λ€. metaclassλ ν΄λμ€μ ν΄λμ€λ‘, κ° metaclassλ νλμ μΈμ€ν΄μ€λ₯Ό κ°μ§λ€. metaclassλ€μ μ΄λ¦μ κ°μ§μ§ μμ§λ§ (κ·Έλ€μ λ¨μΌμΈμ€ν΄μ€λ₯Ό ν΅ν κ°μ μ μΈ λ°©λ²μ γ
γ
νκ³ ), κ·Έλ€μ λ¨μΌ μΈμ€ν΄μ€λ₯Ό μ μ§νλ©° μΌλ°μ μΌλ‘ λ€λ₯Έ ν΄λΌμ΄μΈνΈμ μν΄ μμ±λμ§ μλλ€.
InterViews user interface toolkitLCI+92λ toolkitμ Sessionκ³Ό WidgetKit ν΄λμ€μ unique instanceμ μ κ·Όνμ§ μν΄ SingletonPatternμ μ΄μ©νλ€. Sessionμ applicationμ λ©μΈ μ΄λ²€νΈλ₯Ό dispatchνλ 루νλ₯Ό μ μνκ³ μ¬μ©μ μ€νμΌκ΄λ ¨ λ°μ΄ν°λ² μ΄μ€λ₯Ό μ μ₯νκ³ , νλλ κ·Έ μ΄μμ 물리μ display μ λν μ°κ²°λ€(connections)μ κ΄λ¦¬νλ€. WidgetKitμ user interface widgetsμ look and feelμ μ μνλ€. WidgetKit::instance () operationμ Session μμ μ μλ νκ²½λ³μμ κΈ°λ°νμ¬ νΉμ WidgetKit μ subclassλ₯Ό κ²°μ νλ€. Sessionμ λΉμ·ν operationμ μ§μνλ displayκ° monochrome displayμΈμ§ color displayμΈμ§ κ²°μ νκ³ μ΄μ λ°λΌμ singleton μΈ Session instanceλ₯Ό μ€μ νλ€.
1.11. Related Patterns ¶
λ§μ patternλ€μ΄ SingletonPatternμ μ¬μ©νμ¬ κ΅¬νλ μ μλ€. AbstractFactoryPattern, BuilderPattern, PrototypePatternμ μ°Έμ‘°νλΌ.
μ§λ¬Έ
- μ κ° ν
μ€νΈ μ©μΌλ‘ n-class singletonμ ꡬννλ € ν©λλ€. κ·Έλ°λ° λ€μκ³Ό κ°μ λ¬Έμ κ° λ°μνλλ° μ΄λ»κ² ν΄κ²°ν΄μΌ λ κΉμ?
~cpp ----- CNSingleton.h ------ #include <afxtempl.h> class CNSingleton : public CObject { public: class CSingletonList; // C2248 ν΄κ²° friend CSingletonList; // C2248 ν΄κ²° static CNSingleton* Instance(); private: CNSingleton(); virtual ~CNSingleton(); //////////////////////////////////////////// // inner class static class CSingletonList : public CObject { public: CSingletonList() throw(); virtual ~CSingletonList() throw(); CNSingleton* Next(); private: void Init(); void Destory(); int m_Count; int m_Index; CList <CNSingleton*, CNSingleton*>* m_ContainerOfSingleton; }; static CSingletonList* m_Instances; }; ----- CNSingleton.cpp ------ #include "stdafx.h" #include "NSingleton.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CNSingleton::CSingletonList::CSingletonList() throw() { Init(); } CNSingleton::CSingletonList::~CSingletonList() throw() { Destory(); delete m_ContainerOfSingleton; } //////////////////////////////////////////////////////////////////////// // κ°μ²΄ μ΄κΈ°ν void CNSingleton::CSingletonList::Init() { m_Index = 0; m_Count = 3;//μμ m_ContainerOfSingleton = new CList <CNSingleton*, CNSingleton*>; for (int i = 0; i < m_Count; i++) { m_ContainerOfSingleton->AddTail(new CNSingleton()); } } //////////////////////////////////////////////////////////////////////// // κ°μ²΄ destory void CNSingleton::CSingletonList::Destory() { POSITION position = m_ContainerOfSingleton->GetHeadPosition(); while(position) { delete m_ContainerOfSingleton->GetAt(position); m_ContainerOfSingleton->GetNext(position); } m_ContainerOfSingleton->RemoveAll(); } //////////////////////////////////////////////////////////////////////// // indexμ ν΄λΉνλ CNSingletonλ₯Ό Containerμμ μ°Ύμ λ°ν CNSingleton* CNSingleton::CSingletonList::Next() { if (m_Index == m_ContainerOfSingleton->GetCount()) m_Index = 0; POSITION position = m_ContainerOfSingleton->FindIndex(m_Index); m_Index++; return m_ContainerOfSingleton->GetAt(position); } ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CNSingleton::CSingletonList* CNSingleton::m_Instances = NULL; CNSingleton::CNSingleton() { m_Instances = new CSingletonList(); } CNSingleton::~CNSingleton() { delete m_Instances; } //////////////////////////////////////////////////////////////////////// // n-th instanceλ₯Ό μ»μ΄μ¨λ€. CNSingleton* CNSingleton::Instance() { return m_Instances->Next(); }
μ΄ μμ€λ₯Ό μ»΄νμΌνλ©΄, outer classμ μμ±μλ₯Ό νΈμΆνλ λΆλΆ, μ¦ Init()κ³Ό Destroy()μμ
error C2248: 'CNSingleton::CNSingleton' : cannot access private member declared in class 'CNSingleton' λΌκ³ μλ¬κ° λ°μν©λλ€.
error C2248: 'CNSingleton::CNSingleton' : cannot access private member declared in class 'CNSingleton' λΌκ³ μλ¬κ° λ°μν©λλ€.
inner classμμλ outer classμ private μμ±μμ μ κ·Όν κΆνμ΄ μλμ?
λ§μ½ μ μ½λλ₯Ό μ λλ‘ μμ νλ € νλ€λ©΄ μ΄λ»κ² ν΄μΌ λλμ? μ°Έκ³ λ‘ μ λ http://www.javaworld.com/javaworld/javaqa/2001-11/01-qa-1102-singleton.htmlμ μλ μλ°μμ€λ₯Ό cppλ‘ ν¬ν
νμ΅λλ€. -- FredFrith