Item 1 (Static Factory Method), Effective Java

이창호·2022년 3월 30일
0

이펙티브자바

목록 보기
1/12

여기에 아이템1에 나온 용어들을 정리했습니다.

생성자 대신 정적 팩토리 메서드를 고려하라

개요

클래스를 인스턴스화 하기 위해서 필요한것이 바로 생성자다.

  • 인스턴스란 객체(클래스)를 실제로 생성(실체화)한 것
	Human h = new Human(); // new 생성자를 통한 인스턴스를 생성

public 생성자를 통해서 인스턴스를 생성할 수 있다.
생성자에 넘기는 매개변수에 따라 같은 클래스 내에도 여러 생성자를 가질 수 있다.

	Class Human {
    	private String name;
        private int age;
        private String gene;
        
        public Human(String name, int age, String gene) { ... }
        
        public Human(String name) { ... }
        
        public Human(int age) { ... }
        
        public Human(String gene){ ... }
    }

생성자 마다 어떤 이유로 매개변수를 다르게 주는지 알려면 코드를 작성한 사람에게 묻거나 직접 내부를 볼 수 밖에 없다.

이때 사용할 수 있는게 정적 팩토리 메서드다.

장점

	public class Human {
    	private String name;
        private int age;
        private String gene;
        
        public static Human basicRegistration(String name, int age, String gene) { ... }
        
        public static Human registerBygene(String gene){ ... }
        
        public static Human registerByAge(int age){ ... }
    }
  • 클래스는 정적 팩토리 메서드를 사용하여 매개변수에 따라 다른 방식으로 인스턴스를 생성합니다. 메서드 이름만으로 반환될 인스턴스의 특성을 알 수 있습니다.
    public class LottoNum {
    	private static final int MIN_NUM = 1;
        private static final int MAX_NUM = 45;
        private static List<LottoNum> lottoNums = new ArrayList();
        
        public static void init(){
        	for (int i = 0; i < 6; i++) {
            	IntStream.range(MIN_NUM, MAX_NUM)
                .forEach(i -> new LottoNum(i));
        	}
        }
        
        private int pickNum;
        
        private LottoNum(int pickNum) {
        	this.pickNum = pickNum;
        }
        
        public List<LottoNum> getLottoNums() {
        	return lottoNums;
        }
    }
  • 또 한, private 생성자로 외부에서 객체 생성을 막아두고 정적 팩토리 메서드로 생성된 객체들만 사용하게 합니다. 이렇게 하면 불필요한 객체 생성을 막을 수 있습니다.
	public abstract class Mammal {
    	...
        public static Mammal getSpecies(String characteristic){
        	if(characteristic.equals("cute"){
            	return new Dog();
            }
            if(characteristic.equals("bipedalism"){
            	return new Human();
            }
        }
        ...
    }
  • 정적 팩토리 메서드에서 입력한 매개변수에 따라 다른 클래스의 객체를 반환할 수 있습니다. 그리고 해당 클래스를 상속받은 클래스만 객체로 반환할 수 있게 하는 것도 가능합니다.

단점

이런 장점들에도 불구 하고 단점은 존재합니다.

	public abstract class Test {
    	private Test() {

    	}

    	static public Test test() {
        	return new Test();
    	}
	}
  • 위 코드와 같이 상속을 하려면 public이나 protected 생성자가 필요한데, 정적 팩토리 메서드 방식을 사용하면 하위 클래스를 만들 수 없게 됩니다.

  • 그리고 정적 팩토리 메소드는 따로 문서화를 통해 명시해야 합니다. 그렇지 않으면 개발자가 팩토리 메소드를 찾기 힘들겁니다. ㅠ

참고

https://velog.io/@ljinsk3/정적-팩토리-메서드는-왜-사용할까

profile
이타적인 기회주의자

0개의 댓글