이펙티브 자바5

참치돌고래·2021년 8월 31일
0

이펙티브 자바

목록 보기
5/21

5. 의존성 주입을 사용하자.

SpellChecker 와 Dictionary로 예를 들어보자.

유연하지 않은 구현

static 유틸 클래스

public class SpellChecker{
    private static final Lexicon dictionary = new KoreanDictionary();
    
    private SpellChecker(){
    }
    
    public static boolean isValid(String word){
    	throw new UnsupportedOperationException();
    }
    public static List<String> suggestions(String typo){
    	throw new UnsupportedOperationException();
    }
    
    public static void main(String[] args){
    	SpellChecker.isValid("hello");
    }
}

interface Lexicon{}

class KoreanDictionary implements Lexicon{}

싱글톤으로 구현하기

public class SpellChecker{
    private final Lexicon dictionary = new KoreanDictionary();
    
    private SpellChecker(){
    }
    
    public static final SpellChecker INSTANCE = new SpellChecker(){
    };
    
    public boolean isValid(String word){
    	throw new UnsupportedOperationException();
    }
    public List<String> suggestions(String typo){
    	throw new UnsupportedOperationException();
    }
}

Dictionary가 하나로 고정되어 유연하지 않은 코드가 생성된다.

어떤 클래스가 사용하는 리소스에 따라 행동을 달리 해야 하는 경우에는 스태틱 유틸리티 클래스와 싱글톤을 사용하는 것은 부적절하다.

해답

public class SpellChecker{
    private final Lexicon dictionary;
    
    public SpellChecker(Lexicon dictionary){
    	this.dictionary = Objects.requireNonNull(dictionary);
    }
    
    public boolean isValid(String word){
    	throw new UnsupportedOperationException();
    }
    public List<String> suggestions(String typo){
    	throw new UnsupportedOperationException();
    }
}

class Lexicon{}

의존성 주입은 생성자, 스태틱 팩토리, 빌더에도 적용할 수 있다.

Supplier 인터페이스로 리소스의 팩토리를 생성자에 전달하는 방법도 있다.

public class SpellChecker{
    private final Lexicon dictionary;
    
    public SpellChecker(Supplier<Lexicon> dictionary){
    	this.dictionary = Objects.requireNonNull(dictionary);
    }
    
    public boolean isValid(String word){
    	throw new UnsupportedOperationException();
    }
    public List<String> suggestions(String typo){
    	throw new UnsupportedOperationException();
    }
    public static void main(String[] args){
    	Lexicon lexicon = new KoreanDictionary();
        SpellChecker spellChecker = new SpellChecker(()->new lexicon);
    }
}
interface Lexicon{}

class KoreanDictionary implements Lexicon{}
profile
안녕하세요

0개의 댓글