SOLID가 뭔가요? 🤔
객체지향 프로그래밍의 5가지 핵심 설계 원칙입니다.
마치 탄탄한 건물을 짓기 위한 건축의 기본 원칙처럼, 견고한 소프트웨어를 만들기 위한 기초가 되는 원칙들이에요!
S - 단일 책임 원칙 (Single Responsibility Principle) 📝
핵심 개념
- 한 클래스는 단 하나의 책임만 가져야 합니다
- "변경의 이유가 오직 하나여야 한다"는 의미
예시 코드
// Bad Example
class UserService {
public void saveUser(User user) { /* 저장 로직 */ }
public void sendEmail(User user) { /* 이메일 발송 로직 */ }
public void generateReport(User user) { /* 리포트 생성 로직 */ }
}
// Good Example
class UserService {
private EmailService emailService;
private ReportService reportService;
public void saveUser(User user) { /* 순수하게 저장 로직만 */ }
}
O - 개방-폐쇄 원칙 (Open-Closed Principle) 🔓
핵심 개념
- 확장에는 열려있고, 수정에는 닫혀있어야 함
- 기존 코드를 변경하지 않고 새로운 기능을 추가할 수 있어야 함
예시 코드
// Bad Example
class PaymentProcessor {
public void processPayment(String type) {
if (type.equals("CARD")) {
// 카드 결제 로직
} else if (type.equals("BANK")) {
// 계좌이체 로직
}
}
}
// Good Example
interface PaymentStrategy {
void processPayment();
}
class CardPayment implements PaymentStrategy {
public void processPayment() { /* 카드 결제 로직 */ }
}
class BankPayment implements PaymentStrategy {
public void processPayment() { /* 계좌이체 로직 */ }
}
L - 리스코프 치환 원칙 (Liskov Substitution Principle) 🔄
핵심 개념
- 자식 클래스는 부모 클래스의 역할을 완벽하게 대체할 수 있어야 함
- 기존 동작을 방해하지 않고 확장이 가능해야 함
예시 코드
// Bad Example
class Bird {
public void fly() { }
}
class Penguin extends Bird { // 펭귄은 날 수 없는데...
public void fly() {
throw new UnsupportedOperationException();
}
}
// Good Example
interface Flyable {
void fly();
}
class Bird {
// 기본 조류 특성
}
class Sparrow extends Bird implements Flyable {
public void fly() { /* 날기 구현 */ }
}
I - 인터페이스 분리 원칙 (Interface Segregation Principle) 🔍
핵심 개념
- 클라이언트는 자신이 사용하지 않는 메서드에 의존하면 안 됨
- 하나의 큰 인터페이스보다 여러 개의 작은 인터페이스가 좋음
예시 코드
// Bad Example
interface Worker {
void work();
void eat();
void sleep();
}
// Good Example
interface Workable {
void work();
}
interface Eatable {
void eat();
}
interface Sleepable {
void sleep();
}
class Human implements Workable, Eatable, Sleepable {
// 필요한 기능만 구현
}
D - 의존성 역전 원칙 (Dependency Inversion Principle) 🔄
핵심 개념
- 고수준 모듈은 저수준 모듈에 의존하면 안 됨
- 둘 다 추상화에 의존해야 함
예시 코드
// Bad Example
class OrderService {
private MySQLDatabase database; // 구체적인 구현에 의존
public void saveOrder(Order order) {
database.save(order);
}
}
// Good Example
interface Database {
void save(Order order);
}
class OrderService {
private Database database; // 추상화에 의존
public OrderService(Database database) {
this.database = database;
}
}
SOLID 원칙의 실제 적용 예시 💡
쇼핑몰 시스템 예시
// 1. 단일 책임 원칙 (SRP)
class OrderProcessor {
private PaymentService paymentService;
private InventoryService inventoryService;
private NotificationService notificationService;
public void processOrder(Order order) {
paymentService.processPayment(order);
inventoryService.updateInventory(order);
notificationService.sendConfirmation(order);
}
}
// 2. 개방-폐쇄 원칙 (OCP)
interface DiscountStrategy {
double calculateDiscount(Order order);
}
// 3. 리스코프 치환 원칙 (LSP)
abstract class Payment {
abstract void validate();
abstract void process();
}
// 4. 인터페이스 분리 원칙 (ISP)
interface OrderRepository {
void save(Order order);
Order findById(Long id);
}
// 5. 의존성 역전 원칙 (DIP)
class OrderService {
private final OrderRepository repository;
private final PaymentService paymentService;
OrderService(OrderRepository repository, PaymentService paymentService) {
this.repository = repository;
this.paymentService = paymentService;
}
}
SOLID 원칙 적용의 장점 🌟
유지보수성 향상
- 코드 변경이 쉬워짐
- 버그 수정이 용이
재사용성 증가
- 모듈화된 코드
- 다른 프로젝트에서도 활용 가능
테스트 용이성
- 단위 테스트 작성 쉬움
- 버그 예방 효과
주의사항 ⚠️
과도한 적용 금지
- 작은 프로젝트에서는 오버엔지니어링이 될 수 있음
상황에 맞는 적용
- 프로젝트의 규모와 특성 고려
- 팀의 역량 고려
참고문헌
- Clean Architecture (Robert C. Martin)
- Head First Design Patterns
- Effective Java (Joshua Bloch)
#Java #객체지향 #SOLID #CleanCode #개발자성장
728x90
'800===Dev Docs and License > Clean Code' 카테고리의 다른 글
코드 품질 향상을 위한 대형 메서드 분리 기법 🚀 (1) | 2024.12.06 |
---|