U E D R , A S I H C RSS

Gof/Singleton


1. Singleton

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 ž‹ ˜ œ ผ•œ ธŠค„Šค๋ฅผ ƒ„•˜๋Š” …ž„„ ๊ฐ€„๋‹ค.

1.6. Collaborations

  • ด๋ผด–ธŠธ๋Š” ˜คง Singleton˜ Instance operationœผ๋กœ๋งŒ Singleton ธŠค„Šค—  ‘๊ทผ•  ˆ˜ žˆ๋‹ค.

1.7. Consequences

SingletonPattern€ —ฌ๋Ÿฌ๊ฐ€ง€ žฅ „ ๊ฐ€„๋‹ค.
  1. ด๋ž˜Šค— ๋Œ€•œ  ‘๊ทผด ˜คง •˜๋‚˜˜ ธŠค„Šค—๊ฒŒ๋กœ  œ•œ๋œ๋‹ค. Singleton ด๋ž˜Šค๋Š” ž๊ธฐ ž‹ ˜ ๋‹จผ ธŠค„Šค๋ฅผ บกА™”•˜๊ธฐ ๋•Œ๋ฌธ—, ด๋ผด–ธŠธ๊ฐ€ –ธ œ, –ด๋–ป๊ฒŒ  ‘๊ทผ•˜๋˜ง€ ๊ทธ  ‘๊ทผด —„๊ฒฉ•˜๊ฒŒ  œ–ด๋œ๋‹ค.
  2. namespace๋ฅผ „ธ๋‹ค. SingletonPattern€ global variable„ „ž„œผ๋กœ„œ global variable๋กœ ธ•œ namespace˜ ๋‚ญ๋น„๋ฅผ „ธ๋‹ค.
  3. ๋ช…๋ น–ด™€ ‘œ˜„„ ™•žฅ‹œ‚ฌ ˆ˜ žˆ๋‹ค. Singleton class๋Š” subclass๋  ˆ˜ žˆ๊ณ , ด ™•žฅ๋œ ด๋ž˜Šค˜ ธŠค„Šค๋ฅผ ๊ฐ€ง€๊ณ  –ด”Œ๋ฆฌผ€ด…˜„ „ ••˜๋Š” ๊ฒƒ€ ‰ฝ๋‹ค. run-timeค‘— •„š”•œ ๊ฒฝšฐ—๋„ ๊ฐ€๋Šฅ•˜๋‹ค.
  4. —ฌ๋Ÿฌ๊ฐœ˜ ธŠค„Šค๋ฅผ —ˆšฉ•œ๋‹ค. ”„๋กœ๊ทธ๋ž˜๋จธ˜ ๋งˆŒ— ๋”ฐ๋ผ ‰ฝ๊ฒŒ Singleton class˜ ธŠค„Šค๋ฅผ •˜๋‚˜ดƒ„ ๋‘˜ ˆ˜๋„ žˆ๋„๋ก •  ˆ˜ žˆ๋‹ค. ๊ฒŒ๋‹ค๊ฐ€ –ด”Œ๋ฆฌผ€ด…˜ด ‚ฌšฉ•˜๋Š” ธŠค„Šค๋“ค„  œ–ด•˜๊ธฐ œ„•ด ๋™ผ•œ  ‘๊ทผ๋ฐฉ๋ฒ•„ ทจ•  ˆ˜ žˆ๋‹ค. ๋‹จง€ Singleton ธŠค„Šค—  ‘๊ทผ•˜๋Š” ๊ฒƒ„ ๋ณดžฅ•˜๋Š” operation๋งŒ ˆ˜ ••˜๋ฉด ๋œ๋‹ค.
  5. 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 ๋“ค ๊ฐ„—๋Š” –ด๋– •œ ˜กด„๋„ กดžฌ•  ˆ˜ —†Œ„ ˜๋ฏธ•œ๋‹ค. ๋งŒผ ๊ทธ๋Ÿด ˆ˜ žˆ๋‹ค๋ฉด, —๋Ÿฌ๋ฅผ ”ผ•  ˆ˜ —†๋‹ค.
•ฝ๊ฐ„ ฒจ–ธ„ •˜๋ฉด, global/static ๊ฐฒด˜  ‘๊ทผ€ singleton๋“คด ‚ฌšฉ๋˜๊‚ฌšฉ๋˜ง€ •Š๊ด ๊ฐ„— ๋ชจ๋“  singletonด ๋งŒ๋“ค–ดง€๋„๋ก •œ๋‹ค๋Š” ๊ฒƒด๋‹ค. static member function ๋ฅผ ‚ฌšฉ•จœผ๋กœ„œ ด๋Ÿฌ•œ ๋ชจ๋“  ๋ฌธ œ๋“ค„ ”ผ•  ˆ˜ žˆ๋‹ค.

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' ๋ผ๊ณ  —๋Ÿฌ๊ฐ€ ๋ฐœƒ•ฉ๋‹ˆ๋‹ค.
inner class—„œ๋Š” outer class˜ private ƒ„ž—  ‘๊ทผ•  ๊ถŒ•œด —†๋‚˜š”?
๋งŒ•ฝ  € ฝ”๋“œ๋ฅผ  œ๋Œ€๋กœ ˆ˜ ••˜๋ ค •œ๋‹ค๋ฉด –ด๋–ป๊ฒŒ •ด•ผ ๋˜๋‚˜š”? ฐธ๊ณ ๋กœ  €๋Š” http://www.javaworld.com/javaworld/javaqa/2001-11/01-qa-1102-singleton.html— žˆ๋Š” ž๋ฐ”†ŒŠค๋ฅผ cpp๋กœ ฌŒ…–ˆŠต๋‹ˆ๋‹ค. -- FredFrith

 œ๊ฐ€ ถ”๊ฐ€•œ ๋‹คŒ ๋‘„
~cpp 
         class CSingletonList; //  C2248 •ด๊ฒฐ
         friend CSingletonList; //  C2248 •ด๊ฒฐ 
„ ๋ณด‹ญ‹œ˜ค. ด๋ ‡๊ฒŒ •˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. -- imays
DeleteMe) imays ด๋ฉด, ˜น‹œ ˜„งด˜•ด‹ ๊ฐ€š”? --๊ธฐ–ต„ •˜‹คง€ ๋ชจ๋ฅด๊ฒ ๋Š” 1002 -- ๋„imays
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:19
Processing time 0.1904 sec