🔥 혹시 지금까지 구현한 코드를 조금 더 개선할 수 있을까요?
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 객체 = 실제 재료를 넣어서 만들어진 빵
👉 "가위"를 예로 들어 설명 드리자면, "가위가 필요할 때마다 가위를 만들어서 사용하는 것"과 같습니다.
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;
}
}
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장에서 '스프링 테스트 프레임워크' 에서는 테스트 코드를 작성하여 자동 테스트하는 방법을 배웁니다.