본문 바로가기
카테고리 없음

인터페이스를 통한 느슨한 결합

by 찐세 2021. 7. 15.
class A{
	public void methodA(B b){
		b.methodB();
	}
}

class B{
	public void methodB(){
		System.out.println("methodB()");
	}
}

class InterfaceTest{
	public static void main(String[] args){
		A a = new A();
		a.method(new B());
	}
}

 

위의 내용에서는 클래스 A가 클래스 B의 인스턴스를 직접 사용하고 메서드를 호출한다.

이런 경우에 클래스 A와 클래스 B은 서로 직접적인 관계에 있게 된다.

 

 

 

이 방식의 단점에 대해서 알아보면 이번 주제를 잘 이해할 수 있을 것이다.

 

 

1.  클래스 A를 작성하려면 클래스 B가 먼저 작성이 되어 있어야 한다.

2.  만약 중간에 클래스 B의 methodB( ) 의 선언부가 변경이 된다면 클래스 A도 수정이 되어야 한다.

 

 

 

이러한 문제점을 개선하기 위해 두 클래스 사이에 인터페이스를 두고 이를 매개로 하여 통신(?)을 할 수 있다.

 

class A{
	public void methodA(I i){
		i.method();
	}
}

Interface I{
	public abstract void method();
}

class B implements I{
	public void method(){
		System.out.println("methodB()");
	}
}

class InterfaceTest{
	public static void main(String[] args){
		A a = new A();
		a.method(new B());
	}
}

 

클래스 B가 인터페이스 I를 구현하고 클래스 A의 메소드에서는 B가 아닌 I에 접근하는 방식으로, 클래스 A는 직접적으로 클래스 B에 접근하지 않는다.

main 메서드에서 인터페이스 I의 타입으로 B의 인스턴스를 받게 된다. 

즉, 간접적으로 B에 접근한다.

 

 

이 방식으로 얻을 수 있는 장점은 클래스 A는 인터페이스 I와 통신하는 것이지, 클래스 B와는 직접적으로 연관이 없다.

 

그렇기 때문에 클래스 A는 클래스 B의 수정으로 인한 직접적인 영향을 받지 않고, 오로지 인터페이스 I의 변경에 대한 영향만 받게 된다.

 

메서드를 사용하는 쪽(클래스 A)에서는 메서드의 구현 내용에 대해서는 몰라도 된다. 단지 메서드의 선언부만 알고 있으면 사용할 수 있기 때문이다.

 

그래서 선언부를 인터페이스 I를 통해서 강제하고, 이 인터페이스를 구현한 모든 클래스의 메서드를 클래스 A에서 사용할 수 있게 된다.

 

 

이는 프록시 패턴 등 자바에서의 다양한 디자인 패턴의 기본 개념이 된다.