생성자를 사용할 때와 getInstance () 메서드 (정적 팩토리 메서드)를 사용할 때


84
  1. 생성자를 언제 어떻게 사용해야합니까?

    Foo bar = new Foo();
    
  2. 그리고 언제 어떻게 getInstance () (정적 팩토리 메서드)를 사용해야합니까?

    Foo bar = Foo.getInstance();
    

이 둘의 차이점은 무엇입니까? 나는 항상 생성자를 사용했지만, getInstance()대신 언제 사용해야 합니까?


수업을 직접 작성하고 있습니까? 그렇지 않다면 그것을 제공하는 무엇을 부르고 있습니까?
Chris B.

그래서, 클래스 자체의 구현은 싱글 톤 패턴을 구현하고 있음을 의미합니다.
zengr 2010

호출 getInstance() 하고 있습니까 , 아니면 라는 메서드작성하고getInstance() 있습니까?
Chris B.

1
질문이 생성자 대 정적 팩토리 메서드 에 관한 것이라면 제목을 명확히하고 변경하는 것이 좋습니다.
Pascal Thivent

@zengr : update2와 관련하여 이는 이름을 지정해야한다는 규칙에 따라 정적 메서드의 이름을 지정하지 않았기 때문일 수 있습니다 Foo.newInstance(). Foo.getInstance()클래스의 싱글 톤 인스턴스를 얻기위한 규칙입니다. 예제를 수정하고 Foo.newInstance()대신 사용해야 합니다.
JRL

답변:


96

나는 질문이 실제로 생성자 대 정적 팩토리 메소드에 관한 것이라고 생각하는 동안 모든 사람들이 싱글 톤에 초점을 맞추는 것 같습니다 .

이것은 실제로 항목 1 : Joshua Bloch 의 Effective Java 생성자 대신 정적 팩토리 메소드를 고려하십시오 .

항목 1 : 생성자 대신 정적 팩토리 메서드 고려

클래스가 클라이언트가 자신의 인스턴스를 얻을 수 있도록 허용하는 일반적인 방법은 공용 생성자를 제공하는 것입니다. 모든 프로그래머의 툴킷에 포함되어야하는 또 다른 기술이 있습니다. 클래스는 클래스 의 인스턴스를 반환하는 정적 메서드 인 공용 정적 팩토리 메서드를 제공 할 수 있습니다 . 다음은 Boolean(기본 유형에 대한 박스형 기본 클래스) 의 간단한 예입니다 boolean. 이 메서드는 부울 프리미티브 값을 Boolean객체 참조 로 변환합니다 .

public static Boolean valueOf(boolean b) {
    return b ? Boolean.TRUE : Boolean.FALSE;
}

정적 팩토리 방법은 디자인 패턴팩토리 방법 패턴 과 동일하지 않습니다 [Gamma95, p. 107]. 이 항목에 설명 된 정적 팩토리 방법은 디자인 패턴에 직접 해당되지 않습니다. .

클래스는 클라이언트에게 생성자 대신 또는 생성자에 추가하여 정적 팩토리 메서드를 제공 할 수 있습니다. 공용 생성자 대신 정적 팩토리 메서드를 제공하면 장점과 단점이 모두 있습니다.

장점 (책 인용) :

  • 정적 팩토리 메서드의 한 가지 장점은 생성자와 달리 이름이 있다는 것입니다.
  • 정적 팩토리 메서드의 두 번째 장점은 생성자와 달리 호출 될 때마다 새 개체를 만들 필요가 없다는 것입니다.
  • 정적 팩토리 메서드의 세 번째 장점은 생성자와 달리 반환 유형의 모든 하위 유형의 객체를 반환 할 수 있다는 것입니다.
  • 정적 팩토리 메서드의 네 번째 장점은 매개 변수가있는 형식 인스턴스를 만드는 자세한 정도를 줄이는 것입니다.

단점 (여전히 책 인용) :

  • 정적 팩토리 메서드 만 제공 할 때의 가장 큰 단점은 공용 또는 보호 된 생성자가없는 클래스는 하위 클래스화할 수 없다는 것입니다.
  • 정적 팩토리 메소드의 두 번째 단점은 다른 정적 메소드와 쉽게 구별 할 수 없다는 것입니다.

8
마지막 것은 다소 완화 될 수 있습니다. Factory 메서드를 만들 때 더 명확하게 만들기 위해 Factory라는 정적 내부 클래스와 다양한 newInstance 메서드가있는 경향이 있습니다. 그것은 과거에 저를 사냥하는 시간을 절약했습니다. :)
Rich Schuler

@Qberticus 공장 메서드 전용 내부 클래스는 좋은 생각입니다. 나는 그것을 시도 할 것이다, thx.
Dave O.

확실히 클래스의 생성자는 최소한 protected서브 클래 싱을 허용 해야 하지만, 클라이언트 코드는 새 객체를 만들고 생성자를 호출하는 것이 정적 팩토리 메서드를 호출하는 것보다 실질적인 이점을 얻습니까? 연결된 생성자 호출은 의미 론적으로 인스턴스 메서드 인 반면, 시퀀스 "단일화 된 객체 생성 및 생성자 호출"은 의미 상 정적 팩토리 메서드 호출과 동일합니다.
supercat 2014-01-29

