객체 중복 생성 문제 해결

송영재·2022년 10월 10일

Spring

목록 보기
43/45

🔥 혹시 지금까지 구현한 코드를 조금 더 개선할 수 있을까요?

  • 41) 객체 중복 생성 문제 👉 ProductService 를 보시면 "new ProductRepository()" 코드가 중복되는 게 보이시나요?
    public class ProductService {
    
        public List<Product> getProducts() throws SQLException {
            ProductRepository productRepository = new ProductRepository();
    				// ...
        }
    
        public Product createProduct(ProductRequestDto requestDto) throws SQLException {
            ProductRepository productRepository = new ProductRepository();
            // ...
        }
    
        public Product updateProduct(Long id, ProductMypriceRequestDto requestDto) throws SQLException {
            ProductRepository productRepository = new ProductRepository();
    				// ...
        }
    }		
    👉 아래 코드는 "빵틀에서 빵을 만들라"는 명령을 내리는 것이고, "객체 생성" 과정이라고 표현합니다.
    ProductRepository productRepository = new ProductRepository();
    • ProductRepository 클래스 = 빵틀

    • productRepository 객체 = 실제 재료를 넣어서 만들어진 빵

      👉 "가위"를 예로 들어 설명 드리자면, "가위가 필요할 때마다 가위를 만들어서 사용하는 것"과 같습니다.

  • 42) 객체 중복 생성 코드 정리
    👉 ProductService 가 생성될 때, 딱 한 번 생성해서 계속 사용하면 어떨까요?
    public class ProductService {
        
        **// 멤버 변수 선언**
        private final ProductRepository productRepository;
    
        // **생성자**: ProductService() 가 생성될 때 호출됨
        public ProductService() {
            **// 멤버 변수 생성**
            this.productRepository = new ProductRepository();
        }
        
        public Product createProduct(ProductRequestDto requestDto) throws SQLException {
            // 요청받은 DTO 로 DB에 저장할 객체 만들기
            Product product = new Product(requestDto);
    
            **// 멤버 변수 사용**
            this.productRepository.createProduct(product);
    
            return product;
        }
👉 오! 좋네요~! 그럼 ProductController 와 ProductService 에 모두 적용해 봅시다!

"this 지시자" 는 생략 가능

[코드스니펫] ProductController 중복 삭제

        import lombok.RequiredArgsConstructor;
        import org.springframework.web.bind.annotation.*;
        
        import java.sql.SQLException;
        import java.util.List;
        
        @RequiredArgsConstructor // final로 선언된 멤버 변수를 자동으로 생성합니다.
        @RestController // JSON으로 데이터를 주고받음을 선언합니다.
        public class ProductController {
        
            private final ProductService productService;
        
        		public ProductController() {
                ProductService productService = new ProductService();
                this.productService = productService;
            }
            
            // 신규 상품 등록
            @PostMapping("/api/products")
            public Product createProduct(@RequestBody ProductRequestDto requestDto) throws SQLException {
                Product product = productService.createProduct(requestDto);
        
                // 응답 보내기
                return product;
            }
        
            // 설정 가격 변경
            @PutMapping("/api/products/{id}")
            public Long updateProduct(@PathVariable Long id, @RequestBody ProductMypriceRequestDto requestDto) throws SQLException {
                Product product = productService.updateProduct(id, requestDto);
        
                // 응답 보내기 (업데이트된 상품 id)
                return product.getId();
            }
        
            // 등록된 전체 상품 목록 조회
            @GetMapping("/api/products")
            public List<Product> getProducts() throws SQLException {
                List<Product> products = productService.getProducts();
        
                // 응답 보내기
                return products;
            }
        }
  • [코드스니펫] ProductService 중복 삭제
        import java.sql.SQLException;
        import java.util.List;
        
        public class ProductService {
            
        		private final ProductRepository productRepository;
        
            public ProductService() {
                ProductRepository productRepository = new ProductRepository();
                this.productRepository = productRepository;
            }
        
            public Product createProduct(ProductRequestDto requestDto) throws SQLException {
                // 요청받은 DTO 로 DB에 저장할 객체 만들기
                Product product = new Product(requestDto);
                
                productRepository.createProduct(product);
        
                return product;
            }
        
            public Product updateProduct(Long id, ProductMypriceRequestDto requestDto) throws SQLException {
                Product product = productRepository.getProduct(id);
                if (product == null) {
                    throw new NullPointerException("해당 아이디가 존재하지 않습니다.");
                }
        
                int myprice = requestDto.getMyprice();
                productRepository.updateMyprice(id, myprice);
        
                return product;
            }
        
            public List<Product> getProducts() throws SQLException {
                List<Product> products = productRepository.getProducts();
        
                return products;
            }
        }
👉 리팩토링이 끝나면 꼭 테스트를 통해 기능에 문제가 없는지 확인하기!

잊지 않으셨죠? ☺️

그런데.. 테스트를 매번 하는게 힘들지 않으신가요?? 우리 수업 3장에서 '스프링 테스트 프레임워크' 에서는 테스트 코드를 작성하여 자동 테스트하는 방법을 배웁니다.

0개의 댓글