1. 튜터님에게 피드백 받은 메서드 파라미터에서의 의존성 낮추기
// Kiosk 클래스
view.printTotalPrice(cartManager);
// View 클래스
public void printCartList(CartManager cartManager) {
System.out.println("[ Orders ]");
List<CartItem> cartItemList = cartManager.getCartItemList();
for (CartItem cartItem : cartItemList) {
System.out.println(cartItem.getItemName() + " | W " +
cartItem.getPrice() + " | " + cartItem.getQuantity());
}
}
근데 이 코드에서 문제가 있었는데 바로 무엇이냐?!
이런 식으로 Kiosk 클래스에서 view.printTotalPrice() 메서드가 인스턴스를 인자로 넘겨주고 View클래스 printCartList 메서드 에서는 인스턴스에서 파라미터로 받고있다. 바로 이 부분이 잘못되었다.
왜냐? 인스턴스를 파라미터로 주고 받는 방식은 클래스 간의 의존도를 높이는 원인이 될 수 있다.
이렇게 되면 코드의 결합도가 증가하여 확장이 어려워질 가능성이 있다.
따라서 나는 SOLID에서 O, OCP원칙(Open Closed Principle)을 지키지 않고 있었던 것이다.
그래서 의존도를 낮추기 위한 코드 변경을 보면
// Kiosk 클래스
view.printCartList(cartManager.getCartItemList());
// View 클래스
public void printCartList(List<CartItem> cartItemList) {
System.out.println("[ Orders ]");
for (CartItem cartItem : cartItemList) {
System.out.println(cartItem.getItemName() + " | W " + cartItem.getPrice() + " | " + cartItem.getQuantity());
}
}
이런 식으로 인스턴스를 직접 주지말고 필요한 데이터만 전달해 주는 것이다.
View 클래스의 printCartList함수를 보면 cartItemList만 필요하다.
클래스 간에 인스턴스를 통째로 전달하는 대신, 메서드가 필요로 하는 데이터만 파라미터로 전달하는 방식으로 변경하면 의존성을 줄 일 수 있다.
의존도를 낮추기 위한 방법 2번째
DTO(Data Transfer Object)를 사용하자!
DTO가 무엇이냐? DTO는 데이터 전송 객체로, 시스템 내에서 데이터를 운반하기 위한 클래스이다. 로직 없이 순수하게 데이터를 전달하는데만 사용되며, 주로 계층 간의 의존성을 낮추고 데이터를 명확하게 전달하기 위해 사용한다.
아래 코드를 보자.
// DTO 클래스
public class CartItemDTO {
private String itemName;
private int price;
private int quantity;
// 생성자
public CartItemDTO(String itemName, int price, int quantity) {
this.itemName = itemName;
this.price = price;
this.quantity = quantity;
}
// Getter
public String getItemName() {
return itemName;
}
public int getPrice() {
return price;
}
public int getQuantity() {
return quantity;
}
}
// CartManager 클래스
//CartManager에서 DTO 생성 및 반환
// DTO 리스트 생성 및 반환
public List<CartItemDTO> getCartItemDTOs() {
List<CartItemDTO> cartItemDTOs = new ArrayList<>();
for (CartItem cartItem : cartItems) {
cartItemDTOs.add(new CartItemDTO(
cartItem.getItemName(),
cartItem.getPrice(),
cartItem.getQuantity()
));
}
return cartItemDTOs;
}
// Kiosk 클래스에서 vartItemDTOs의 데이터 전달
List<CartItemDTO> cartItemDTOs = cartManager.getCartItemDTOs();
view.printCartList(cartItemDTOs);
// View 클래스
public void printCartList(List<CartItemDTO> cartItemDTOs) {
System.out.println("[ Orders ]");
for (CartItemDTO cartItemDTO : cartItemDTOs) {
System.out.println(cartItemDTO.getItemName() + " | W " + cartItemDTO.getPrice() + " | " + cartItemDTO.getQuantity());
}
}
처음 보면 약간 복잡할 수 있다! (사실 필자도 좀 머리 뜨거워짐;;)
그래서 내 프로젝트에서 DTO의 사용으로 View와 같은 출력 계층에서 불필요한 의존성을 줄이고, 명확한 데이터 전달 방식으로 유지보수성과 확장성을 확보하는 데 큰 도움이 됩니다.
어쨋든 DTO의 사용으로 객체지향 설계의 장점을 살리면서 계층 간의 결합도를 줄이는 데 유용한 도구이다.
많이 사용해보고 익숙해지자!!
2. 튜터님의 해설 강의 때 나온 주입 얘기

보면 Main 클래스에서 Menu, MenuItem 인스턴스를 생성 시켜주고 Kiosk를 생성할 때 Kiosk에서 필요한 Menu를 생성자를 통해 주입해주는 모습이다.
정리해보면 Main 클래스 main 메서드 안에서
1. Menu와 MenuItem 객체를 생성
2. Kiosk 객체도 생성
3. Kiosk 객체를 생성할 때 인자로 Menu 객체를 넣어 의존성 주입을 해줌.
왜냐? Kiosk 클래스에서 start()라는 메서드를 실행해야 코드가 작동되니깐. start()를 하려면 Menu 객체가 필요하기 때문에 넣어줬다.
4. kiosk.start() 실행
그럼 왜 주입을 사용하는가?
- 유지보수성
- Kiosk 클래스는 Menu의 구체적인 생성 방식을 몰라도 된다.
- Menu의 구현이 변경되더라도, Kiosk를 수정할 필요가 없다. - 재사용성
- Menu를 여러 곳에서 재사용할 수 있다.
- 다양한 Menu 객체를 만들어 Kiosk에 주입하면, Kiosk의 동작을 쉽게 변경할 수 있다.
이번 키오스크 과제를 통해서 평소 공부했지만 약간 부족한 부분을 채울 수 있어서 매우 만족스러웠다!
'Project' 카테고리의 다른 글
| (Java / Spring) TossPayments PG 윗젯 Version2 연동 (0) | 2025.02.14 |
|---|---|
| JPA를 활용한 일정 앱 프로젝트 트러블 슈팅 및 회고 (0) | 2024.12.12 |
| 일정 관리 앱 프로젝트 트러블 슈팅 및 회고 (2) | 2024.12.09 |
| 키오스크 프로젝트 트러블 슈팅 및 회고 (0) | 2024.11.22 |
| Java 계산기 프로젝트 진행하며 회고 및 트러블 슈팅 작성 (0) | 2024.11.12 |