Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

쉽지않은 블로그

[Spring] DI & IOC (1) 느슨한 결합력 본문

개발공부/스프링

[Spring] DI & IOC (1) 느슨한 결합력

쉽지않네 2021. 4. 13. 20:10

자바의 객체지향 프로그래밍 관점에서 보게 되면

 

1) 클래스가 다른 클래스를 사용하거나

2) 클래스가 다른 클래스를 상속하거나 

 등

어떤 클래스 객체가 하는 일이 다른 객체에 영향을 받게 되면 "결합력이 있다"고 표현한다

 

일단 다른 클래스를 사용하면 결합력이 있다고 하는데 어떻게 사용하냐에 따라서

강한 결합력느슨한 결합력으로 정의될 수 있다


다음 예시를 보자

예시에서는 가정이 있다

"A 인스턴스 안에서 B객체를 사용해야 되는 상황"

             (spring mvc 관점에서 A를 controller B를 service라고 생각하여도 좋다)

class A {
	private b;
    public A(){
        b = new B();
    }
    
    public doSomeThing(){
    	int val = b.getData().....
        
        
    }
}


class B{
	public B(){
       ....
    }
    
    int getData(){
       ....
    }
}

A클래스 안에서 B클래스를 사용하기 위해

객체 b를 A클래스 안에서 생성을 하고 b의 메서드를 사용하는 모습이다

 

이러한 코드 형태는 결합력이 강하다고 할 수 있다

이유는 다음과 같다

1. 객체 B를 사용하기 위해서 B의 생성을 A가 책임진다.

      A의 비즈니스 로직(doSomeThing 함수)을 수행하는데 b가 필요하기 때문에

      A의 생성자 안에 B의 생성이 들어가 있는 것을 확인할 수 있을 것이다. 

 

2.B클래스 가 아닌 다른 클래스가 B의 역할을 하게 되면 doSomeThing 안의 호출 문도 바꿔주어야 한다.

      B클래스가 아닌 같은 기능의 C클래스가 있다고 해서 B 대신 C로 교체하려고 해도  A클래스의 메서드를 수정해주어 야 한다.


위의 결합력이 강한 예시를 약하게 만들어주기 위한 해결방법으로는

 

1. 객체 B를 사용하기 위해서 B의 생성을 A가 책임진다.

     ==> B를 A의 생성자 밖에서 생성을 한 다음 A의 생성자 인자로 받아준다.

            더 이상 A가 B를 생성하지 않게끔 구조를 변형

 

2.B클래스 파일의 내용이 수정되면 doSomeThing 안의 호출 문도 바꿔주어야 한다.

     ==> 인터페이스를 하나 정의한 후 B는 이 인터페이스의 구현체로 설계를 한다.

            그다음 A안에서 B를 인터페이스 인자로 받은 후 A에 저장한다.

 

대충 다음과 같은 코드가 될 것이다

public class A {

	private B_interface b;
	
	public A(B_interface b) {
		this.b = b;
	}
	public int doSomeThing() {
		int val = b.getDate();
        	..
        	..
        	..
		return val;
	}

}



public interface B_interface {
	int getDate();
}

public class B implements B_interface{
	@Override
	public int getDate() {
		// TODO Auto-generated method stub
		return 10;
	}
}

 

코드를 이렇게 바꾸고 나니

 

1. 밖에서 생성하고 주입을 해주는 형식인걸 A의 생성자로 확인을 할 수 있을 것이고 

 

2.B의 대체품 C를 A의 생성자에 주입을 하고 싶으면 C를 interface 구현체로 정의한 다음 생성 부분에서 주입해주면 해결 가능하다 

 

이런 식으로 구현을 하고 메인 함수의 호출부에서는 

b를 생 성해준 다음 A의 생성자에 넣어주는 (injection)해주는 방식이다

public static void main(String[] args) {
	
	B b = new B();
	A a = new A(b);
    	a.doSomeThing();
}

 

하지만 위 방법은 딱 보아도 파일의 구조가 복잡해지고 유지 보수화 하기 까다로워질 것이다

또한 지금처럼 A, B 클래스 두 클래스가 아닌 A, B, C 세 가지의 클래스가 있고 서로 계층적인 의존관계라면

어떻게 해결해야 할 것인가?.... 

Comments