Skip to content

Latest commit

 

History

History
162 lines (114 loc) · 5.29 KB

01.정적 팩토리 메서드로 생성 목적에 맞는 객체를 생성하라.md

File metadata and controls

162 lines (114 loc) · 5.29 KB

정적 팩토리 메서드로 생성 목적에 맞는 객체를 생성하라

정적 팩토리 메서드(Static Factory Method)란 public 생성자와 별도로 객체를 생성하는 메서드이다

// public 생성자를 이용한 객체 생성
Car car = new Car("dog");

// 정적 팩토리 메서드를 이용한 객체 생성
// Integer Wrapper 객체를 반환 
Integer i = Integer.valueOf(10);

// 생성할 클래스가 아닌 다른 클래스에 정의된 정적 팩토리 메소드
BufferReader br = Files.newBufferedReader(path)
  1. 정적 팩토리 메서드의 많은 장점
  2. 정적 팩토리 메서드의 사소한 단점
  3. 정적 팩토리 메서드 네이밍 컨벤션

정적 팩토리 메서드의 많은 장점

  • 반환 될 객체의 특성을 묘사하는 이름을 지을 수 있다
// 반환 된 Car의 위치가 0임을 짐작할 수 있다 
Car firstCar = Car.createZeroPosition("dog");

클래스에 여러 생성자가 필요할 때, 동일 시그니처로 생성할 수 없다
따라서, 정적 팩토리 메서드를 이용하여 각각의 차이를 드러내는 이름을 붙여준다
💡 동일 시그니처란?: 메서드 명과 파라미터가 모두 같음


  • 호출할 때 마다 새로운 인스턴스를 생성하지 않아도 된다
Boolean b = Boolean.valueOf(true);

// TRUE, FALSE를 반환하고 있다 
@HotSpotIntrinsicCandidate
public static Boolean valueOf(boolean b) {
    return (b ? TRUE : FALSE);
}

불변 클래스의 인스턴스를 미리 만들어 놓거나, 인스턴스를 캐싱해 재활용하는 식으로 불필요한 객체 생성을 피할 수 있다
이렇게 사용한다면 객체 생성 비용이 클 때 성능을 끌어올릴 수 있다


  • 반환 타입의 하위 타입 객체를 반환할 수 있다
public interface Crew {
	static Type getBackendCrew() {
		return new BackendCrew();
	}

	static Type getFrontendCrew() {
		return new FrontendCrew();
	}
}

구현 클래스를 노출시키지 않는 동시에, 사용자에게 반환 클래스가 어떤 클래스인지 굳이 찾아보지 않도록 할 수 있다


  • 매개변수에 따라 다른 클래스 인스턴스를 반환할 수 있다
public class WoowaMember {

    public static WoowaMember getMember(boolean isCrew) {
        return flag ? new Crew() : new Coach();
    }

    static class Crew extends WoowaMember {
    }

    static class Coach extends WoowaMember {
    }

    public static void main(String[] args) {
        WoowaMember member1 = WoowaMember.getWoowaMember(true);     // Crew
        WoowaMember member2 = WoowaMember.getWoowaMember(false);    // Coach
    }
}

  • 작성 시점에서 반환 객체의 클래스가 존재하지 않아도 된다

서비스 제공자 프레임워크의 근반이 되며, 대표적으로 JDBC가 존재한다
작성자가 이해를 제대로 하지 못 한 관계로 jdbc의 예를 들어 설명을 잘 해둔 링크로 대체합니다
2021BookChallenge/effective-java#1 (comment)


정적 팩토리 메서드의 사소한 단점

  • 상속을 하려면 public이나 protected 생성자가 필요하다
    하지만 상속보다 컴포지션을 사용하도록 유도하고, 불변 타입으로 만들기 위한 목적이라면, 단점이 아닌 장점으로 받아들일 수 있다

  • 프로그래머가 찾기 어렵다
    다른 정적 메서드와 구분이 어려우므로 문서화를 잘 해두어야 한다
    이 단점은 네이밍 컨벤션을 통해 완화할 수 있다


정적 팩토리 메서드 네이밍 컨벤션

  • from : 매개변수를 하나 받아서 해당 타입의 인스턴스를 반환
Date date = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
  • of : 여러 매개변수를 받아 적합한 타입의 인스턴스를 반환
Set<Prize> lottoPrizes = EnumSet.of(FIRST, SECOND, THIRD, FOURTH, FIFTH);
  • valueOf : from과 of의 더 자세한 버전
int x = Integer.valueOf("20");
  • Instance / getInstance : 매개변수로 명시한 인스턴스를 반환하나, 같은 인스턴스를 보장하지 않음
Calendar calendar = Calendar.getInstance();
  • create / newInstance : 매번 새로운 인스턴스 생성을 보장

  • getType : getInstance와 같으나, 생성할 클래스가 아닌 다른 클래스에 정의

int a = Character.getType('A');
  • newType : newInstance와 같으나, 생성할 클래스가 아닌 다른 클래스에 정의
 BufferReader br = Files.newBufferedReader(path)
  • type : getType과 newType의 간결한 버전
List<Complaint> litany = Collections.list(legacyLitany);

참고한 글들

https://devlog-wjdrbs96.tistory.com/256
https://velog.io/@ljinsk3/%EC%A0%95%EC%A0%81-%ED%8C%A9%ED%86%A0%EB%A6%AC-%EB%A9%94%EC%84%9C%EB%93%9C%EB%8A%94-%EC%99%9C-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C