컴퓨터 공학

👉 [Python] 싱글톤(Single) 패턴으로 DB 접근하기

bitcodic 2019. 10. 25. 23:23

 

싱글톤 패턴?

디자인 패턴 책을 읽다보면 빠지지 않는 패턴이다.

In software engineering, the singleton pattern is a software design pattern that restricts the instantiation of a class to one "single" instance. This is useful when exactly one object is needed to coordinate actions across the system.
출처 : 위키피디아 singleton pattern

해석 : 소프트웨어 엔지니어링에서, 싱글톤 패턴은 클래스의 생성을 오직 한가지 인스턴스로만 제한하는 소프트웨어 디자인 패턴이다. 이는 시스템 전체적으로 행동을 제어하는데에 한 오브젝트만 명확하게 필요할때 유용하다.

위키피디아에서 언급한 것처럼 접근을 제한해야 하는 행동, 즉 한번에 한가지만 행동해야 하는 시스템에 적합한 패턴으로, 데이터베이스 액세스나 로그 생성 클래스를 선언할 때 적절하다.

클래스를 어디서 선언하던지 인스턴스의 주소를 확인해보면 항상 같은 번지를 가리킨다.

즉, 언제 어디서 클래스를 선언하여 인스턴스를 생성하든지 상관 없이 하나의 인스턴스만을 갖는다.

구현 방법은 클래스 선언시, 이미 인스턴스가 존재하는지 확인하고 존재하면 이미 생성된 값을 반환하고,

없으면 새로 만드는 방식으로 구현 가능하다. (Static 하게 구현하는 방식)

장점?

메모리를 적게 쓰기도하고, Static 하게 선언되었으므로 접근이 쉽다.

단점?

Static 의 가장 큰 문제를 고스란히 갖고 있다. OOP 개념과는 조금 멀어질 수 있다. 적절히 활용해야 한다.(하지만 쉽지 않다..)

 

 

아래는 현재 내가 사용하고 있는 Python Code 이며, DB Access Class 를 Singleton 으로 구현한 예시다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# Class For Mysql Database OOP
import re
import pymysql
 
class Singleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        else:
            cls._instances[cls].__init__(*args, **kwargs)
 
        return cls._instances[cls]
 
 
class Database(metaclass=Singleton):
 
    def __init__(self, dbName):
        self.db = pymysql.connect(host='',
                                  user='',
                                  password='*',
                                  db=dbName,
                                  charset='')
 
    def execute(self, query, args={}):
 
    def executeOne(self, query, args={}):
        row = self.cursor.fetchone()
        return row
 
    def executeAll(self, query, args={}):
        row = self.cursor.fetchall()
        return row
 
    def commit(self):
        self.db.commit()
 
 
 
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
cs

 

__call__ 함수에서 인스턴스의 기존 생성 여부를 확인하여 반환한다.