IT story

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

hot-time 2020. 4. 7. 08:34
반응형

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


"정적 팩토리"방법은 무엇입니까?


데이터베이스 연결은 리소스를 많이 사용하기 때문에 데이터베이스 연결에 직접 액세스 할 수 없습니다. 따라서 우리 getDbConnection가 한계 미만인 경우 연결을 생성 하는 정적 팩토리 메소드 를 사용합니다. 그렇지 않으면 "예비"연결을 제공하려고하지만 예외가 없으면 실패합니다.

public class DbConnection{
   private static final int MAX_CONNS = 100;
   private static int totalConnections = 0;

   private static Set<DbConnection> availableConnections = new HashSet<DbConnection>();

   private DbConnection(){
     // ...
     totalConnections++;
   }

   public static DbConnection getDbConnection(){

     if(totalConnections < MAX_CONNS){
       return new DbConnection();

     }else if(availableConnections.size() > 0){
         DbConnection dbc = availableConnections.iterator().next();
         availableConnections.remove(dbc);
         return dbc;

     }else {
         throw new NoDbConnections();
     }
   }

   public static void returnDbConnection(DbConnection dbc){
     availableConnections.add(dbc);
     //...
   }
}

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

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

Matthew와 James가 지적했듯이 연결과 같은 제한된 리소스에 대한 액세스를 제어하는 ​​또 다른 이점이 있습니다. 이 방법 은 재사용 가능한 객체 풀 을 구현하는 방법 입니다. 객체를 생성 , 사용 및 분해하는 대신 구성 및 파괴가 고가의 프로세스 인 경우 한 번 구축하여 재활용하는 것이 더 합리적입니다. 팩토리 메소드는 기존의 사용되지 않는 인스턴스화 된 오브젝트가있는 경우이를 리턴하거나 오브젝트 수가 임계 값보다 낮은 null경우이를 생성 하거나 예외를 발생 시키거나 상위 임계 값을 초과하면 리턴 할 수 있습니다.

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

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

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

Rasmus가 지적한 것처럼 가독성을 향상시키는 데에도 사용할 수 있습니다.


노트! " 정적 팩토리 메소드팩토리 메소드 패턴 과 동일 하지 않습니다 "(c) Effective Java, Joshua Bloch.

팩토리 메소드 : "객체를 생성하기위한 인터페이스를 정의하지만 인터페이스를 구현하는 클래스가 인스턴스화 할 클래스를 결정하게합니다. 팩토리 메소드는 클래스가 서브 클래스에 대한 인스턴스화를 연기하게합니다"(c) GoF.

"정적 팩토리 메소드는 단순히 클래스의 인스턴스를 리턴하는 정적 메소드입니다." (c) 효과적인 Java, Joshua Bloch. 일반적으로이 메소드는 특정 클래스 내에 있습니다.

차이점:

정적 팩토리 메소드의 핵심 아이디어는 객체 생성을 제어하고 생성자에서 정적 메소드로 위임하는 것입니다. 생성 될 객체의 결정은 메소드 외부에서 만들어진 추상 팩토리 (일반적인 경우는 아니지만)에서와 같습니다. Factory Method의 핵심 (!) 아이디어는 Factory Method 내에서 생성 할 클래스의 인스턴스에 대한 결정을 위임하는 것입니다. 예를 들어 고전적인 Singleton 구현은 정적 팩토리 메소드의 특별한 경우입니다. 일반적으로 사용되는 정적 팩토리 메소드의 예 :

  • valueOf
  • getInstance
  • newInstance

정적 팩토리 메소드로 가독성을 향상시킬 수 있습니다.

비교

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();

  • 코드를 명확히 할 수있는 생성자와 달리 이름이 있습니다.
  • 호출 할 때마다 새 객체를 만들 필요가 없습니다. 필요한 경우 객체를 캐시하고 재사용 할 수 있습니다.
  • 반환 유형의 하위 유형을 반환 할 수 있습니다. 특히 구현 클래스가 호출자에게 알려지지 않은 개체를 반환 할 수 있습니다. 이것은 인터페이스를 정적 ​​팩토리 메소드의 리턴 유형으로 사용하는 많은 프레임 워크에서 매우 유용하고 널리 사용되는 기능입니다.

