싱글톤 패턴이란? (Signleton Pattern)

리팩토링 벨로그·2022년 9월 29일
0

싱글톤 패턴의 정의

객체의 인스턴스가 오직 1개만 생성되는 패턴을 의미

싱글톤 패턴 코드 예시

public class Singleton {

    private static Singleton instance = new Singleton();
    
    private Singleton() {
        // 생성자는 외부에서 호출못하게 private 으로 지정해야 한다.
    }

    public static Singleton getInstance() {
        return instance;
    }

    public void say() {
        System.out.println("hi, there");
    }
}

싱글톤 패턴에서는 getter를 사용한다. 그 이유는?

싱글톤 패턴을 사용하는 이유

일단, confirm이라는 클래스가 있다 하자.
다른 클래스에서 confirm 클래스 접근 시, getter와 setter로 접근하여 수정 또는 반환하여 사용하여야 합니다. (즉, new를 사용하지 않습니다.)
이 때, 다른 클래스에서 각자 인스턴스를 생성하게 된다면 다른 클래스들끼리 confirm 클래스의 정보를 공유하기가 어렵게 된다는 문제점이 생깁니다.

  1. 메모리 측면-최초 한번 new 연산자 이용해서 고정된 메모리 영역 사용=>메모리 낭비 방지, 생성된 인스턴스 활용한다는 장점
  2. 클래스간 데이터 공유 쉬움-싱글톤 인스턴스가 전역으로 사용되는 인스턴스기에 다른 클래스의 인스턴스들이 접근하여 사용 가능
  3. 도메인 관점에서 인스턴스가 한 개만 존재하는 것을 보증하고 싶을 때 사용

싱글톤 패턴의 문제점

  1. 싱글톤 인스턴스는 전역으로 사용되는 인스턴스인데, 여러 클래스의 인스턴스에서 싱글톤 인스턴스의 데이터에 동시 접근 시, 동시성 문제 발생

  2. 싱글톤 패턴을 구현하는 코드 자체가 많이 필요

  3. 테스트의 어려움

  4. 의존 관계상 클라이언트가 구체 클래스에 의존

싱글톤 패턴 종합

=>결론적으로 유연성이 많이 떨어지는 패턴이라고 할 수 있다. 싱글톤 패턴 단독 사용 시, 실제로 싱글톤 패턴은 안티 패턴이라 불릴 만큼 객체 지향에 위반되는 사례가 많다.
그러나 스프링 컨테이너 같은 프레임 워크의 도움을 받으면 싱글턴 패턴의 문제점을 보완하면서 장점의 혜택을 누릴 수 있다. 실제로 스프링 빈은 컨테이너의 도움을 받아 싱글톤 스콥으로 관리된다.

싱글톤 패턴 사용 예시

1)싱글톤 클래스 생성
package src;

public class CompanyInfo {
    private static CompanyInfo innstance;

    private String companyName;
    private String companyAddr;


    private CompanyInfo()
    {
    }

    public static CompanyInfo getInstance()
    {
        if (innstance == null)
        {
            synchronized(CompanyInfo.class)
            {
                innstance = new CompanyInfo();
            }
        }

        return innstance;
    }


    // getter, setter
    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    public String getCompanyAddr() {
        return companyAddr;
    }

    public void setCompanyAddr(String companyAddr) {
        this.companyAddr = companyAddr;
    }
}

CompanyInfo라는 싱글톤 클래스를 만들었다.
getter, setter를 사용해야 한다.

2)테스트 코드1
package src;

import src.CompanyInfo;

public class SingletoneTest {
    public static void main(String[] args) {
        CompanyInfo companyInfo1 = CompanyInfo.getInstance();

        // setter로 접근
        companyInfo1.setCompanyName("회사명");
        companyInfo1.setCompanyAddr("회사주소");
    }
}
3) 테스트 코드2
public class TestClassTwo {
    
    public static void main(String[] args) {
        CompanyInfo companyInfo2 = CompanyInfo.getInstance();
        
        // getter로 접근 
        System.out.println( "companyName : " + companyInfo2.getCompanyName() );
        System.out.println( "companyAddr : " + companyInfo2.getCompanyAddr() );
    }
    
}
결과

데이터 공유 잘 됨
실행 순서를 테스트 코드1 -> 테스트 코드2로 실행하고 콘솔의 결과를 확인해보니 데이터 공유가 잘 된다.

companyName : 회사명
companyAddr : 회사주소

출처

싱글톤 패턴 정의, 장점, 싱글톤 패턴 기본 코드
https://tecoble.techcourse.co.kr/post/2020-11-07-singleton/
싱글톤 패턴의 필요성
https://itstudy402.tistory.com/8

추가로 알아봐야 할 것)import 키워드는 왜 테스트 코드에서 쓰였는가
IntelliJ 환경에서, am.1시 52분에 왜 저러한 오류가 났고 해결책은 무엇인지
IntelliJ 기본 코드 작성 환경 및 gradle 설정 방법
테스트 코드 사용 방법
테스트 코드를 분리해서 쓰는 방법은?

profile
글 다시 씁니다.

0개의 댓글