alt

객체지향 설계에서 싱글턴 패턴

Shared on June 14, 2026

1
Speaker 100:00

안녕하세요. 객체지향분석 및 설계에서 GANG HOB4 디자인 패턴 중에 싱글턴 본을 공부하도록 하겠습니다.

2
Speaker 200:14

패턴입니다. 싱글탑 패턴은 한 클래스를 만들게 되면 그 클래스에서 있는 object, instance가 단 하나만 존재하는 그런 패턴을 얘기합니다. 그래서 하나의 클래스에서 단지 하나의 인스턴스만 허락을 해주는 것입니다. 이것을 싱글턴이다 라고 보시면 되겠고요. 그래서 이 하나의 인스턴스는 계속 new new 해서 컨스트럭터를 해서 계속 object 인스턴스를 만드는 것이 아니라 인스턴스를 만들면 그것을 계속해서 재사용하는 거죠. 글로벌 컨셉, 싱글 포인트 버세스 형태가 된다고 보시면 되겠습니다. 이것을 접근을 하기 위해서 어떻게 하냐 라고 볼 수가 있는데요. 스테이맨터드를 사용해서 만들어진 인스턴스를 접근을 하도록 하는 것입니다. 그래서 이 싱글 인스턴스를 접근하기 위해서 글로벌 비지자블리티를 제한을 한다든가 아니면 하나의 어세스 포인트를 제한을 해 줄 수가 있습니다. 자 그림에서 한번 볼까요? 서비스 팩토리라고 이제 있고요. 여기 1이라는 것이 있어요. 그래서 우리 UML 다이그라면서 클래스 다이그라를 볼 때 1을 한다는 것은 싱글턴이다 라고 표기를 한다고 저희가 배웠습니다 그리고 여기 보면 서비스 팩토리라는 클래스의 컨스트럭터는 서비스 팩토리겠죠 그것이 이렇게 밑줄이 거져 있어요 static으로 컨스트럭터가 만들어졌구나 라는 거 알 수가 있습니다 그리고 이것을 접근하기 위해서는 get instance를 사용을 하는데요 get instance도 또한 이것이 static 클래스로 되어 있습니다. static method로 되어 있습니다. 한번 볼까요? service factory return type get instance get instance 이거죠? 이거에요. return type은 service factory synchronize는 여러 트레드가 접근을 하는 것을 컨트롤 하기 위해서 멀티트레이드 있는 것에 하나의 메토드만 들어가서 작업을 할 수 있도록 해주는 것입니다. 키워드에요. 그래서 Thread를 사용하면 Synchronized를 붙이시면 동기화시킬 수가 있습니다. Static 하게 되면 이 Static은 Class의 종속적인 메토드라고 보시면 되겠습니다. 여기서 해야 되는 것은 뭐냐면 Instance를 주는 거죠. 그래서 instance를 return을 해 줘요. instance를 return을 해 주는 거죠. 그리고 이 instance가 null이면 새로운 constructor를 이제 만들어 나가는 것입니다. 만약에 이미 하나 만들었으면 그 instance를 전해주는 거죠. 싱글턴 패턴은 언제 쓰느냐 하면 단 하나의 인스턴스가 존재할 때에요. 예를 들어서 그 회사의 매니저가 한 명이다. 어떤 일을. 그럼 그 매니저는 인스턴스가 여러 개 만들도록 하면 안 되는 거죠. 여기는 이제 회사가 포스트 시스템을 운영을 하는 회사인데요. 레지스터를 하나로 운영을 하고 싶은 거예요. 그 포스트 시스템 하나. 한 회사, 한 판매처에서 하나의 레지스터를 하는 거죠. 그래서 여기 Initialization 보시게 되면 여기에 service_vactory.get_instance 이 팩토리, 서비스 팩토리의 인스턴스가 나오는 거죠. 그것의 어댑터 이렇게 불렀어요. 그래서 물론 이렇게 컴마 컴마 해서 보는 것이 별로 좋지는 않지만 여기서 싱글 터널을 이용을 한 거죠. 서비스 배터리에 get instance를 접근해서 그것의 어댑터를 받아서 어댑터에 넣고 시작을 하는 겁니다. 그래서 이렇게 싱글 인스턴스를 만들 때는 글로벌 비지어빌리티를 접근을 하도록 하는 것이 좋습니다. 그래서 많은 경우에 static method를 사용하게 되면 접근을 할 수 있는 것이 그 클래스 이름에서 접근을 하니까 global visability가 좋아진다 라고 보시면 되겠습니다. 그 다음에는 lazy한 연결점이에요. lazy한 늦게 인스턴스 연결을 해주는 거죠. 보시게 되면 get instance method죠. Synchronize. 아까 보셨어요. static 타입으로 method를 define했어요. 그래서 궁극적으로 이것을 하는 것은 자기가 물고 있는 인스턴스를 리턴을 해주는 거죠. 근데 이 내부에서 인스턴스가 null이면 아직 object 인스턴스가 만들어져 있지 않으면 새로운 팩토리의 인스턴스를 만들어서 그래서 그 인스턴스를 리턴을 해주게 됩니다. 여기서 보시게 되면 여러 트레드가 접근을 하는게 된다면 Synchronize를 사용해서 critical section을 운영을 할 수 있도록 합니다. 그래서 Concurrent Control 같이 접근을 하더라도 이 메소드는 딱 하나의 트레드만 하는게 Dread만 진입이 가능하도록 해주는 것이 바로 Synchronize 입니다. 그 다음 케이스는 Eager Initialization이에요. 그래서 이 Get Instance 안에서 인스턴스를 만드는 것이 아니라 바깥에서 만들어 주는 거예요 뭐냐면은 이 인스턴스라는 컨스트럭터 대용으로 하는 이 어떤 애트리뷰트가 있으면 거기에다가 이렇게 new 서비스 팩토리라는 것을 해줘서 인스턴스가 새로운 인스턴스를 만들어서 물고 있도록 해주는 겁니다. 그래서 get instance 하면 그것만 리턴을 해주는 거죠. 그래서 이런 경우에는 미리 애트리뷰트를 만들 때 object instance를 만드는 경우에요. 빨리 우선 인스턴스를 만들어서 이니셜라이제이션을 해준다 라고 보시면 되겠습니다. 그런데 이 경우는 하다 보면 이니셜 값에 다른 일을 하고 나서 넘겨주는 경우도 있어요. 이걸로 그러니까 이걸 이니셜라이제이션을 하게 되면 맨 처음에 애트리뷰트 만들 때 만들어지니까 나중에 교정을 하려도 잘 안 되는 거죠 그래서 오히려 그런 경우에는 아까와 같은 경우처럼 lazy, initialize, and logic이 더 좋다 보시면 되겠습니다. 얘는 어떤 경우에는 그리고 이 인센스를 제너레이션 하는 것이 싹 심플해서 복잡하지 않은 형태인 경우에 이렇게 사용을 합니다. Prefold 됩니다. 그래서 교과에서 나온 이그젠프를 보도록 하겠습니다. Register 있고요. Service Factory 하나를 가지고 있죠. 이거를 Singleton로 하겠다 라고 하면 어댑터 연결을 해서 하는 겁니다. 그러면 Store가 레스토 크리에이트 크리에이트 해서 서비스 팩토리 싱글턴 해서 얘를 어댑터로 하면 어댑터를 붙여 나가는 형태죠 그래서 여기 보시면 어댑터를 필요에 따라서 붙여 나가는 형태를 보시면 되겠습니다 설치하고 시작하는 단계죠 그래서 스토어 띄우고 레지터 띄우고 팩토리 띄우고 어댑터를 붙여 나가는 형태죠 밑에 경우는 운영하는 단계에요 그래서 예를 들어서 구매를 하려고 합니다 그러면 페이먼트 압젠 만들고 연결된 Accounting Adapter 이용해서 Post Sale 하고 나서 결제에 대한 Accounting 회계 장부를 작업을 한다고 보시면 되겠습니다. 그리고 거기에 연결된 다른 SAP 시스템의 결과를 보내주게 된다고 보시면 되겠습니다.