9

때 내가해야 : 당신은 두 가지 질문이있어 전화getInstance() 방법을, 나는 때를해야 생성 을?

당신이 전화를 할 것인지 여부를 결정하는 경우getInstance() 방법은 간단합니다. 언제 호출해야하는지 알아 보려면 클래스 문서를 읽어야합니다. 예를 들면, NumberFormat생성자 제공 하고getInstance() 방법; 이 getInstance()방법은 현지화 된 NumberFormat. 를 들어 Calendar, 다른 한편으로는, 생성자가 보호됩니다. 당신 전화 getInstance()를받을 수 있습니다.

생성 여부를 결정하는 경우getInstance() 방법을, 당신은 당신이 달성하기 위해 노력하고 무엇을 결정해야합니다. 어느 쪽이든 당신은 하지 않는 사람들이 생성자를 (당신이 만드는 전화 할 싱글 또는 공장 ), 또는 (같이 괜찮다 NumberFormat가 발신자의 편의를 위해 일부 개체를 초기화하는 경우, 위).


짧은 이야기? getInstance()자신의 코드에서 메서드를 만드는 것에 대해 걱정하지 마십시오 . 유용 할 때가되면 알게 될 것입니다. 그리고 일반적으로 클래스의 생성자를 호출 할 있다면 클래스가 getInstance()메서드를 제공하더라도 그렇게해야 할 것 입니다.


7

getInstance 메소드의 용도 :

그러나 대부분의 경우 개체는 간단한 POJO 이며 공용 생성자를 사용하는 것이 가장 실용적이고 확실한 솔루션입니다.

U1 : 다른 클래스의 getInstance

다른 클래스의 인스턴스를 반환하려면 :

public class FooFactory {
    public static Foo getInstance() {
        return new Foo();
    }
}

NumberFormat.getInstance메서드는 실제로 DecimalFormat.

U2 : 싱글 톤 문제

싱글 톤 패턴은 객체 지향 프로그래밍의 많은 이점을 제한합니다. 싱글 톤에는 일반적으로 개인 생성자가 있으므로 확장 할 수 없습니다. getInstance 메서드를 통해 액세스하고 인터페이스를 참조하지 않으므로 다른 구현을 위해 스왑 할 수 없습니다.


팩토리 패턴의 경우 'createInstance'또는 'buildInstance'와 같은 다른 메서드 이름이 훨씬 더 적합 할 수 있지만 질문자가 원하는 것의 가능한 경우 일 수 있습니다 (여전히 약간 모호하고 숙제처럼 들립니다)
jdehaan

6

둘 다 사용할 수 있다면 제대로 구현되지 않은 싱글 톤 패턴 처럼 들립니다 .

시스템에 클래스의 단일 인스턴스 만 있고 생성자를 비공개로 만들려는 경우 두 번째 옵션을 사용합니다.

첫 번째를 사용하여 클래스의 여러 개체를 만들 수 있습니다.

그러나 수업에 두 가지 가능성을 모두주지 마십시오.

싱글 톤을 과도하게 사용하지 않도록주의하고, 시스템에 실제로 하나의 인스턴스 만 존재할 경우에만 사용하십시오. 그렇지 않으면 다른 프로젝트에서 클래스 재사용 가능성을 제한 할 수 있습니다. 프로젝트의 모든 곳에서 getInstance를 호출 할 수 있다는 것이 흥미로울 것 같지만 실제로 해당 인스턴스를 소유 한 사람이 누구인지 명확하지 않습니다. 아무도 및 / 또는 모두. 프로젝트에 싱글 톤이 많은 경우 시스템이 잘못 설계되었다고 확신 할 수 있습니다 (일반적으로). 싱글 톤은주의해서 사용해야하며 전역 변수와 동일한 조언이 적용됩니다.


질문 업데이트, 약간 혼란 스러웠습니다. 죄송합니다
zengr

4
------> "끝나지 사용 싱글에주의해야"<------
바트 밴 Heukelom

1

내가 항상 일반 생성자보다 정적 팩토리를 선호하는 한 가지 경우는 객체 생성이 느려질 것이라는 것을 알 때입니다. 생성자에서 간단한 초기화를 수행하지만 무거운 것을 만들어야하는 경우 정적 메서드를 사용하고 동작을 문서화합니다.


0

싱글 톤은 악합니다. 내가 본 문제는 시스템의 재사용이나 확장성에 관한 것이 아니라 (어떻게 발생할 수 있는지 알 수는 있지만) 더 많은 문제가 발생하여 모호한 버그를 본 횟수를 셀 수 없습니다. 싱글 톤에서 발생하는 시스템.

싱글 톤을 사용해야하는 경우 범위가 매우 좁은 지 확인하십시오. 즉, 시스템에 대해 알고있는 다른 객체의 수를 신중하게 제한하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.