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.0511 sec