728x90
반응형
SMALL
학습내용
- 리팩토링
- 실습
학습정리
1. 리팩토링
정의
- 기존 애플리케이션의 기능적인 동작을 유지하면서, 코드의 구조를 체계적으로 개선하는 작업
- 가독성, 유지보수성, 확장성을 높이는 작업
주요 기법
메서드 추출 : 긴 메서드에서 관련 있는 블록을 별도의 메서드로 추출
@Transactional public Boolean create(OrderRequest request) { try { //order 저장 별도의 메서드로 추출 Order order = save(request.getUserId(), request.getShoppingAddress()); //orderItems 저장 별도의 메서드로 추출 List<OrderItem> orderItems = orderProcessService.saveOrderItems(order, request.getOrderProducts()); //총합 금액 설정 별도의 메서드로 추출 BigDecimal totalPrice = orderProcessService.getOrderTotalPrice(orderItems); order.setTotalPrice(totalPrice); orderRepository.save(order); return true; } catch (ServiceException e){ log.error("주문 처리 중 서비스 예외 발생 : {}", e.getMessage(),e); throw e; } catch (Exception e){ log.error("주문 처리 중 시스템 예외 발생 : {}", e.getMessage(),e); throw new RuntimeException("주문 처리 중 문제가 발생했습니다.", e); } }
클래스 분리 : 하나의 클래스가 너무 많은 책임을 가지는 경우, 역할에 따라 분리
@Service @RequiredArgsConstructor public class OrderService { //orderProcessService 로 분리 private final OrderProcessService orderProcessService; private final OrderRepository orderRepository; private final UserRepository userRepository; @Transactional public Order order(OrderRequest request) { ...생략 //역할 분리로 OrderProcessService와 OrderService 분리 //OrderProcessService를 주입받아 사용 Order order = save(...); OrderItems orderItems = orderProcessService.createOrderItems(..) orderProcessService.validateStock(..) } public Order save(Long userId) { ... } }
@Service @RequiredArgsConstructor public class OrderProcessService { private final OrderItemRepository orderItemRepository; private final ProductRepository productRepository; public List<OrderItem> createOrderItems(OrderRequest request, Order order){ ... } public BigDecimal calculateTotalPrice(List<OrderItem> orderItems) { ... } //해당 OrderProcessService에서만 사용되는 메서드는 private private void validateStock(OrderProductRequest orderProduct, Product product) { ... } private OrderItem buildOrderItem(Order order, Product product, OrderProductRequest orderProduct) { ... } }
중복 코드 제거 : 여러 곳에서 반복되는 코드는 공통 메서드로 추출
public Order save(Long userId) { User orderUser = getUser(userId); ... } public void cancelOrder(Long userId, Long orderId) { User orderUser = getUser(userId); ... } //중복되는 코드 공통 메서드로 추출 private User getUser(Long userId) { return userRepository.findById(userId) .orElseThrow(() -> new ServiceException(ServiceExceptionCode.NOT_FOUND_USER)); }
상태와 행위 분리 : 엔티티와 비즈니스 로직을 분리하여 설계
//기존 분리전 @Entity ...생략 public class Product{ ...생략 public void update(String name,String description){ this.name = name; this.description = description; } }
//분리 후 //ProductProcessor(Service) 클래스 private Product updateProduct(Long id, ProductRequest request) { //공통 메서드로 추출한 getProduct, getCategory Product product = getProduct(id); Category category = getCategory(request.getCategoryId()); //해당 엔티티 필드 setter를 이용하여 product.setName(request.getName()); product.setCategory(category); return productRepository.save(product); }
추가적으로..
리팩토링의 중요성을 알고는 있었지만, 실천하기가 어려웠는데
이번 강의와 실습을 통해서 유용하게 리팩토링하는 방법도 배워서 좋았다.
마지막에 상태와 행위 분리부분에서 배운 내용은 계속해서 고민이 있던 부분였는데
처리 방법을 하나 배운 것 같아서 뜻 깊은 시간였습니다.
아직까지 리팩토링의 기준점이 잘 잡히지는 않았지만
많은 연습을 통해서 나의 확실한 기준을 잡아야 할 것 같다.
728x90
반응형
LIST
'TIL' 카테고리의 다른 글
3_4.API테스트 작성 연습 (0) | 2025.01.13 |
---|---|
3_3.클린코드 원칙 이해 (0) | 2025.01.13 |
3_1.Spring AOP를 활용한 로깅 및 예외 처리 (0) | 2025.01.10 |
2_5.QueryDSL 활용 (0) | 2025.01.10 |
2_4.QueryDSL 설정 및 활용 (0) | 2025.01.10 |