본문 바로가기

Java

강한 결합과 느슨한 결합이 무엇인가??

오늘은 강한 결합과 느슨한 결합의 차이점이 무엇인지 알아보겠다.

 

강한 결합과 느슨한 결합은 객체지향 설계에서 클래스나 모듈이 서로 얼마나 의존하고 있는지를 나타내는 개념이다.

쉽게 말하면

  • 강한 결합 : 한쪽이 바뀌면 다른 쪽도 영향을 크게 받는 구조
  • 느슨한 결합 : 서로 의존은 하지만, 변경의 영향이 작게 펴지는 구조

 

강한 결합

강한 결합은 클래스가 다른 구체적인 클래스에 직접 의존하는 구조이다.

class KakaoPay {
	public void pay(int amount) {
    	System.out.println("카카오페이로 " + amount + "원 결제");
    }
}

class OrderService {
	private KakaoPay kakoPay = new KakoPay();
    
    
    public void order(int amount) {
    	kakoPay.pay(amount);
    }
}

 

OrderService는 내부에서 직접 KakoPay 객체를 생성하고 있다

 

이 구조에서는 OrderService가 KakaoPay에 강하게 묵여 있다

만약 결제 수단을 NaverPay나 TossPay로 바꾸고 싶다면 OrderService 코드를 직접 수정해야 한다.

 

class OrderService {
	private NaverPay naverPay = new NaverPay();
    
    public void order(int amount) {
    	naverPay.pay(amount);
	}
}

 

즉, 결제 수단이 바뀔 때마다 주문 서비스 코드도 함께 바뀌게 된다

이런 구조가 강한 결합이다

 

강한 결합의 문제점은 다음과 같다

  • 변경에 약하다
  • 테스트가 어렵다
  • 코드 재사용성이 떨어진다
  • 기능 확장 시 기존 코드를 자주 수정해야 한다

느스한 결합

느스한 결합은 구체적인 클래스가 아니라 인터페이스나 추상화에 의존하는 구조이다.

먼저 결제 기능을 인터페이스로 분리한다

 

interface Payment {
	void pay(int amount)
}

 

그리고 각 결제 수단은 이 인터페이스를 구현한다

class KakaoPay implements Payment {
	@Override
    public void pay(int amount) {
    	System.out.println("카카오페이로 " + amount + "원 결제");
    }
}

class NaverPay implements Payment {
	@Override
    public void pay(int amount) {
    	System.out.println("네이버페이로 " + amount + "원 결제");
    }
}

 

이제 OrderService는 특정 결제 수단이 아니라 Payment 인터페이스에 의존한다

 

class OrderService {
	private final Payment payment;
    
    public OrderService(Payment payment) {
    	this.payment = payment;
    }
    
    public void order(int amount) {
    	payment.pay(amount);
    }
}

 

사용할 때는 외부에서 원하는 결제 수단을 넣어주면 된다.

Payment payment = new KakaoPay();
OrderService orderService = new OrderService(payment);

orderService.order(10000);

 

나중에 NaverPay로 바꾸고 싶다면 OrderService는 수정하지 않아도 된다

Payment payment = new NaverPay();
OrderService orderSerivce = new OrderService(payment);

orderService.order(10000);

 

OrderService는 여전히 Payment만 알고 있고, 실제 결제 수단이 무엇인지는 외부에서 결정한다

이런 구조가 느슨한 결합이다.

 

정리

 

강한 결합은 클래스가 특정 구현체에 직접 의존하는 구조이다.

private KakaoPay kakaoPay = new KakaoPay();

 

느슨한 결합은 인터페이스나 추상화에 의존하고, 실제 구현체는 외부에서 주입받는 구조이다

private final Payment payment;

public OrderService(Payment payment) {
	this.payment = payment;
}

 

실무에서는 보통 인터페이스, 생성자 주입, DI 컨테이너, 예를 들면 Spring을 사용해서 느슨한 결합을 만든다

간단히 말하면

  • 강한 결합 : "내가 직접 만들고, 특정 클래스만 쓴다"
  • 느슨한 결합 : "나는 역할만 알고, 실제 구현은 외부에서 받는다"