[Java 디자인패턴]  static을 응용한 싱글톤 패턴(Singleton Pattern) 구현

클래스 내의 변수에 static 키워드를 붙이면 그 클래스의 인스턴스들이 공유하는 클래스 변수가 됩니다. 다음 예제를 봅시다. 사용자 클래스 User로 인스턴스를 생성할 때 마다 첫 번째 인스턴스에는 1001을, 두 번째 인스턴스에는 1002, 다음은 1003, ... 이런식으로 1000부터 시작해서 인스턴스를 생성할 때마다 1씩 증가시켜 id를 부여해주려고 합니다.

 

/*
사용자 클래스
 */
public class User {

    private static Long serialNumber = 1000L;
    private Long userId;
    private String userName;

    public User(String userName) {
        this.userName = userName;
        serialNumber++;
        this.userId = serialNumber;
    }

    public static Long getSerialNumber() {
        return serialNumber;
    }

    @Override
    public String toString() {
        return "User{" +
                "userId=" + userId +
                ", userName='" + userName + '\'' +
                '}';
    }

    public static void main(String[] args) {

        System.out.println(User.getSerialNumber());     // serialNumber: 1000

        User user1 = new User("김현정");
        System.out.println(User.getSerialNumber());     // serialNumber: 1001

        User user2 = new User("서지은");
        System.out.println(User.getSerialNumber());     // serialNumber: 1002

        User user3 = new User("박주영");
        System.out.println(User.getSerialNumber());     // serialNumber: 1003

        System.out.println(user1);
        System.out.println(user2);
        System.out.println(user3);
    }
}

 

User 클래스의 serialNumber 변수에 static 키워드가 붙어있습니다. 즉 serialNumber는 static 변수(클래스 변수)로써, User 클래스로 생성하는 모든 인스턴스가 공유하는 값이 됩니다. 1000번부터 시작할 것이므로 1000으로 초기화를 해두었습니다.

 

다음으로 중요하게 볼 것은 생성자입니다. 생성자는 객체를 생성할 때 마다 호출되지요.

그래서 생성자 안에 serialNumber를 1 증가하는 코드를 넣어주었습니다.

이제 User()가 호출될 때 마다 serialNumber는 1000부터 1씩 증가합니다.

 

그리고 serialNumber는 외부에서 수정할 수 없도록 private 접근제어자를 붙여주고 값을 받아갈 수 있도록 getter를 만들어주었습니다.

 

이제 main 메소드에서 User 인스턴스를 하나씩 만들며 확인해봅시다.

구상한 대로, 인스턴스를 생성할 때 마다 User 클래스의 serialNumber가 1씩 증가하고 각 인스턴스의 userId 변수에 증가된 serialNumber가 할당되었습니다.

 

???? 실행 결과

1000
1001
1002
1003
User{userId=1001, userName='김현정'}
User{userId=1002, userName='서지은'}
User{userId=1003, userName='박주영'}
1003

Process finished with exit code 0

 

싱글톤 패턴(Singleton Pattern)

이렇게 static 변수는 단순히 모든 인스턴스들이 공유하기 위한 변수를 만들기 위해서도 사용되지만 이러한 static 키워드의 특성을 이용한 디자인패턴이 싱글톤 패턴(Singleton Pattern) 입니다. 디자인 패턴은 객체지향 프로그래밍 언어로 프로그램을 설계할 때 효율적이고 유지보수가 용이하게 하기 위한 설계 기법입니다.

싱글톤 패턴은 하나의 프로젝트, 어플리케이션 안에서 단 한 개만 존재해야 하는 인스턴스를 생성해야 할 경우 사용할 수 있습니다.

 

어떤 클래스를 싱글톤 패턴으로 구현하는 방법은 다음 세 가지를 지키면 됩니다.

① private 생성자
② static 변수로 객체 생성
③ 객체의 getter 구현

클래스를 위와 같이 설계하면 인스턴스의 유일성이 보장됩니다.

 

어떤 프로젝트에서 상점 클래스 Store의 객체는 어플리케이션에서 단 한 개만 사용해야 한다고 가정해봅시다.

Store 클래스를 싱글톤 패턴으로 구현한 예제입니다.

 

public class Store {

    private static Store instance = new Store();

    private Store() { }

    public static Store getInstance() {
        return instance;
    }
}

public class StoreTest {

    public static void main(String[] args) {

        Store store1 = Store.getInstance();
        Store store2 = Store.getInstance();
        //Store store3 = new Store();   // 직접 생성 불가

        System.out.println(store1);
        System.out.println(store2);
    }
}

 

