1. ์ฑ๊ธํค ํจํด (Singleton Pattern) ์ด๋?
- ์ํํธ์จ์ด ๋์์ธ ํจํด์ผ๋ก์, ์ฑ๊ธํด ํจํด(Singleton pattern)์ ๋ฐ๋ฅด๋ ํด๋์ค๋, ์์ฑ์๊ฐ ์ฌ๋ฌ ์ฐจ๋ก ํธ์ถ๋๋๋ผ๋ ์ค์ ๋ก ์์ฑ๋๋ ๊ฐ์ฒด๋ ํ๋์ด๊ณ ์ต์ด ์์ฑ ์ดํ์ ํธ์ถ๋ ์์ฑ์๋ ์ต์ด์ ์์ฑ์๊ฐ ์์ฑํ ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ๋ค. ์ฃผ๋ก ๊ณตํต๋ ๊ฐ์ฒด๋ฅผ ์ฌ๋ฌ๊ฐ ์์ฑํด์ ์ฌ์ฉํ๋ DBCP(DataBase Connection Pool)์ ๊ฐ์ ์ํฉ์์ ๋ง์ด ์ฌ์ฉ๋๋ค. ๊ฐ๋จํ ๋งํด์, ํ๋ฒ ๊ฐ์ฒด๋ฅผ ์์ฑํด์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ ์ผ๋ก ์ฌ๋ ค๋๊ณ , ์ด ์์ฑ๋ ๊ฐ์ฒด๋ฅผ ์ ์ญ์ ์ผ๋ก ์ฌ์ฉํ ์ ์๊ฒ ๋ง๋ค์ด ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๋ฅผ ์ค์ฌ์ฃผ๋ ํจํด์ด๋ค.
2. ์ฑ๊ธํค ํจํด ์ฐ๋ ์ด์
(1) ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๋ฅผ ๋ฐฉ์งํ๋ค.
(2) ๋ค๋ฅธ ํด๋์ค์ ์ธ์คํด์ค๋ค์ด ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๊ธฐ ์ฝ๋ค.
(3) DBCP(DataBase Connection Pool)์ฒ๋ผ ๊ณตํต๋ ๊ฐ์ฒด๋ฅผ ์ฌ๋ฌ๊ฐ ์์ฑํด์ ์ฌ์ฉํ ๋
(4) ์ธ์คํด์ค๊ฐ ์ ๋์ ์ผ๋ก ํ๊ฐ๋ง ์กด์ฌํ๋ ๊ฒ์ ๋ณด์ฆํ๊ณ ์ถ์ ๊ฒฝ์ฐ.
3. ์ฃผ์ ํด์ผํ ์
- ์ฑ๊ธํค ์ธ์คํด์ค์ ๋ํ ๋น์ค์ด ๋์์ง๋ฉด ํด๋์ค๊ฐ ๊ฒฐํฉ๋๊ฐ ๋์์ ธ OCP(Open-Close Principle)์ ์ด๊ธ๋๊ธฐ ์ฝ๋ค.
4. ํ์ด์ฌ์์ ์ฐ๋ ๋ฐฉ๋ฒ
(1) __new__ ์์ฑ์๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํํ๊ธฐ ( Singleton ํด๋์ค๊ฐ ์์ฑ๋ ์ฌ๋ถ๋ฅผ ํ์ธํ์ฌ ์ฒ๋ฆฌ)
***__new__ ์์ฑ์๋ __init__์ด ๋ฐํ๊ฐ์ ๊ฐ์ง์ ์๋์ ์ ๋ณด์ํ ์์ฑ์
class Singleton( object):
def __new__(self):
if not hasattr(self, 'instance'):
self.instance = super( Singleton, self).__new__(self)
return self.instance
s = Singleton()
s2 = Singleton()
print("Object created ", s)
print("Object created ", s2)
## output
Object created <__main__.Singleton object at 0x0000028014344EF0>
Object created <__main__.Singleton object at 0x0000028014344EF0>
(2) ๋ชจ๋ ๊ฐ์ฒด๊ฐ ๊ฐ์ ์ํ๋ฅผ ๊ณต์ ํด์ ๋ค๋ฅธ ๊ฐ์ฒด์ง๋ง ์ฑ๊ธํค์ธ๊ฑฐ ์ฒ๋ผ ์ฌ์ฉ๊ฐ๋ฅ
*** __dict__ (๊ฐ์ฒด์ ์์ฑ์ ์ ์ฅ) : ํด๋์ค๋ด ๋ชจ๋ ๊ฐ์ฒด์ ์ํ๋ฅผ ์ ์ฅ
class Singleton2:
__shared_state = {"1":"2"}
def __init__(self):
self.x = 1
self.__dict__ = self.__shared_state
pass
b1 = Singleton2();
b2 = Singleton2();
b1.x = 5
print( b1)
print( b2)
print( b1.__dict__)
print( b2.__dict__)
## output
<__main__.LazySingleton object at 0x0000028014357F60>
<__main__.LazySingleton object at 0x0000028014357F98>
{'1': '2', 'x': 5}
{'1': '2', 'x': 5}
(3) Metaclass๋ฅผ ์ฌ์ฉํ์ฌ Singleton ๊ตฌํํ๊ธฐ
โ ***Metaclass๋ฅผ ์์๋ฐ๋ ๊ฐ๋
class MetaSingleton( type):
_instances = {}
def __call__(self , *args, **kwargs):
if self not in self._instances:
self._instances[self] = super( MetaSingleton, self).__call__( *args, **kwargs)
return self._instances[self]
class Logger( metaclass = MetaSingleton):
pass
lo1 = Logger()
lo2 = Logger()
print( lo1, lo2)
## output
<__main__.Logger object at 0x000002801435F2E8>
<__main__.Logger object at 0x000002801435F2E8>