-
싱글톤(Singleton)패턴1Web 개발/디자인 패턴 2023. 6. 17. 11:47
싱글톤 패턴
인스턴스를 오직 한개만 제공하는 클래스
시스템 런타임, 환경세팅에 대한 정보 등, 인스턴스가 여러개 일 때 문제가 생길 수 있는 경우가 있다. 인스턴스를 오직 한개만 만들어 제공하는 클래스가 필요하다.
private한 생성자와 static한 메서드를 이용한 구현
Settings.class
public class Settings{ }
App.class
public class App{ public static void mian(String[] args){ Settings setting = new Settings(); Settings setting1 = new Settings(); } }
App이라는 class가 있고, Settings라는 class가 있다. 이때 App class에서 Settings class의 인스턴스를 얼마든지 만들 수 있다. 즉 Settings 타입의 인스턴스가 얼마든지 만들어질 수 있다는 것을 의미한다.
public class App{ public static void mian(String[] args){ Settings setting = new Settings(); Settings setting1 = new Settings(); System.out.println(setting != settings1); } }
두개의 다른 인스턴스를 만들면 두 인스터스는 같지 않다.
public class Settings{ private Settings(){} }
그러므로 싱글톤 패턴을 구현하려면 절대 new 연산자로 인스턴스를 생성하면 안된다. 자바에서 new를 사용해서 생성자를 만들지 못하게 하려면 private 생성자를 만들어주면 된다. 오직 Settings 클래스 안에서만 접근할 수 있는 생성자를 만들어 주는 것이다. 이렇게 되면 더이상 Settings 클라스 밖에서 새로운 Settings 타입의 인스턴스를 생성할 수 없다.
public class Settings{ private Settings(){} public static Settings getInstance(){ return new Settings(); } }
이제 Settings 클래스 밖에서 인스턴스를 만들 수 없기 때문에 Settings 클래스 안에서 인스턴스를 만들어서 글로벌하게 접근가능 하도록 만들어야 한다. 글로벌 하게 접근 가능하게 만드는 방법은 static을 사용하는 것이다. static한 getInstance()메서드를 Settings 클래스안에 만들어 준다.
public class App{ public static void mian(String[] args){ Settings setting = Settings.getInstance(); Settings setting1 = Settings.getInstance(); System.out.println(setting != settings1); } }
하지만 getInstance()메서드를 만들때 Settings 클래스에서 new Setting()를 사용한 것도 문제가 된다. Settings.getInstance()를 부를대 마다 새로운 Settings 클래스의 인스턴스가 생성되어 반환되기 때문이다.
해결방법
public class Settings{ private static Settings instance; private Settings(){} public static Settings getInstance(){ if(instance == null){ instance = new Settings(); } return instance; } }
Settings 인스턴스가 null일때만 new 연산자로 Settings 인스턴스를 만들어주고 이미 존재한다면 이미 존재하는 Settings instance를 반환한다.
public class App{ public static void mian(String[] args){ Settings setting = Settings.getInstance(); Settings setting1 = Settings.getInstance(); System.out.println(setting -== settings1); } }
이렇게 하면 getInstance()메서드를 부를 때 마다 같은 인스턴스가 반환 된다.
❗하지만 private한 생성자와 static한 메서드를 이용한 구현 방법에는 치명적인 문제가 존재한다. 보통 웹 어플리케이션을 만들 멀티 쓰레드를 사용하게 된다. 즉 여러 쓰레드가 동시에 접근할 수 있는 코드가 된다. 그런 환경에서 private한 생성자와 static한 메서드를 이용한 구현 방법은 안전하지 못하다.
[출처 - https://www.inflearn.com/course/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4/dashboard]
'Web 개발 > 디자인 패턴' 카테고리의 다른 글
팩토리 메소드(Factory Method)패턴1 (0) 2023.06.25 싱클톤(Singleton)패턴 구현2 (0) 2023.06.17 디자인 원칙 - 구현이 아닌 인터페이스에 대해 프로그래밍 (0) 2022.12.21 디자인 원칙 - 변화하는 내용을 캡슐화 (0) 2022.12.20 디자인패턴 - 소개 (0) 2022.12.19