반응형
ISP(Interface Segregation Principle) - 인터페이스 분리 원칙
- 인터페이스는 사용에 따라 잘 구분해야 한다
- 인터페이스 내에 추상 메서드들을 범용적으로 이것저것 구현하면, 상속받을 클래스는 자신이 사용하지 않는 인터페이스까지도 억지로 구현 해야 하는 상황이 올 수도 있다.
- 인터페이스의 단일 책임 원칙 (SRP = 클래스/모듈 단일 책임)
- 범용적이지 않게, 인터페이스를 사용하는 클라이언트 기준으로 인터페이스를 분리한다
- 인터페이스를 잘게 분리함으로써, 클라이언트의 목적과 용도에 적합한 인터페이스 '만'을 제공하는 것
- 한번 개발한 인터페이스를 용도에 맞게 자꾸 수정한다는 목적으로 수차례 수정하는 건 지양
ISP 위반 사례: 거대 인터페이스 ❌
이 예시는 모든 결제 시스템의 기능을 하나의 큰 인터페이스에 묶어놓았을 때, 현금 결제처럼 단순한 클라이언트가 불필요한 메서드를 강제로 구현해야 하는 상황을 보여줍니다.
// ISP 위반: 모든 결제 수단이 이 모든 기능을 다 사용하지 않을 수 있음
interface IPaymentService {
void payByCard(double amount, String cardNumber); // 카드 결제
void payByCash(double amount); // 현금 결제
void refund(double amount, String transactionId); // 환불
void processInstallment(double amount, int months); // 할부 처리
void processNfcPayment(double amount); // NFC (간편) 결제
}
// 📌 문제의 클라이언트: CashPayment
class CashPayment implements IPaymentService {
@Override
public void payByCard(double amount, String cardNumber) {
// ❌ 현금 결제는 카드를 사용하지 않는데, 강제로 구현해야 함 (불필요)
throw new UnsupportedOperationException("Cash payment does not support card payment.");
}
@Override
public void payByCash(double amount) {
System.out.println("✅ Cash paid: " + amount);
}
@Override
public void refund(double amount, String transactionId) {
// ❌ 현금 환불은 복잡한 트랜잭션 ID 관리가 필요 없거나 로직이 다를 수 있음
throw new UnsupportedOperationException("Cash refund requires different logic.");
}
@Override
public void processInstallment(double amount, int months) {
// ❌ 현금은 할부가 불가능한데, 강제로 구현해야 함 (불필요)
throw new UnsupportedOperationException("Cash payment does not support installments.");
}
@Override
public void processNfcPayment(double amount) {
// ❌ 현금은 NFC 간편 결제를 지원하지 않는데, 강제로 구현해야 함 (불필요)
throw new UnsupportedOperationException("Cash payment does not support NFC.");
}
}
문제점: CashPayment(현금결제) 클라이언트는 payByCash 메서드만 필요하지만, IPaymentService 인터페이스에 묶여있는 나머지 4개의 메서드(payByCard, processInstallment 등)를 강제로 구현하고 UnsupportedOperationException을 던지는 불필요한 코드가 발생합니다. 이는 인터페이스가 정의한 계약과 실제 구현체의 필요성 사이에 불일치를 만들어냅니다.
ISP 준수 사례: 인터페이스 분리 ✅
거대 인터페이스를 기능별로 작고 응집도 높은 여러 개의 인터페이스로 분리하여, 각 클라이언트가 자신에게 필요한 계약만 구현하도록 만듭니다.
// 1. 기본 결제 기능
interface IBasicPayment {
void payByCash(double amount);
}
// 2. 카드 및 할부 기능
interface ICardPayment {
void payByCard(double amount, String cardNumber);
void processInstallment(double amount, int months);
}
// 3. 간편 결제 (NFC) 기능
interface INfcPayment {
void processNfcPayment(double amount);
}
// 4. 환불 기능 (모든 결제에 공통적이지 않을 수 있음)
interface IRefundable {
void refund(double amount, String transactionId);
}
// 📌 ISP 준수 클라이언트 1: 현금 결제
class CashPayment implements IBasicPayment {
// 오직 현금 결제에 필요한 메서드만 구현합니다.
@Override
public void payByCash(double amount) {
System.out.println("✅ Cash paid: " + amount);
}
// ICardPayment, INfcPayment의 불필요한 메서드를 구현할 필요가 없습니다.
}
// 📌 ISP 준수 클라이언트 2: 신용카드 결제
class CreditCardPayment implements ICardPayment, IRefundable {
// 카드 결제에 필요한 기능과 환불 기능만 구현합니다.
@Override
public void payByCard(double amount, String cardNumber) {
System.out.println("✅ Card payment processed: " + amount);
}
@Override
public void processInstallment(double amount, int months) {
System.out.println("✅ Installment processed over " + months + " months.");
}
@Override
public void refund(double amount, String transactionId) {
System.out.println("✅ Card refund issued for transaction: " + transactionId);
}
}
개선점:
- 결합도 감소: CashPayment 클래스는 이제 자신이 사용하는 IBasicPayment 인터페이스에만 의존합니다.
- 유지보수 용이: 만약 INfcPayment에 새로운 간편 결제 방식이 추가되어 인터페이스가 변경되더라도, CashPayment와 CreditCardPayment에는 아무런 영향이 없습니다.
- LSP 지원: 인터페이스를 분리함으로써 각 인터페이스의 계약이 명확해져 리스코프 치환 원칙(LSP)을 준수하기가 훨씬 수월해집니다.
참고 자료
💠 객체 지향 설계의 5가지 원칙 - S.O.L.I.D
객체 지향 설계의 5원칙 S.O.L.I.D 모든 코드에서 LSP를 지키기에는 어려움. 리스코프 치환 원칙에 따르면 자식 클래스의 인스턴스가 부모 클래스의 인스턴스를 대신하더라도 의도에 맞게 작동되어
inpa.tistory.com
💠 완벽하게 이해하는 ISP (인터페이스 분리 원칙)
인터페이스 분리 원칙 - ISP (Interface Segregation Principle) ISP 원칙이란 범용적인 인터페이스 보다는 클라이언트(사용자)가 실제로 사용하는 Interface를 만들어야 한다는 의미로, 인터페이스를 사용에
inpa.tistory.com
반응형
'IT > Architecture' 카테고리의 다른 글
| 디자인 패턴(Design Pattern)이란? (0) | 2025.10.29 |
|---|---|
| DIP 의존성 역전 원칙 | SOLID 설계 원칙 (0) | 2025.10.26 |
| LSP 리스코프 치환 원칙 | SOLID 설계 원칙 (0) | 2025.10.26 |
| OCP 개방-폐쇄 원칙 | SOLID 설계 원칙 (0) | 2025.10.26 |
| SRP 단일 책임 원칙 | SOLID 설계 원칙 (0) | 2025.10.26 |