오늘은 강한 결합과 느슨한 결합의 차이점이 무엇인지 알아보겠다.
강한 결합과 느슨한 결합은 객체지향 설계에서 클래스나 모듈이 서로 얼마나 의존하고 있는지를 나타내는 개념이다.
쉽게 말하면
- 강한 결합 : 한쪽이 바뀌면 다른 쪽도 영향을 크게 받는 구조
- 느슨한 결합 : 서로 의존은 하지만, 변경의 영향이 작게 펴지는 구조
강한 결합
강한 결합은 클래스가 다른 구체적인 클래스에 직접 의존하는 구조이다.
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을 사용해서 느슨한 결합을 만든다
간단히 말하면
- 강한 결합 : "내가 직접 만들고, 특정 클래스만 쓴다"
- 느슨한 결합 : "나는 역할만 알고, 실제 구현은 외부에서 받는다"
'Java' 카테고리의 다른 글
| JUnit 5와 Mockito로 테스트 코드 작성하기 (0) | 2026.07.23 |
|---|---|
| Java String, StringBuilder, StringBuffer 각각의 차이점 정리 (0) | 2026.06.25 |