TIL

IoC와 DI

everyday-spring 2024. 8. 14. 21:40

IoC (Inversion of Control) : 제어의 역전, 설계원칙

DI (Dependency Injection) : 의존성 주입, 디자인패턴

 

비슷한 기능을 하는 객체로 변경을 하는 경우!

강하게 결합되어 있다면 의존하는 객체의 코드도 수정이 되어야 한다

그러나 비슷한 기능을 하는 객체들을 Interface로 묶어준다면?

-> Interface의 객체를 사용하여 새로 추가된 객체라도 코드 수정이 간단해진다

 

DI를 통한 IoC

의존성 주입을 통한 제어의 역전

 

강한결합

/* 강한 결합 */
public class Consumer {
	
    void eat() {
    	Chicken chicken = new Chicken();
        chicken.eat();
    }
    
    public static void main(String[] args) {
    	Consumer consumer = new Consumer();
        consumer.eat();
    }
}

class Chicken {
	public void eat() {
    	System.out.print("치킨을 먹는다");
    }
}

// 만약 피자를 먹고싶다면?
// Pizza class를 생성한다
// Consumer의 eat method를 수정한다
// -> 불필요한 Consumer 클래스의 수정

 

 

약한결합

/* 약한 결합 */
public class Consumer {

	// 인터페이스를 parameter로 받는다
	void eat(Food food) {
    	food.eat();
    }
    
    public static void main(String[] args) {
    
    	Consumer.consumer = new Consumer();
        consumer.eat(new Chicken());
        consumer.eat(new Pizza());
        
        // 먹고싶은 음식이 변경되어도 Consumer의 코드는 수정되지 않는다
    }
}

interface Food {
	void eat();
}

class Chicken implements Food {
	@Override
    public void eat() {
    	System.out.print("chicken~~");
    }
}

class Pizza implements Food {
	@Override
    public void eat() {
    	System.out.print("pizza~~");
    }
}

 

 

필드에 직접 주입

public class Consumer {

	Food food;
    
    void eat() {
    	this.food.eat();
    }
    
    public static void main(String[] args) {
    	Consumer consumer = new Consumer();
        consumer.food = new Chicken();
        consumer.eat();
        
        consumer.food = new Pizza();
        consumer.eat();
    }
}

 

 

 

메서드를 통한 주입 (Setter)

public class Consumer {
	
    Food food;
    
    void eat() {
    	this.food.eat();
    }
    
    public void setFood(Food food) {
    	this.food = food;
    }
    
    public static void main(String[] args) {
    	Consumer consumer = new Consumer();
        consumer.setFood(new Chicken());
        consumer.eat();
        
        consumer.setFood(new Pizza());
        comsumer.eat();
    }
}

 

 

 

생성자를 통한 주입

public class Consumer {

	Food food;
    
    public Consumer(Food food) {
    	this.food = food;
    }
    
    void eat() {
    	this.food.eat();
    }
    
    public static void main(String[] args) {
    	Consumer consumer = new Consumer(new Chicken());
        consumer.eat();
        
        consumer = new Consumer(new Pizza());
        consumer.eat();
    }
}