[인프런 BE 0기] 코드 리팩토링

HeeYeon Kim·2024년 2월 26일

STUDY

목록 보기
12/15
post-thumbnail

인프런 워밍업 클럽 스터디 0기
BE 6일차



문제1

기존 FruitController를 Controller-Service-Repository로 분리


FruitController

package com.group.libraryapp.controller;

import com.group.libraryapp.dto.hw.Fruit;
import com.group.libraryapp.dto.hw.FruitCreateRequest;
import com.group.libraryapp.dto.hw.FruitResponse;
import com.group.libraryapp.service.hw.FruitService;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
public class FruitController {
    private final FruitService fruitService;
    public FruitController(FruitService fruitService) {
        this.fruitService = fruitService;
    }
    @PostMapping("/api/v1/fruit")
    public void saveFruit(@RequestBody Fruit fruit){
        fruitService.saveFruit(fruit);
    }

    @PutMapping("/api/v1/fruit")
    public void sellFruit(@RequestBody Map<String,Long> body){
        fruitService.sellFruit(body.get("id"));
    }

    @GetMapping("/api/v1/fruit")
    public FruitResponse calcPrice(@RequestParam String name){
        return fruitService.calcPrice(name);
    }
}

FruitService

package com.group.libraryapp.service.hw;

import com.group.libraryapp.dto.hw.Fruit;
import com.group.libraryapp.dto.hw.FruitCreateRequest;
import com.group.libraryapp.dto.hw.FruitResponse;
import com.group.libraryapp.repository.hw.FruitRepository;
import org.springframework.stereotype.Service;

@Service
public class FruitService {
    private final FruitRepository fruitRepository;

    public FruitService(FruitRepository fruitRepository) {
        this.fruitRepository = fruitRepository;
    }

    public void saveFruit(Fruit fruit){
        fruitRepository.saveFruit(fruit);
    }

    public void sellFruit(long id){
        fruitRepository.sellFruit(id);
    }

    public FruitResponse calcPrice(String name){
        return fruitRepository.calcPrice(name);
    }
}

FruitRepository

package com.group.libraryapp.repository.hw;

import com.group.libraryapp.dto.hw.FruitResponse;
import org.springframework.jdbc.core.JdbcTemplate;

import java.time.LocalDate;

@Repository
public class FruitRepository {

    private final JdbcTemplate jdbcTemplate;

    public FruitMySqlRepository(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public void saveFruit(Fruit fruit){
        String sql = "INSERT INTO fruit (name,warehousingDate,price) VALUES (?,?,?)";
        jdbcTemplate.update(sql,fruit.getName(),fruit.getWarehousingDate(),fruit.getPrice());
    }

    public void sellFruit(long id){
        String sql = "UPDATE fruit SET isSold=1 WHERE id=?";
        jdbcTemplate.update(sql,id);
    }

    public FruitResponse calcPrice(String name){
        String sql1 = "SELECT SUM(price) FROM fruit WHERE name=? AND isSold=?";
        String sql2 = "SELECT SUM(price) FROM fruit WHERE name=? AND isSold=?";

        long salesAmount = jdbcTemplate.queryForObject(sql1,Long.class,name,1);
        long notSalesAmount = jdbcTemplate.queryForObject(sql2,Long.class,name,0);

        return new FruitResponse(salesAmount,notSalesAmount);
    }
}



문제 2

분리된 코드 중 FruitRepository를 FruitMemoryRepository/FruitMySqlRepository로 나누고 @Primary 어노테이션을 활용하기


FruitRepository

package com.group.libraryapp.repository.hw;

import com.group.libraryapp.dto.hw.Fruit;
import com.group.libraryapp.dto.hw.FruitResponse;

public interface FruitRepository {

    void saveFruit(Fruit fruit);
    void sellFruit(long id);
    FruitResponse calcPrice(String name);
}

FruitMySqlRepository

package com.group.libraryapp.repository.hw;

import com.group.libraryapp.dto.hw.Fruit;
import com.group.libraryapp.dto.hw.FruitResponse;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

@Repository
@Primary
public class FruitMySqlRepository implements FruitRepository {

    private final JdbcTemplate jdbcTemplate;

    public FruitMySqlRepository(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public void saveFruit(Fruit fruit){
        String sql = "INSERT INTO fruit (name,warehousingDate,price) VALUES (?,?,?)";
        jdbcTemplate.update(sql,fruit.getName(),fruit.getWarehousingDate(),fruit.getPrice());
    }

    public void sellFruit(long id){
        String sql = "UPDATE fruit SET isSold=1 WHERE id=?";
        jdbcTemplate.update(sql,id);
    }

    public FruitResponse calcPrice(String name){
        String sql1 = "SELECT SUM(price) FROM fruit WHERE name=? AND isSold=?";
        String sql2 = "SELECT SUM(price) FROM fruit WHERE name=? AND isSold=?";

        long salesAmount = jdbcTemplate.queryForObject(sql1,Long.class,name,1);
        long notSalesAmount = jdbcTemplate.queryForObject(sql2,Long.class,name,0);

        return new FruitResponse(salesAmount,notSalesAmount);
    }
}

FruitMemoryRepository

package com.group.libraryapp.repository.hw;

import com.group.libraryapp.dto.hw.Fruit;
import com.group.libraryapp.dto.hw.FruitResponse;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;

@Repository
public class FruitMemoryRepository implements FruitRepository{
    private final List<Fruit> fruits = new ArrayList<>();
    @Override
    public void saveFruit(Fruit fruit) {
        fruits.add(fruit);
    }

    @Override
    public void sellFruit(long id) {
        Fruit fruit = fruits.get(id);
        if(fruit!= null){
            fruit.setSold(1);
        }
    }

    @Override
    public FruitResponse calcPrice(String name) {

        long num1 = fruits.stream().filter(f -> f.getName().equals(name) && f.isSold()).mapToLong(Fruit::getPrice).sum();
        long num2 = fruits.stream().filter(f -> f.getName().equals(name) && !f.isSold()).mapToLong(Fruit::getPrice).sum();

        return new FruitResponse(num1,num2);

    }
}





강의

자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지!

0개의 댓글