1. S : 단일 책임 원칙 (SRP) 적용
- 문제점 : SRP 원칙은 단일 책임 원칙으로써, 한 클래스는 한 가지 책임에만 집중해야 한다! 그러나 현재 Manager 클래스의 상태를 보면,
public class Manager {
private final Menu menu;
private final CoffeeFactory factory;
private final CoffeeMaker maker;
public Manager(Menu menu, CoffeeFactory factory, CoffeeMaker maker) {
this.menu = menu;
this.factory = factory;
this.maker = maker;
}
public void takeOrder(String name, Payment payment) {
if(!menu.hasItem(name)) {
System.out.println("쏘리 우리는 없습니다:" + name);
return;
}
int price = menu.getPrice(name);
Coffee coffee = factory.createCoffee(name);
System.out.println(price);
payment.pay(price);
maker.makeCoffee(coffee);
}
}
- 메뉴 확인 + 커피 생성 + 결제 처리 + 제조 명령 + 출력 까지... 정말 많은 기능을 수행하고 있다!
그러므로 만약 현재는 결제 방식이 카드결제밖에 없지만, 나중에 현금결제나 쿠폰이나 그런 할인 기능이 추가되거나 커피 제조 과정을 로그로 보여줘야 한다거나 결제 전에 잔액확인을 해서 한도초과라면 결제 못하게 해야 한다거나 커피 제조 전에 대기번호가 추가된다거나 하면,
Manager 클래스를 수정해야 하니 의존성이 점점 추가되므로 코드가 엄청나게 길어진 것이다. 그러면 테스트가 어려워지며 버그가 발생하도 고치기 힘들어진다.
즉, SRP 원칙을 준수하여 Manager 클래스는 주문 접수만 하고 OrderProcessor 클래스를 새로 만들어 얘는 주문 처리만 하도록 변경해주는 것이 올바르다!
class Manager {
private final OrderProcessor orderProcessor;
public Manager(OrderProcessor orderProcessor) {
this.orderProcessor = orderProcessor;
}
public void takeOrder(String name, Payment payment) {
orderProcessor.process(name, payment);
}
}
class OrderProcessor {
private final Menu menu;
private final CoffeeFactory factory;
private final CoffeeMaker maker;
public OrderProcessor(Menu menu, CoffeeFactory factory, CoffeeMaker maker) {
this.menu = menu;
this.factory = factory;
this.maker = maker;
}
public void process(String name, Payment payment) {
if (!menu.hasItem(name)) {
System.out.println("쏘리 우리는 없습니다: " + name);
return;
}
int price = menu.getPrice(name);
Coffee coffee = factory.createCoffee(name);
System.out.println("가격: " + price + "원");
payment.pay(price);
maker.makeCoffee(coffee);
}
}
또다른 이야기로 Menu로 조금 더 확장해보면 아마 재고 관리 기능을 추가한다거나 했을 때 이걸 Menu에서 관리하게 한다기보다는 다른 재고관리 클래스를 새로 만들어서 해보면 좋을 것 같다는 생각도 들었지만 지금은 여기에서 일단 마무리해보는 걸로!
2. O : 개방 폐쇄 원칙 (OCP) 적용
- 문제점 : OCP는 확장과 수정에 있어서 열려 있어야 한다는 원칙인데, Payment를 추가했을 때 이걸 그냥 결제가 아니라 카드나 현금으로 결제할 수 있도록 Payment를 인터페이스로 만들었다.
즉, 기존 코드를 수정하지 않고 새 클래스만 추가하면 된다는 점에서 발전되었다!
interface Payment {
void pay(int amount);
}
class CardPayment implements Payment {
@Override
public void pay(int amount) {
System.out.println("카드 결제 완료: " + amount + "원");
}
}
별개지만 Manager와 OrderProcessor가 CardPayment가 아니라 Payment 인터페이스에 의존하니까 DIP도 적용되었다고 볼 수 있겠다.
별개로 CoffeeFactory 클래스를 보면, 새 메뉴가 추가되면 switch 문을 사용하고 있어서 새 메뉴가 추가되었을 때 확장이 어렵다. 그래서 Map을 활용해서 새 메뉴 추가 메서드를 추가해보면 될 것 같다.

느낀 점
이미 완벽해 보였고 잘 돌아가는 코드였는데 SOLID 원칙을 적용해서 수정해보니 코드가 더 깔끔해진 것 같아서 좋은 것 같다. 한 가지 클래스나 인터페이스가 너무 많은 역할을 수행하지 않도록 하고 코드의 수정이 용이하도록 변경하는 방식에 대해 조금 알 것 같다. 추가로 기술블로그에 대한 이야기를 들었었는데.. 그래서 지난 주에는 노션을 사용했었는데 보이는 결과가 중요할 것 같아서 티스토리로 플랫폼을 바꿔가는 시도를 하는 중이다. 티스토리는 다른 사람한테도 보여지니까!
'Develop > Java' 카테고리의 다른 글
| [10주차] SpringBoot - 1 (0) | 2025.11.23 |
|---|---|
| [9주차] DB & JDBC (0) | 2025.11.16 |
| [8주차] GUI + Event + Thread를 이용한 망나니 잡기 (0) | 2025.11.02 |
| [7주차-2] 디자인패턴 추가조사 - 데코레이터 패턴 (0) | 2025.10.18 |
| [7주차] 디자인패턴 기초실습 (0) | 2025.10.15 |