해당 패턴은 어떠한 클래스가 유일하게 1개만 존재할 때 사용합니다. 즉, 똑같은 인스턴스를 만들지 않고 기존의 인스턴스를 활용하는 것입니다.
생성자가 여러번 호출되어도 이미 생성한 객체를 반환시키도록 만드는 것입니다. 객체 생성할 때 마다 메모리 영역을 할당하지 않고 한번만 객체를 생성한다면 메모리 낭비를 방지할 수 있습니다. 메모리 낭비를 막기 위해 실제 프로그래밍에서는 TCP Socket 통신에서 서버와 연결된 connect 객체에 주로 사용합니다. 또한 싱글톤으로 구현한 인스턴스는 전역이므로, 다른 클래스의 인스턴스들이 데이터 공유가 가능한 장점이 있습니다.
주로 사용하는 곳은 서로 자원을 공유할 때 사용하거나, 공통된 객체를 여러개 생성하여 사용해야 하는 상황에 사용됩니다. 다수의 컴퓨터에 연결된 프린터 1개 같은 느낌입니다.
싱글톤 인스턴스가 지나치게 많은 것을 공유하면 다른 클래스들끼리의 결합도가 높아질 수 밖에 없습니다. 결합도가 높아지면 유지보수가 힘들고 테스트가 원할하게 진행되는 상황이 나오지 않습니다. 따라서 반드시 싱글톤이 필요한 상황이 아니면 쓰지 않는게 제일 좋다고 생각합니다.
SocketClient
public class SocketClient {
private static SocketClient sc = null;
private SocketClient() {
}
public static SocketClient getInstance() {
if (sc == null) {
sc = new SocketClient();
}
return sc;
}
}
Test1, Test2
public class Test1 {
private SocketClient sc;
public Test1() {
this.sc = SocketClient.getInstance();
}
public SocketClient getSocketClient() {
return this.sc;
}
}
public class Test2 {
private SocketClient sc;
public Test2() {
this.sc = SocketClient.getInstance();
}
public SocketClient getSocketClient() {
return this.sc;
}
}
Main
public class Main {
public static void main(String[] args) {
Test1 t1 = new Test1();
Test2 t2 = new Test2();
System.out.println(t1.getSocketClient() == t2.getSocketClient());
}
}
해당 코드를 실행하면 true라는 값이 출력되게 된다. 그 이유는 싱글톤 객체를 사용하였기 때문입니다. 만일 SocketClient 생성자가 private이 아닌 public이였다면 각각 다른 객체가 생성되었을것입니다.