//////
Search
🗒️

황민우

날짜
2022/10/05
작성자
황민우
카테고리
회고

인터페이스와 DI(Dependency Injection)

DI : Dependency Injection (의존성 주입) 객체를 직접 생성하지 않고 외부 컨테이너가 생성한 객체를 주입받아 사용하는 방식. 외부 컨테이너 = 스프링 컨테이너 or IoC 컨테이너 DI는 스프링에서 나오는 개념으로 여기서는 객체를 내부에서 직접 생성하지 않고 “주입”받아 사용하는 방식으로 이해하도록 한다.

인터페이스

인터페이스는 무엇인가?

OOP(Object-Oriented Programming) 객체 지향 프로그래밍의 특징 중 하나인 추상화를 먼저 알아보자.
추상화란, 공통적인 속성과 기능을 따로 분리하여 추상 클래스나 인터페이스로 생성하는 것을 말한다.
인터페이스는 구현을 강제하기 때문에 같은 기능이지만 로직이 다른 공통분모를 추상화하기 좋다.
Java8 부터 인터페이스에 default 메서드를 미리 구현할 수도 있다.

인터페이스는 왜 사용할까?

인터페이스는 어떤 메서드를 구현할지 미리 정의된 파일이다.
반대로 말하면 구현해두지 않아도 어떤 메서드가 있는지, 그 메서드는 어떤 타입의 반환값을 주는지 알고 있다는 말이다.
그렇기 때문에 구현체가 없어도 인터페이스를 가져와 사용하는 로직을 작성할 수 있다.
그리고 인터페이스를 구현한 구현체들이 다양하더라도 같은 인터페이스를 구현했기 때문에 각 구현체들을 주입하여도 정상적으로 동작한다.
따라서, 하나의 인터페이스를 기반으로 여러 사람들이 만든, 혹은 같은 기능을 가지지만 로직이 다른 여러 구현체들을 생성하여 “주입”해주기만 하면 주입받는 객체는 수정하지 않고 동작시킬 수 있다.
다시 말해, 주입받는 메인 객체의 코드 수정 없이 구현체를 주입해 주기만 하면 정상 작동한다는 것이다.

주입?

오늘 수업에서 진행한 코드와 함께 위 설명과 주입이란 무엇인지 알아보자.
NumberGenerator.java
public interface NumberGenerator { int generate(int num); }
Java
복사
아래 RandomNumberGeneratorSpecificNumberGenerator의 숫자 생성의 공통 기능을 추상화
RandomNumberGenerator.java
public class RandomNumberGenerator implements NumberGenerator{ @Override public int generate(int num) { return (int)(Math.random()*num); } }
Java
복사
NumberGeneratorgenerate(int num) 메서드 구현
NumberGenerator의 구현체
0 ~ num - 1 까지의 랜덤한 정수를 반환
SpecificNumberGenerator.java
public class SpecificNumberGenerator implements NumberGenerator{ @Override public int generate(int num) { return 1000; } }
Java
복사
NumberGeneratorgenerate(int num) 메서드 구현
NumberGenerator의 구현체
어떤 값이 들어와도 고정된 1000을 반환
Calculator.java
public class Calculator { private NumberGenerator numberGenerator; public Calculator(NumberGenerator numberGenerator) { this.numberGenerator = numberGenerator; } public void plus(int num) { System.out.println(10 + numberGenerator.generate(num)); } }
Java
복사
Calculator의 생성자를 보면 numberGenerator를 받아와 필드에 넣어줌. (주입 받는 것)
주입 받아온 numberGeneratorgenerator메서드를 활용해 로직 동작.
NumberGenerator인터페이스를 작성해두었기 때문에 실제 구현체를 생성하지 않아도 에러 발생이 없음. (단! Calculator객체 생성시 반드시 NumberGenerator를 주입해야함)
Main.java
public class Main { public static void main(String[] args) { NumberGenerator randomNumberGenerator = new RandomNumberGenerator(); Calculator randomCalculator = new Calculator(randomNumberGenerator); randomCalculator.plus(10); // EXPECTED : 10 + 0 ~ 9 = 10 ~ 19 NumberGenerator specificNumberGenerator = new SpecificNumberGenerator(); Calculator specificCalculator = new Calculator(specificNumberGenerator); specificCalculator.plus(10); // EXPECTED : 1010 } }
Java
복사
본격적으로 Calculator객체를 NumberGenerator를 주입하며 생성하는 메인 코드
line 1 : NumberGeneratorRandomNumberGenerator객체를 생성하여 초기화
line 2 : RandomNumberGenerator객체를 주입한 Calculator객체 생성하여 초기화
line 3 : Calculatorplus메서드 실행
line 5 ~ 7 : NumberGeneratorSpecificNumberGenerator객체로 생성한 것 이외에는 동일.
하나의 인터페이스를 각기 다른 로직으로 구현한 RandomNumberGeneratorSpecificNumberGeneratorCalculator에 주입하여 사용.
이 과정에서 서로 다른 동작을 하는데도 불구하고 Calculator코드는 전혀 수정하지 않음.