3
Speaker 309:39

싱글턴 디자인 패턴에 대해서 이어서 공부하도록 하겠습니다. 싱글턴 패턴이라는 것은 한 클래스에서 하나의 인스턴스만 갖고 있는 것이고요. 외부에서 이 인스턴스에 접근을 할 수 있는 영역을 제공하는 것입니다. static하는 method in 예를 들어서 get instance 라는 method를 통해서 접근을 할 수 있도록 해주는 것입니다. 내용을 한번 보도록 할까요? singleton eagle 라는 클래스 이구요. 앞에서 있었던 example 교과서 example처럼 같은 클래스인데 attribute를 정의를 할 때 static attribute 유트에 정의식 인스턴스를 생성을 해 주는 겁니다 그래서 글로벌 배리어블 역할을 하게 되는 거죠 그러면 아까 보셨던 것에 컨스트럭터가 없었어요 이런 경우에 컨스트럭터를 만들어야 되는 경우에 이런 식으로 아무것도 안 넣어 주는 거죠 자 또 동일하게 sc라는 object instance를 가지고 있고 eager한 형태로 instance를 만들어 주고요 그리고 constructor를 만들 때 private로 정해서 내용을 없게 하는 겁니다 외부에서 object을 못 만들도록 하는 거죠. private로 한다는 것은요. 외부에서 singleton eager를 new 할 수가 없어요. new 해서 외부에서 singleton eager 이런 식으로 하게 되면 안 되는 거죠 왜냐면 private로 정했기 때문입니다 그래서 클래스 바깥에서 인스턴스를 만들지 못하도록 한다 라고 설명하고 있습니다 자 그 다음에는 어떤 내용인지 보도록 하겠습니다 SC가 있고요. 얘는 static 타입으로 잡았습니다. 그리고 constructor를 만들긴 했지만 private로 잡아줬죠. 그리고 얘를 접근을 할 때는 얘를 아까 같은 경우에는 public해서 그냥 무조건 접근을 하는 거죠. 그러면은 외부에서 접근을 한다는 것은 접근식 singleton.sc 이런 식으로 접근을 해서 이 인스턴스를 접근을 해야 됩니다. 그런데 sc라는 것이 적절하게 일반적으로 쓴 것이 아닐 수도 있고 모를 수도 있죠. 그래서 얘를 sc를 알려드라오 라고 get instance 라는 static 메소드를 정리하고 얘를 public로 잡았습니다. 그래서 sc는 private이 되는 거죠. 그래서 sc를 접근하기 위해서 여기에 get instance 그래서 외부에서 외부 사용할 때는 싱글턴 이거 점 get instance 이런 식으로 하게 되면 거기에 따라서 값을 return을 해주는 거죠 어떤 값이요? 인스턴스 값이죠 새로운 인스턴스 계속 재사용되는 거죠 인스턴스를 new-new-new해서 만들지 않고 하나를 만들어서 재사용한다고 보시면 되겠습니다 자 그 다음 케이스 보도록 할까요 이거는 lazy 타입이구요 싱글탑 lazy sc에다가 null을 해주셨어요 new를 해주지 않구요 그리고 constructor는 private로 잡아서 아무나 접근하지 못하도록 하고 getInstance라는 static 타입의 public_assess을 할 수 있는 메소드를 만들었습니다 그래서 여기서 해주는 것이 바로 sc를 return을 해주는 거예요 그건 이전과 동일하죠? sc를 return을 해주는 거예요 그런데 여기서 달라진 것은 만약에 sc가 null이면 새로운 object을 만들어다오 그래서 아까 여기서 만들지 않고 필요할 때 만들어 놓은거죠 필요시 instance 생성하고 접근을 합니다 그래서 아우젝은 요청할 때 만들어지는 효과를 가지고 볼 수 있다 라고 보시면 되겠어요 그래서 얘를 접근하는 것은 아까와 동일해요 활용하고 사용시 싱글턴 베이지 하고 getInstance method를 부르게 되면 거기에 따른 인스턴스가 리턴이 된다라고 보시면 되겠습니다. 다음 케이스는 다중 트레드들을 사용을 해서 트레드들이 필요에 따라서 그 메소드를 접근을 할 때 이것을 assess 컨트롤을 잘 정리해서 critical 섹션이죠. 그러니까 critical 섹션에 하나의 트레드만 들어갈 수 있도록 해주는 것입니다. 그래서 get instance 있죠. 이 클래스 이름이에요. 이것을 synchronized 라는 키워드를 해줘요. 물론 얘는 static 타입이고요. public이고요. 컨트럭터는 private로 잡아 놓고요. 그리고 sc라는 애트리뷰트도 static 얘도 private로 잡아놨어요. 그래서 얘만 밑에 있는 get instance만 외부에서 접근할 수 있도록 해 줬습니다. null인 경우에는 새로운 인스턴스를 만들어주고 만약에 null이 아니면 만들어진 sc를 return을 하게 된다 라고 보시면 되겠습니다. 그래서 이 예제는 synchronized keyword를 사용함으로써 critical section 역할을 하게 되고요. Thread가 이 메소드를 사용하기 전에 다른 트레드가 사용을 하고 있는지를 점검을 한 이후에 그리고 나서 이 메소드에 들어가는 역할을 하게 됩니다. 다음 케이스는 multiple한 트레드를 사용을 하는데 더블체크 럭을 합니다. 럭킹하는 것을 다른 형태로 하는 겁니다. 그래서 보시게 되면 class.sc 있고요. 그리고 constructor 있고요. 여기 보면 SingletonLazyDoubleCheck GetInstance GetInstance면소드의 return 타입은 얘고 얘가 static 타입으로 퍼블릭 접근하죠. 근데 멀티트레드인 멀티트레드를 컨트롤하는 싱크로나이즈가 없어요. 그죠? 언제 있냐면요. 이것이 널인 경우에 처음에 만들어진 경우에 그때 싱크로나이즈를 해주는 거예요. 맨 처음. 하나만 만들도록 누구나 들어와서 다 만들지 못하도록 하는 거죠 아까 보시면 Synchronize에 누가 들어와서 계속 만들지 못하도록 한 Thread만 들어와서 럭킹을 하고 아부지 인스턴스 만들어서 리턴을 하죠 이와 같은 경우에 있어서는 만약에 여기서 Synchronize 해야 되는 것만 찾아서 하는 거예요. 우선 이 Method이 들어와도 되고 그리고 나서 만약에 null인 경우에만 이 Synchronize 키워드를 이용해서 새로운 아프 인스턴스를 만들 수 있도록 해주는 것입니다. 그래서 이와 같은 경우에는 우선 인스턴스가 크리에이티되었는지를 확인하고 그렇지 않는다면 Synchronize를 하는 거죠 그래서 중간에 웨이팅을 너무 바깥에서 하지 않고 안에서 널인 경우에만 Synchronize를 해서 비지 웨이팅을 할 수 있도록 해줬습니다 자 그러면 이 example를 한번 더 볼까요 여기서 보면 싱글탐 클래스 이고요 스리얼라이저을 해줘요 그래서 IO나 네트워크 혹은 외부로 접근을 할 때 아부쉑이 현재 메모리 이외에 밖으로 나갈 때 사용을 하는 거죠 그래서 이 싱글턴에 serial version number 넣어주고요 그 다음에 아까처럼 new instance를 만들고 constructor를 private하게 잡아줬습니다 그래서 이것이 null이면 뭔가 작업을 해야 되는데 null이 아닌 경우에 누군가 부른다 라고 하는 것은 이미 만들어졌습니다 라는 illegal state exception을 던져주게 됩니다. lookAt instance 라는 것은 public하게 접근할 수 있는 것에서 sc를 던져주게 되는 거고요. Read/write 관련된 것을 Object Stream Exception 로 잡아줬습니다. Cloned 여기서는 클론화 시키면 이 object이 또 만들어지기 때문에 인스턴스를 못 만들도록 해야 되는 거죠. 그래서 여기서도 exception을 던져주게 됩니다. 그리고 get class에서도 여기는 현재 클래스 로더를 찾아서 이것이 null이면 singleton에 로더를 해주고요. 그렇지 않으면 클래스 이름을 가지고 로드 클래스 해서 로더를 알려주게 됩니다. 인스턴스를 최대한 접근하지 못하도록 해서 이 이름으로만 로더의 역할을 한다고 보시면 되겠습니다. 또 다른 케이스는 Singleton Enumerate를 사용하는 거고요. Enum에서 Singleton Enum 이런 식으로 할 수가 있습니다. 그래서 이렇게 Enumerate를 하게 되면 스테릭하고 파이널한 특성을 가지고 있기 때문에 한번 만들어진 것을 변경하지 않도록 해줄 수가 있죠. 수고했습니다

객체지향 설계에서 싱글턴 패턴 | Alt