[java] 정적 팩토리 메소드 란 무엇입니까?



Answers

정적 팩토리 메소드 패턴 은 오브젝트 작성을 캡슐화하는 방법입니다. 팩토리 메소드가 없다면 Foo x = new Foo() 클래스의 constructor 직접 호출하면됩니다. 이 패턴을 사용하면 대신 factory 메소드를 호출합니다. Foo x = Foo.create() . 생성자는 private로 표시되므로 클래스 내부를 제외하고는 호출 할 수 없으며 factory 메소드는 static 으로 표시되므로 먼저 객체가 없어도 호출 할 수 있습니다.

이 패턴에는 몇 가지 장점이 있습니다. 하나는 팩토리가 여러 서브 클래스 (또는 인터페이스 구현 자) 중에서 선택하여 리턴 할 수 있다는 것입니다. 이렇게하면 호출자는 잠재적으로 복잡한 클래스 계층을 알거나 이해하지 않고도 매개 변수를 통해 원하는 동작을 지정할 수 있습니다.

또 다른 장점은 Matthew와 James가 지적한 바와 같이 연결과 같은 제한된 리소스에 대한 액세스를 제어하는 ​​것입니다. 이렇게 재사용 가능한 객체 풀 을 구현하는 방법 - 객체를 작성 , 사용 및 분해하는 대신에 비싼 프로세스 인 경우에는 한 번 빌드하고 재활용하는 것이 더 적합 할 수 있습니다. 팩토리 메서드는 기존의 사용되지 않는 인스턴스화 된 객체가 있으면 기존 객체를 반환하거나 객체 수가 일부 임계 값보다 낮 으면 객체를 생성하거나 예외를 throw하거나 상위 임계 값보다 큰 경우 null 반환 할 수 있습니다.

Wikipedia에있는 기사에 따르면 여러 팩터 방법을 사용하여 유사한 인수 유형에 대한 다른 해석을 허용합니다. 일반적으로 생성자는 클래스와 동일한 이름을 갖습니다. 즉, 지정된 signature 생성자를 하나만 가질 수 있습니다. 팩토리는 제약이 없으므로 동일한 인수 유형을 허용하는 두 가지 메소드를 가질 수 있습니다.

Coordinate c = Coordinate.createFromCartesian(double x, double y)

Coordinate c = Coordinate.createFromPolar(double distance, double angle)

이것은 Rasmus가 지적했듯이 가독성을 향상시키는 데에도 사용할 수 있습니다.

Question

"정적 팩토리"메소드 란 무엇입니까?




private 생성자가있는 정적 팩토리 메소드의 장점 중 하나는 (인스턴스 생성이 외부에서 생성되지 않도록 객체 생성이 제한되어 있어야한다는 것입니다) 인스턴스 제어 클래스를 만들 수 있다는 것입니다. 그리고 인스턴스 제어 클래스는 equals 메소드 대신 == 연산자를 사용하여 객체의 평등을 검사 할 수 있다는 것을 의미합니다 (프로그램이 실행되는 동안 a == b 인 경우에만 a.equals (b) 가 존재하지 않음) , 유효 자바에 따르면.

반복 팩토리로부터 같은 오브젝트를 돌려주는 static 팩토리 메소드의 기능에 의해, 클래스는 언제라도 존재하는 인스턴스를 엄밀하게 제어 할 수 있습니다. 이를 수행하는 클래스는 인스턴스 제어라고합니다. 인스턴스 제어 클래스를 작성해야하는 몇 가지 이유가 있습니다. 인스턴스 제어를 통해 클래스는 그것이 싱글 톤 (항목 3) 또는 인스턴스 불가능 (항목 4)임을 보장 할 수 있습니다. 또한 불변 클래스 (항목 15)가 a == b 인 경우에만 a.equals (b)가 존재하지 않는다는 것을 보증 할 수 있습니다. 클래스가이 보증을하면 클라이언트는 equals (Object) 메서드 대신 == 연산자를 사용할 수 있으므로 성능이 향상 될 수 있습니다. Enum 유형 (항목 30)은이 보증을 제공합니다.

Effective Java, Joshua Bloch (항목 1, 6 페이지)




그것은 모두 유지 보수 가능성으로 귀결됩니다. 이것을 넣는 가장 좋은 방법은 new 키워드를 사용하여 객체를 만들 때마다 작성하는 코드를 구현에 연결하는 것입니다.