에서 http://www.javapractices.com/topic/TopicAction.do?Id=21


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

팩토리 패턴을 사용하면 객체를 만드는 방식과 객체를 만드는 방식을 분리 할 수 ​​있습니다. 생성자를 사용하여 모든 객체를 만들면 본질적으로 객체를 사용하는 코드를 해당 구현에 연결해야합니다. 객체를 사용하는 코드는 해당 객체에 "종속"됩니다. 이것은 표면 상 큰 문제처럼 보이지 않을 수도 있지만 객체가 변경 될 때 (생성자의 서명을 변경하거나 객체를 서브 클래 싱하는 것을 고려할 때) 돌아가서 모든 곳에서 사물을 다시 연결해야합니다.

오늘날 공장은 자체 유지하기가 약간 어려운 보일러 플레이트 코드가 많이 필요하기 때문에 Dependency Injection을 선호하여 크게 솔질되었습니다. Dependency Injection은 기본적으로 팩토리와 동일하지만 구성 또는 주석을 통해 객체를 선언적으로 연결하는 방법을 지정할 수 있습니다.


클래스의 생성자가 private 인 경우 클래스 외부에서 클래스의 객체를 만들 수 없습니다.

class Test{
 int x, y;
 private Test(){
  .......
  .......
  }
}

우리는 클래스 외부에서 객체를 만들 수 없습니다. 따라서 클래스 외부에서 x, y에 액세스 할 수 없습니다. 그렇다면이 수업의 용도는 무엇입니까?
답변 : FACTORY 메소드 는 다음과 같습니다 .
위 클래스에서 아래 메소드를 추가하십시오.

public static Test getObject(){
  return new Test();
}

이제 외부에서이 클래스에 대한 객체를 만들 수 있습니다. 길처럼 ...

Test t = Test.getObject();

따라서 개인 생성자를 실행하여 클래스의 객체를 반환하는 정적 메서드를 FACTORY 메서드 라고
합니다.


나는 내가 아는 것에 대해이 게시물에 약간의 빛을 추가 할 것이라고 생각했습니다. 우리는이 기술을 광범위하게 사용했습니다 recent android project. 대신 클래스를 인스턴스화하는 데 creating 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();
  }
}

정적 메소드는 조건부 객체 생성을 지원합니다 . 생성자를 호출 할 때마다 객체가 생성되지만 원하지 않을 수도 있습니다. 조건 만 확인한 다음 새 객체를 만들고 싶다고 가정합니다. 조건이 충족되지 않으면 매번 Vinoth의 새 인스턴스를 생성하지 않습니다.

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

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

이 메소드는 부울 프리미티브 값을 부울 오브젝트 참조로 변환합니다. Boolean.valueOf(boolean)방법은 우리를 설명하며 결코 객체를 생성하지 않습니다. static factory methods반복에서 동일한 객체를 반환하는 기능을 invocations통해 클래스는 언제든지 존재하는 인스턴스를 엄격하게 제어 할 수 있습니다.

Static factory methods와 달리 모든 반환 유형 하나를 constructors반환 할 수 있습니다 . 이러한 유연성의 한 가지 적용은 API가 클래스를 공개하지 않고도 객체를 반환 할 수 있다는 것입니다. 이러한 방식으로 구현 클래스를 숨기면 매우 컴팩트 한 API가됩니다.objectsubtype

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;
    }
}

팩토리 메소드는 객체의 인스턴스화를 추상화하는 메소드입니다. 일반적으로 팩토리는 일부 인터페이스를 구현하는 클래스의 새 인스턴스가 필요하지만 구현 클래스를 모르는 경우 유용합니다.

