2025. 1. 8. 21:55ㆍCS
개요
디자인 패턴 중에서 '싱글톤' 이라고 불리는 디자인 패턴이 있다
이 '싱글톤' 디자인 패턴은 어떻게 만드는지, 어디에 사용하는지, 왜 사용하는지에 대해서 같이 알아보자.
싱글톤(Singleton) 패턴이란?
오직 하나의 클래스에 하나의 인스턴스만 가지는 패턴이라고 볼 수 있다.
보통 DB 연결 모듈에 사용을 한다.
장점
- 하나의 인스턴스를 다른 모듈과 공유를 하며 사용하기 때문에 인스턴스 생성 비용(메모리)이 줄어든다.
- 사용하기가 편하다.
단점
- 모듈간의 결합을 강하게 만들 수 있다.
- 단위 테스트가 어렵다.
단점인 결합도를 어떻게 낮출수 있는가?
의존성(종속성이라고도 함) 주입을 통해 모듈간의 결합을 조금 더 느슨하게 만들어서 해결을 할 수 있다.
위에 이미지를 보면 원래 메인 모듈에서 점점 하위 모듈로 의존성을 주는 모습을 볼 수 있다.
이것이 의존성이 높아진다고 한다.
이제 밑에 의존성 주입 후 를 확인 해보면 메인 모듈에서 하위모듈로 주는 것이 아닌
'의존성 주입자'가 중간을 가로채서 메인 모듈이 간접적으로 의존성을 주입하는 모습이 보인다.
이렇게 되면 메인 모듈은 하위 모듈에 대한 의존성이 떨어지게 된다. ( 디커플링이 된다 )
* 참고 : 결합도 (Coupling)
의존성 주입의 장단점은 무엇인가?
장점
- 모듈들을 쉽게 교체할 수 있는 구조가 되어 테스트가 쉬움
- 마이그레이션 하기 편함
- 의존성 방향이 일관되어짐
- 모듈 간의 관계가 명확해짐
단점
- 모듈이 더욱 분리 되므로 클래수 수가 늘어나 복잡성이 늘어날 수 있음
- 약간의 런타임 패널티가 생김
* 참고 : 의존성 주입 원칙
- 상위 모듈은 하위 모듈에서 어떠한 것도 가져오지 말아야 한다.
- 둘 다 추상화에 의존해야 함
- 추상화는 세부 사항에 의존하지 말아야 한다.
자바에서는 싱글톤은 어떻게 사용할 수 있는가?
// Singleton.java
package Singleton;
public class Singleton {
private static class singleInstanceHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static synchronized Singleton getInstance() {
return singleInstanceHolder.INSTANCE;
}
}
package Singleton;
public class Main {
public static void main(String[] args) {
Singleton a = Singleton.getInstance();
Singleton b = Singleton.getInstance();
System.out.println(a.hashCode());
System.out.println(b.hashCode());
if( a.hashCode() == b.hashCode() )
System.out.println("둘이 같은 주소!");
}
}
설명을 하기전에 hashCode() 메소드를 알아야한다.
hashCode() 란?
단순하게 객체의 hashCode를 리턴해주는 메소드이다.
hashCode는 일반적으로 각 객체의 주소값을 변환하여 생성한 객체의 고유한 정수 값이다.
코드의 결과 값을 확인해보자.
출력을 해본다면 서로 같은 hashCode를 가지고 있다는 점을 확인 할 수 있다.
간단하게 Spring 으로 예시를 확인해보자.
package com.example.test.DesignPattern;
public class Singleton {
private int a = 5;
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
public void printString(String value) {
System.out.println(value);
}
public int getA() {
return this.a;
}
public void setA(int a) {
this.a = a;
}
}
간단한 DB라고 생각하고 private int a = 5를 생성했다.
@RestController("/")
public class Controller {
Singleton tempA = Singleton.getInstance();
Singleton tempB = Singleton.getInstance();
@GetMapping("A")
public String getA() {
return String.valueOf(tempA.getA());
}
@PostMapping("A")
public String setB(@RequestBody Map<String, Integer> request ) {
int a = request.get("A");
tempB.setA(a);
return "success";
}
}
간단한 A컨트롤러를 만들어서 같은 내용을 참조하는지 확인을 해보자.
getA 메소드는 tempA를 사용하고
setB 메소드는 tempB를 사용한다.
Postman을 사용하여 확인해보자.
그냥 A를 호출했을 경우는 Singleton Class의 초기값인 5가 출력이 되는 모습을 확인 할 수 있다.
이제 tempB에 값을 10을 보냈다. 다시 getA를 해보자.
값이 10 이 나오는 모습을 확인 할 수 있었다.
결론
싱글톤(Singleton) 패턴은 결론적으로 하나의 클래스에 하나의 인스턴스를 사용을 한다.
싱글톤의 장점은 사용을 하기가 쉽고, 메모리 사용율을 줄일 수 있다는 점이다.
단점으로 의존성이 올라가고, 결합도가 높아진다, 테스트를 하기가 어려워진다는 점.
하지만 단점을 해결을 할 수 있는 부분이 의존성 주입(Dependency Injecting, DI)이다.
의존성 주입의 장점으로 모듈을 쉽게 교체 할 수 있는 구조가 된다. 의존성 방향이 일방향 된다는 점
단점으로 모듈을 세분화하기 때문에 클래스 수가 많아질 수 있다, 약간의 런타임의 패널티가 생기는 점이있다.
느낀 점
튜터님께 추천을 받은 책을 읽고 있는데 별로 안봤는데 벌써 이정도의 공부양이 생겼다.
알게 되는건 좋은데, 배우면 배울수록 배우는 양이 끝이 없다고 계속 생각이 든다.
내가 선택한 서버니까 화이팅 해야겠다.
참고서적
면접을 위한 CS 전공지식 노트 | 주홍철 - 교보문고
면접을 위한 CS 전공지식 노트 | 디자인 패턴, 네트워크, 운영체제, 데이터베이스, 자료 구조, 개발자 면접과 포트폴리오까지! CS 전공지식 습득과 면접 대비, 이 책 한 권이면 충분하다! 개발자 면
product.kyobobook.co.kr
'CS' 카테고리의 다른 글
[RESTful API] 어떻게 하면 좀 더 RESTful 해질 수 있을까? (3) | 2025.01.23 |
---|---|
[HTTP] Persistent Connent(지속 연결)에 대해서.araboza (2) | 2025.01.22 |