[java] Singleton의 대안

애플리케이션에 대한 구성 정보를 보유하는 클래스가 있습니다. 예전에는 싱글 톤이었습니다. 아키텍처 검토 후 싱글 톤을 제거하라는 지시를 받았습니다. 한 번에 다른 구성을 테스트 할 수 있기 때문에 단위 테스트에서 싱글 톤을 사용하지 않는 몇 가지 이점을 확인했습니다.

싱글 톤이 없으면 코드의 모든 곳에서 인스턴스를 전달해야합니다. 너무 지저분 해져서 싱글 톤 래퍼를 작성했습니다. 이제 동일한 코드를 PHP와 .NET으로 포팅하고 있습니다. 구성 객체에 사용할 수있는 더 나은 패턴이 있는지 궁금합니다.



답변

구글 테스트 블로그 (테스트 가능한 코드를 생성하기 위해) 싱글 방지에 관한 항목의 시리즈가있다. 아마도 이것은 당신을 도울 수 있습니다 :

마지막 기사에서는 싱글 톤 사용을 피할 수 있도록 새 오브젝트 생성을 팩토리로 이동하는 방법을 자세히 설명합니다. 확실히 읽을 가치가 있습니다.

요컨대 우리는 모든 신규 작업자를 공장으로 옮깁니다. 수명이 비슷한 모든 개체를 하나의 공장으로 그룹화합니다.


답변

가장 좋은 방법은 대신 Factory 패턴을 사용하는 것입니다. 클래스의 새 인스턴스를 생성 할 때 (팩토리에서) 새로 생성 된 객체에 ‘전역’데이터를 삽입 할 수 있습니다. 단일 인스턴스에 대한 참조 (팩토리 클래스에 저장)로 또는 관련 데이터를 새 개체에 추가합니다.

그러면 모든 개체에 싱글 톤에 살던 데이터가 포함됩니다. 전반적으로 큰 차이는 없다고 생각하지만 코드를 더 쉽게 읽을 수 있습니다.


답변

여기에 명백한 내용이 있지만 Spring 또는 Guice 와 같은 종속성 주입 프레임 워크를 사용할 수없는 이유가 있습니까? (나는 Spring도 .NET에서도 사용할 수 있다고 믿습니다).

이런 식으로 프레임 워크는 구성 개체의 단일 복사본을 보유 할 수 있으며 빈 (서비스, DAO 등)은 검색에 대해 걱정할 필요가 없습니다.

이것이 제가 일반적으로 취하는 접근 방식입니다!


답변

Spring Framework 를 사용 하는 경우 일반 빈을 생성 할 수 있습니다. 기본적으로 (또는 명시 적으로 설정 scope="singleton"한 경우) Bean의 인스턴스는 하나만 생성되고 해당 인스턴스는 Bean이 종속성에서 사용되거나를 통해 검색 될 때마다 반환됩니다 getBean().

Singleton 패턴의 결합없이 단일 인스턴스의 이점을 얻을 수 있습니다.


답변

대안은 물건에 물건을 요청하는 대신 필요한 것을 전달하는 것입니다.


답변

이해하기 어렵고 깨지기 쉬운 매우 큰 개체로 끝날 것이기 때문에 단일 구성 개체에 대한 책임을 축적하지 마십시오 .

예를 들어 특정 클래스에 다른 매개 변수가 필요한 경우 Configuration개체 를 변경 한 다음이를 사용하는 모든 클래스를 다시 컴파일합니다. 이것은 다소 문제가 있습니다.

일반적이고 전역 적이며 큰 Configuration객체 를 피하기 위해 코드를 리팩토링하십시오 . 필수 매개 변수 만 클라이언트 클래스에 전달하십시오.

class Server {

    int port;

    Server(Configuration config) {
        this.port = config.getServerPort();
    }

}

다음과 같이 리팩토링되어야합니다.

 class Server {

    public Server(int port) {
       this.port = port;
    }
 }

의존성 주입 프레임 워크는 여기에 많은 도움이 될 것입니다,하지만 stricly 필요하지 않습니다.


답변

정적 메서드를 사용하여 싱글 톤의 동일한 동작을 수행 할 수 있습니다. Steve yegge는 게시물 에서이를 매우 잘 설명합니다 .