이것은 관련 클래스의 계층 구조로 작업 할 때 유용합니다. 이에 대한 좋은 예는 GUI 툴킷입니다. 각 위젯의 구체적인 구현을 위해 생성자에 대한 호출을 간단히 하드 코딩 할 수 있지만 한 툴킷을 다른 툴킷으로 바꾸고 싶다면 변경해야 할 곳이 많이 있습니다. 팩토리를 사용하면 변경해야 할 코드의 양이 줄어 듭니다.


정적 팩토리의 장점 중 하나는 API가 클래스를 공개하지 않고 객체를 반환 할 수 있다는 것입니다. 이는 매우 컴팩트 한 API로 이어집니다. 자바에서 이것은 32 개의 클래스를 숨겨서 Collection API를 매우 컴팩트하게 만드는 Collections 클래스에 의해 달성됩니다.


정적 팩토리 메소드는 하나의 단일 인스턴스 만 사용할 구체적 클래스를 리턴하도록하려면 좋습니다.

예를 들어, 데이터베이스 연결 클래스에서 하나의 클래스 만 데이터베이스 연결을 작성하도록 할 수 있으므로 Mysql에서 Oracle로 전환하기로 결정한 경우 하나의 클래스에서 논리를 변경할 수 있으며 나머지 응용 프로그램은 새로운 연결을 사용하십시오.

데이터베이스 풀링을 구현하려는 경우 나머지 응용 프로그램에 영향을주지 않고 수행됩니다.

출고시 변경 될 수있는 나머지 응용 프로그램을 보호합니다. 이것이 목적입니다.

정적 인 이유는 제한된 리소스 (소켓 연결 또는 파일 핸들 수)를 추적하려는 경우이 클래스는 얼마나 많은 시간이 경과 및 반환되었는지 추적 할 수 있기 때문에 제한된 자원.


공전

키워드 'static'으로 선언 된 멤버입니다.

공장 방법

새로운 객체를 생성하고 반환하는 메소드.

자바로

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


Java 구현에는 java.util.Arraysjava.util.Collections 유틸리티 클래스가 포함되어 있습니다. 둘 다 정적 팩토리 메소드 , 예제 및 사용 방법을 포함합니다.

또한 java.lang.String 클래스에는 정적 팩토리 메소드가 있습니다 .

  • String.format(...), String.valueOf(..), String.copyValueOf(...)

개인 생성자가있는 정적 팩토리 메소드의 장점 중 하나 (인스턴스가 외부에서 작성되지 않도록하기 위해 외부 클래스에 대해 오브젝트 작성이 제한되어야 함)는 인스턴스 제어 클래스를 작성할 수 있다는 것 입니다. 그리고 인스턴스 제어 클래스 는 프로그램이 실행되는 동안 동일한 두 개의 서로 다른 인스턴스가 존재하지 않음을 보장합니다 ( a.equals (b) aa == b 인 경우에만 ) 즉 equals 메소드 대신 == 연산자 로 객체의 동등성을 확인할 수 있습니다 효과적인 java에 따르면.

정적 팩토리 메소드가 반복 호출에서 동일한 오브젝트를 리턴하는 기능을 통해 클래스는 언제든지 존재하는 인스턴스를 엄격하게 제어 할 수 있습니다. 이를 수행하는 클래스는 인스턴스 제어라고합니다. 인스턴스 제어 클래스를 작성해야하는 몇 가지 이유가 있습니다. 인스턴스 제어를 통해 클래스는 단일 (항목 3) 또는 인스턴스화 할 수없는 (항목 4) 클래스를 보장 할 수 있습니다. 또한 불변 클래스 (항목 15)는 두 개의 동일한 인스턴스가 존재하지 않도록 보장합니다. a. == b 인 경우에만 a.equals (b). 클래스가이 보증을하는 경우, 클라이언트는 equals (Object) 메소드 대신 == 연산자를 사용하여 성능이 향상 될 수 있습니다. 열거 형 (항목 30)은이 보증을 제공합니다.

효과적인 Java에서 Joshua Bloch (항목 1, 6 페이지)

참고 URL : https://stackoverflow.com/questions/929021/what-are-static-factory-methods

반응형