Store 클래스 내에 Store 타입의 static 변수 instance를 선언해서 객체를 생성해주었습니다.

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

여기서 생성한 객체는 static 메모리 영역에 할당되어 어플리케이션 전체에서 이 객체만을 유일하게 사용하게 됩니다.

왜냐면, 생성자의 접근제어자를 private으로 했기 때문에 Store 클래스 외부에서는 절대로 호출할 수 없기 때문입니다.

마지막으로 외부에서 사용할 수 있도록 Store 객체를 반환하는 static getter를 만들어줍니다.

 

StoreTest 클래스의 main 메소드에서 Store 인스턴스를 사용합니다.

new Store()와 같이 생성할 수 없고 Store의 getInstance()를 호출함으로써 Store 인스턴스에 접근할 수 있습니다.

 

???? 실행 결과

com.yoon._static.Store@2c8d66b2
com.yoon._static.Store@2c8d66b2

Process finished with exit code 0

 

store1, store2를 찍어보면 해시코드 값이 동일함을 알 수 있습니다.

즉, 두 변수는 같은 인스턴스를 참조하고 있습니다.

 

자바 API에서 싱글톤 패턴이 적용된 예로는 Calendar 클래스가 있습니다.

// Calendar calendar = new Calendar(); // 직접 생성 불가
Calendar calendar = Calendar.getInstance();

Calendar 클래스도 위에서 구현한 Store 클래스와 마찬가지로 싱글톤 패턴이 적용되어 있기 때문에 new 연산자로 생성이 불가능하며 Calendar의 static 인스턴스를 반환해주는 getInstance()를 호출해야 합니다.

 

 

이처럼 싱글톤 패턴은 직접 구현할 경우도, 적용되어 있는 클래스를 사용할 경우도 많은 디자인 패턴 중 하나입니다.

 

[출처] https://atoz-develop.tistory.com/entry/%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4-static%EC%9D%84-%EC%9D%91%EC%9A%A9%ED%95%9C-%EC%8B%B1%EA%B8%80%ED%86%A4-%ED%8C%A8%ED%84%B4Singleton-Pattern-%EA%B5%AC%ED%98%84

 

 

 

 

 

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
58 [Spring Boot] [VS Code] VSCode에 Spring Boot 개발 환경 세팅 및 샘플 프로젝트 생성, 실행 file 졸리운_곰 2024.07.08 272
57 [java, spring] Spring에서 request와 response를 JSON format 으로 한번에 로깅하기 file 졸리운_곰 2021.06.18 465
56 [Spring Boot] 2) Springboot OncePerRequestFilter 와 GenericFilterBean의 차이 file 졸리운_곰 2021.06.18 184
55 [Spring boot] [Spring boot] Spring Boot servlet filter 사용하기 졸리운_곰 2021.06.18 164
54 [SpringBoot] Filter(필터) OncePerRequestFilter간단히 사용하기 file 졸리운_곰 2021.06.18 259
53 [Spring boot] Spring boot 에서 Filter 사용하기 졸리운_곰 2021.06.18 195
52 [Spring Boot] 스프링 부트에 필터를 '조심해서' 사용하는 두 가지 방법 졸리운_곰 2021.06.18 282
51 [스프링 배치] java Spring Batch 졸리운_곰 2020.12.16 242
50 MyBatisPagingItemReader.java 졸리운_곰 2020.11.07 312
49 [JPA] 스프링 데이터 JPA 소개 file 졸리운_곰 2020.11.07 193
48 Spring Batch Example 3 - 청크 지향 프로세싱 file 졸리운_곰 2020.10.24 210
47 Spring Batch Example 2 - 간단한 Job만들기 file 졸리운_곰 2020.10.24 216
46 Spring Batch Example 1 - Spring Batch란? file 졸리운_곰 2020.10.24 221
45 [spring batch] Spring batch Job 설정과 실행하기 file 졸리운_곰 2020.10.24 199
44 public class MyBatisPagingItemReader<T> extends AbstractPagingItemReader<T> { 졸리운_곰 2020.10.23 275
43 public class MyBatisBatchItemWriter<T> implements ItemWriter<T>, InitializingBean { 졸리운_곰 2020.10.23 248
42 MyBatisPagingItemReader, MyBatisPagingItemWriter 졸리운_곰 2020.10.23 411
41 [spring batch] 처음 해보는 Spring batch, Tasklet 작성하기 file 졸리운_곰 2020.10.18 184
40 Spring Boot - Properties 사용법 정리 졸리운_곰 2020.10.15 232
39 spring 설정 xml과 소스코드에서 properties 사용하기 졸리운_곰 2020.10.15 179
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED