객체지향 원칙은 외우기가 쉬운거 같아요 앞글자만해서 SOLID로 알고 계실겁니다.
오늘은 여기서 S
O
가 담당하는 단일 책임 원칙과 개방패쇄 원칙을 알아보겠습니다.
단일 책임 원칙은 하나의 클래스는 하나의 책임만 가져야 한다는 원칙입니다.
즉, 변경이 필요한 이유는 오직 하나여야 합니다.
public class UserService {
public void registerUser(String username) {
// 1. 사용자 등록
System.out.println(username + " 등록 완료");
// 2. 이메일 전송
System.out.println("이메일 전송");
}
}
UserService는 사용자 등록뿐만 아니라 이메일 전송 책임까지 갖고 있어 SRP를 위반하고 있습니다.
public class UserService {
private final EmailService emailService;
public UserService(EmailService emailService) {
this.emailService = emailService;
}
public void registerUser(String username) {
System.out.println(username + " 등록 완료");
emailService.sendEmail(username);
}
}
public class EmailService {
public void sendEmail(String username) {
System.out.println(username + "에게 이메일 전송");
}
}
각 클래스가 하나의 책임만을 갖게 되면서 코드의 응집도는 높이고, 변경에 유연한 구조가 됩니다.
개방-폐쇄 원칙은 확장에는 열려 있고, 변경에는 닫혀 있어야 한다는 원칙입니다.
즉, 기존 코드를 수정하지 않고도 새로운 기능을 추가할 수 있어야 한다는 의미입니다.
public class PaymentService {
public void pay(String method) {
if (method.equals("card")) {
System.out.println("카드 결제");
} else if (method.equals("kakao")) {
System.out.println("카카오페이 결제");
}
}
}
새로운 결제 수단이 추가될 때마다 PaymentService 내부를 계속 수정해야 하므로 OCP 위반입니다.
public interface Payment {
void pay();
}
public class CardPayment implements Payment {
public void pay() {
System.out.println("카드 결제");
}
}
public class KakaoPayment implements Payment {
public void pay() {
System.out.println("카카오페이 결제");
}
}
public class PaymentService {
public void doPayment(Payment payment) {
payment.pay();
}
}
PaymentService는 Payment 인터페이스에만 의존하며, 새로운 결제 방식이 생기더라도 기존 코드는 전혀 건드릴 필요가 없습니다.
원칙 | 정의 |
---|---|
SRP (단일 책임 원칙) | 클래스는 하나의 책임만 가져야 함 |
OCP (개방-폐쇄 원칙) | 확장에는 열려 있고, 변경에는 닫혀야 함 |