학습 목표
- SOLID 원칙을 이해하고 실제 코딩에 적용할 수 있다.
- 각 원칙을 설명할 수 있으며, 코드의 유지보수성을 높이는 방법을 배운다.
- 객체지향 프로그래밍에서의 설계 개선 방법을 습득한다.
로버트 C. 마틴(Robert C. Martin),
흔히 "아저씨 보브(Uncle Bob)"로 알려진 소프트웨어 엔지니어가 발표한 객체 지향 프로그래밍 설계 원칙입니다.
즉, SOLID 원칙이란 객체지향 설계의 5가지 중요한 원칙을 뜻하며,
유지보수성과 확장성을 높이기 위해 설계 과정에서 따르는 지침입니다.
리스코프 치환 원칙 (Liskov Substitution Principle, LSP)
- 설명: 자식 클래스는 언제나 부모 클래스를 대체할 수 있어야 한다. 즉, 자식 클래스가 부모 클래스의 행동을 변경해서는 안 된다는 원칙입니다.
class Bird {
public void fly() {
System.out.println("새늘 날아다릴 수 있어요");
}
}
class Penguin extends Bird {
@Override
public void fly() {
throw new UnsupportedOperationException("펭귄은 못 날아요");
}
}
Penguin은 Bird 클래스를 상속했지만 fly() 메서드를 정상적으로 구현하지 못하므로 LSP를 위반합니다.
올바른 예시 (LSP 준수)
해결책은 Bird 클래스에 공통 동작으로 날 수 있는 기능을 넣는 대신, 새의 특성에 따라 상속 구조를 분리하거나, 날 수 있는지 여부를 결정할 수 있는 더 적절한 설계를 도입하는 것입니다.
interface Flyable {
void fly();
}
class Bird {
public void eat() {
System.out.println("Bird is eating");
}
}
class Sparrow extends Bird implements Flyable {
@Override
public void fly() {
System.out.println("Sparrow is flying");
}
}
class Penguin extends Bird {
// Penguin 클래스는 Flyable을 구현하지 않음, 즉 fly() 메서드가 없음
}
즉, LSP는 상속을 올바르게 사용하기 위한 핵심 지침이며, '바텀업(Bottom-up) 방식의 상속'은
LSP를 자연스럽게 지킬 수 있는 매우 훌륭한 방법론입니다.
인터페이스 분리 원칙 (Interface Segregation Principle, ISP)
- 설명: 클라이언트는 자신이 사용하지 않는 인터페이스에 의존하지 않아야 한다. 즉, 큰 인터페이스보다 구체적이고 작은 인터페이스로 나누는 것이 좋습니다.
- 설명: 클라이언트는 자신이 사용하지 않는 인터페이스에 의존하지 않아야 한다. 즉, 큰 인터페이스보다 구체적이고 작은 인터페이스로 나누는 것이 좋습니다.
interface Worker {
void work();
void eat();
}
// 잘못된 예: 한 인터페이스에 너무 많은 역할을 포함
class Robot implements Worker {
public void work() {
// robot working
}
public void eat() {
// robot can't eat, 위반된 예
}
}
// 더 나은 설계
interface Workable {
void work();
}
interface Eatable {
void eat();
}
class Human implements Workable, Eatable {
public void work() {
// human working
}
public void eat() {
// human eating
}
}
class Robot implements Workable {
public void work() {
// robot working
}
}
의존성 역전 원칙 (Dependency Inversion Principle, DIP)
- 설명: 고수준 모듈은 저수준 모듈에 의존해서는 안 된다. 둘 다 추상화에 의존해야 한다.
interface MessageSender {
void send(String message);
}
class EmailSender implements MessageSender {
public void send(String message) {
System.out.println("Sending email: " + message);
}
}
class NotificationService {
private MessageSender sender;
public NotificationService(MessageSender sender) {
this.sender = sender;
}
public void sendNotification(String message) {
sender.send(message);
}
}
'JAVA' 카테고리의 다른 글
| OCP (개방-폐쇄 원칙) (0) | 2025.10.15 |
|---|---|
| SRP (Single Responsibility Principle) - 단일 책임 원칙 (0) | 2025.10.15 |
| [1단계] 프로젝트 초기 설정과 핵심 도메인 설계 (0) | 2025.10.15 |
| 프로젝트생성 (0) | 2025.10.15 |
| 디자인 패턴 - 전략 패턴 (0) | 2025.10.02 |