## SOLID - ISP
# 20240326 피어세션
## 🥬 상추
### ISP (Interface Segregation Principle - 인터페이스 분리 원칙)
- 정의: ISP, 즉 인터페이스 분리 원칙은 "클라이언트가 자신이 사용하지 않는 메소드에 의존하도록 강제해서는 안 된다"는 개념을 말합니다. 다시 말해, 하나의 범용 인터페이스보다는 여러 개의 구체적인 인터페이스가 낫다는 원칙입니다.
- 목적: 클라이언트(인터페이스를 사용하는 코드)가 필요하지 않은 기능에 의존하지 않도록 하여, 시스템의 결합도를 낮추고, 변경에 대한 유연성을 증가시키는 것입니다.
- 구현 방법: 대규모 인터페이스를 구현하는 대신, 필요한 특정 기능만을 제공하는 더 작고 구체적인 인터페이스들로 분리합니다. 이렇게 함으로써 클래스는 필요한 인터페이스만을 구현하여, 불필요한 의존성을 줄일 수 있습니다.
<br>
<br>
## 🌱 애셔
- 인터페이스 분리 원칙은 "클라이언트는 자신이 사용하지 않는 인터페이스에 의존 관계를 맺으면 안 된다"는 원칙.
- 즉, 인터페이스는 사용자가 필요로 하는 기능에 따라 적절하게 분리돼야 한다.
### 장점
1. 낮은 결합도
2. 유연성과 확장성
3. 클라이언트 코드의 간결성
### 단점
1. 복잡성 증가
2. 추상화의 어려움
3. 설계 시간 증가
```java
interface ISmartPhone {
void call(String number); // 통화 기능
void message(String number, String text); // 문제 메세지 전송 기능
void wirelessCharge(); // 무선 충전 기능
void AR(); // 증강 현실(AR) 기능
void biometrics(); // 생체 인식 기능
}
```
- 동작을 못하는 기능이 있어도 추상 메소드 구현 규칙상 오버라이딩은 하되, 메서드 내부는 빈공간으로 두거나 혹은 예외를 발생토록 구성해야 한다.
- 결국 필요하지도 않은 기능을 어쩔수없이 구현해야하는 낭비가 발생된 것이다.
```java
interface IPhone {
void call(String number); // 통화 기능
void message(String number, String text); // 문제 메세지 전송 기능
}
interface WirelessChargable {
void wirelessCharge(); // 무선 충전 기능
}
interface ARable {
void AR(); // 증강 현실(AR) 기능
}
interface Biometricsable {
void biometrics(); // 생체 인식 기능
}
```
```java
class S21 implements IPhone, WirelessChargable, ARable, Biometricsable {}
class S3 implements IPhone {}
```
#### 출처: https://inpa.tistory.com/entry/OOP-💠-아주-쉽게-이해하는-ISP-인터페이스-분리-원칙 [Inpa Dev 👨💻:티스토리]
<br>
<br>
## 💧 웨이드
- 요약 설명
- 클라이언트는 자신이 사용하지 않는 인터페이스에 의존하지 않아야 합니다.
- 클라이언트가 필요로 하는 메서드로만 구성된 인터페이스를 제공해야 합니다.
- 이는 더 큰 인터페이스를 더 작은 인터페이스로 분할해야 함을 의미합니다.
- 목적과 필요성
- 이를 통해 구현 클래스가 관심 있는 메서드만 사용하도록 할 수 있습니다.
- 예제 코드
```java
public interface BearKeeper {
void washTheBear();
void feedTheBear();
void petTheBear();
}
```
```java
public interface BearCleaner {
void washTheBear();
}
public interface BearFeeder {
void feedTheBear();
}
public interface BearPetter {
void petTheBear();
}
```
```java
public class CrazyPerson implements BearPetter {
public void petTheBear() {
//Good luck with that!
}
}
```
이러한 인터페이스 분리를 통해 필요한 메서드만 선택해서 구현할 수 있습니다.
- 출처
https://www.baeldung.com/solid-principles#interface-segregation-principle-isp
<br>
<br>
## 🍜 짜왕
ISP, 인터페이스 분리 원칙은 객체지향 디자인의 SOLID 원칙 중 하나이다. 인터페이스를 사용하는 클래스가 "**사용하지 않는 메서드에 의존되어서는 안된다**"라는 점이 강조되는데 이는 인터페이스가 **구현 클래스와 관련있는 메소드로만 구성되어야** 한다는 것이다!
문서 처리 시스템을 예시로 들어보자.
```java
public interface IDocument {
void Open();
void save();
void print();
}
```
위와 같이 다양한 기능을 하는 문서 처리 시스템이 인터페이스로 설계되어 있다.
이 인터페이스를 구현하고자 하면 아래와 같이 클래스를 구현해야할 것이다.
```java
public class WordDocument : IDocument
{
public void Open()
{
// Word 문서 로직 열기
}
public void Save()
{
// Word 문서 로직 저장
}
public void Print()
{
// Word 문서 로직 인쇄
}
}
public class PDFDocument : IDocument
{
public void Open()
{
// PDF 문서 로직 열기
}
public void Save()
{
// PDF 문서 로직 저장
}
public void Print()
{
// PDF 문서 로직 인쇄
}
}
```
이렇게 된다면, WordDocument및 PDFDocument클래스 모두 필요하지 않은 메서드까지 구현해야 한다. 예를 들어, pdf 문서의 인쇄 로직을 사용하지 않고 싶은데 인터페이스를 구현하기 위해서는 어쩔 수 없이 구현해야 한다.
즉, 인터페이스 분리 원칙을 위반하고 있다.
ISP를 지키면서 더 나은 설계를 하고자 하면 아래와 같이 설계할 수 있다.
```java
public interface IOpenable {
void Open();
}
public interface ISaveable {
void save();
}
public interface IPrintable {
void print();
}
```
* 출처 : [medium](https://medium.com/@sunny12jun/the-interface-segregation-principle-isp-35b16f91f4f8)