팩토리 패턴을 사용하면 객체로 수행하는 작업에서 객체를 만드는 방법을 분리 할 수 ​​있습니다. 생성자를 사용하여 모든 객체를 만들면 객체를 사용하는 코드를 해당 구현에 본질적으로 하드 와이어 링합니다. 개체를 사용하는 코드는 해당 개체에 "종속"됩니다. 이것은 표면적으로 큰 문제가 아닐지 모르지만, 객체가 변경되면 (생성자의 시그니처를 변경하거나 객체를 서브 클래 싱하는 것으로 생각할 때) 다시 돌아와서 모든 것을 다시 배선해야합니다.

오늘날 공장에서는 의존성 주입 (Dependency Injection)을 사용하기 위해 크게 보강되었습니다. 왜냐하면 보일러 플레이트 코드를 많이 유지해야하기 때문입니다. Dependency Injection은 기본적으로 공장과 동일하지만 객체가 구성 또는 주석을 통해 선언적으로 함께 연결되는 방법을 지정할 수 있습니다.




나는 내가 아는 것에이 글에 빛을 더할 것이라고 생각했다. 우리는 recent android project 에서이 기술을 광범위하게 사용했습니다. creating objects using new operatorcreating objects using new operator 대신 static method 를 사용하여 클래스를 인스턴스화 할 수도 있습니다. 코드 목록 :

//instantiating a class using constructor
Vinoth vin = new Vinoth(); 

//instantiating the class using static method
Class Vinoth{
  private Vinoth(){
  }
  // factory method to instantiate the class
  public static Vinoth getInstance(){
    if(someCondition)
        return new Vinoth();
  }
}

정적 메서드는 조건부 개체 만들기를 지원합니다 . 생성자를 호출 할 때마다 개체가 만들어 지지만 원하지 않을 수 있습니다. 조건을 확인하기 만하면 새로운 객체를 만들고 싶다고 가정합니다. 조건이 만족되지 않으면 매번 새로운 인스턴스를 생성하지 않을 것입니다.

Effective Java 에서 가져온 또 다른 예입니다.

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

이 메소드는 boolean 프리미티브 값을 Boolean 객체 참조로 변환합니다. Boolean.valueOf(boolean) 메소드는 우리에게 객체를 생성하지 않는다는 것을 보여줍니다. 반복 static factory methods 로부터 같은 오브젝트를 돌려주는 static factory methods 의 기능에 의해, 클래스는 언제라도 존재하는 인스턴스를 엄밀하게 제어 할 수 있습니다.

Static factory methodsconstructors 와 달리 반환 subtypesubtypeobject 를 반환 할 수 있다는 점에서 다릅니다. 이러한 유연성의 한 응용 프로그램은 클래스를 공개하지 않고 개체를 반환 할 수 있다는 것입니다. 이러한 방식으로 구현 클래스를 숨기면 매우 컴팩트 한 API가됩니다.

Calendar.getInstance ()는 위의 훌륭한 예제이며, 로케일에 따라 BuddhistCalendar , JapaneseImperialCalendar 또는 기본적으로 한 Georgian 만듭니다.

내가 생각할 수있는 또 다른 예제는 Singleton pattern . 여기서 생성자를 private으로 만들면 항상 사용할 수있는 인스턴스가 하나뿐임을 확인하는 자체 getInstance 메서드를 만듭니다.

public class Singleton{
    //initailzed during class loading
    private static final Singleton INSTANCE = new Singleton();

    //to prevent creating another instance of Singleton
    private Singleton(){}

    public static Singleton getSingleton(){
        return INSTANCE;
    }
}



Static 팩토리에서 유래하는 장점 중 하나는 해당 API가 클래스를 공개하지 않고 객체를 반환 할 수 있다는 것입니다. 이는 매우 컴팩트 한 API로 이어집니다. 자바에서는 Collections 클래스가 매우 작아서 32 개의 클래스를 숨기는 Collections 클래스에 의해 구현됩니다.




공전

'static'키워드로 선언 된 멤버.

팩토리 메소드

새 객체를 만들고 반환하는 메서드.

자바

프로그래밍 언어는 '정적'의 의미와 관련이 있지만 '공장'의 정의와 관련이 없습니다.




가독성은 정적 팩토리 메소드를 사용하여 향상시킬 수 있습니다.

비교

public class Foo{
  public Foo(boolean withBar){
    //...
  }
}

//...

// What exactly does this mean?
Foo foo = new Foo(true);
// You have to lookup the documentation to be sure.
// Even if you remember that the boolean has something to do with a Bar
// you might not remember whether it specified withBar or withoutBar.

public class Foo{
  public static Foo createWithBar(){
    //...
  }

  public static Foo createWithoutBar(){
    //...
  }
}

// ...

// This is much easier to read!
Foo foo = Foo.createWithBar();



Related