반응형

Singleton Pattern

프로그램 내에서 해당 객체의 인스턴스는 하나만 존재하게 하여, 전역변수와 같이 사용될 수 있다.

Singleton Class

C++ 구현

singleton.hpp

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
#ifndef __SINGLETON_HPP__
#define __SINGLETON_HPP__
 
// templatized Singleton Pattern
// 23.06.09 bw
 
template<typename T>
class Singleton {
    public :
        ~Singleton(){
            if(m_pInst == nullptr){
                return;
            }
            delete m_pInst;
            m_pInst = nullptr;
        }
 
        static T* getInstance(){
            if(m_pInst == nullptr){         // Lazy Initialization
                m_pInst = new T();
            }
            return m_pInst;
        }
 
    private :
        static T* m_pInst;
 
    protected:
        Singleton(){};
        Singleton(const T&){};
 
};
 
template<typename T>
T* Singleton<T>::m_pInst = nullptr;
 
#endif //__SINGLETON_HPP__
 
cs

 

Inherited Class

Earth.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include "Earth.hpp"
 
double Earth::getRadius(){
    return radius;
}
 
void Earth::showSiderealPeriod(){
    printf("Sidereal Period of Earth is %6.2f days per a year\n",year2day);
    return;
}
 
 
void Earth::setNumber(int in){
    number = in;
}
int Earth::getNumber(){
    return number;
}
cs

Earth.hpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef __EARTH_HPP__
#define __EARTH_HPP__
 
#include "Singleton.hpp"
 
class Earth : public Singleton<Earth>{
    public : 
        Earth(){};
        ~Earth(){};
 
        double getRadius();
        void showSiderealPeriod();
        void setNumber(int);
        int getNumber();
 
    private :
        double radius = 6483000;
        double year2day = 365.24;
        double day2hour = 24.0000;
        int number = 0;
};
 
#endif // __EARTH_HPP__
cs

 

Example

Main.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "Earth.hpp"
#include <stdio.h>
 
int main()
{
    Earth* PlanetEarth1 = Earth::getInstance();
    Earth* PlanetEarth2 = Earth::getInstance();
 
    PlanetEarth1->showSiderealPeriod();
    PlanetEarth1->setNumber(1);
    printf("Earth1 : %d\n",PlanetEarth1->getNumber());
 
    PlanetEarth2->showSiderealPeriod();
    PlanetEarth2->setNumber(2);
    printf("Earth2 : %d\n",PlanetEarth2->getNumber());
    printf("Earth1 : %d\n",PlanetEarth1->getNumber());
 
    return 0;
}
cs

 

결과

Sidereal Period of Earth is 365.24 days per a year
Earth1 : 1
Sidereal Period of Earth is 365.24 days per a year
Earth2 : 2
Earth1 : 2

 


 

Python 구현

Singleton.py

1
2
3
4
5
6
7
8
class SingletonType(type):
    _instances = {}
 
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            instance = super().__call__(*args, **kwargs)
            cls._instances[cls] = instance
        return cls._instances[cls]
cs

 

Earth.py

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
from Singleton import SingletonType
 
class Earth(metaclass=SingletonType):
    def __init__(self):
        self.__radius = 6483000
        self.__year2day = 365.24
        self.__day2hour = 24.0000
        self.__number = 0
 
    def getRadius(self):
        return self.__radius
 
    def showSiderealPeriod(self):
        print("Sidereal Period of Earth is {:6.2f} days per a year\n".format(self.__year2day))
 
    def setNumber(self, input:int):
        self.number = input
 
    def getNumber(self):
        return self.number
 
if __name__ == "__main__":
    earth1 = Earth()
    earth2 = Earth()
 
    earth1.showSiderealPeriod()
    earth1.setNumber(1)
    print("Earth1 : {:d}".format(earth1.getNumber()))
 
    earth2.showSiderealPeriod()
    print("Earth2 : {:d}".format(earth2.getNumber()))
    print("Earth1 : {:d}".format(earth1.getNumber()))
 
cs

 

 

[1] 싱글턴 패턴, https://refactoring.guru/ko/design-patterns/singleton

 

728x90

+ Recent posts