ewhk9887/korean_code_reviews_from_github huggingface dataset:
@@ -0,0 +1,85 @@
+package christmas.domain;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public class EventResult {
+    private static final String NON_BADGE = "없음";
+    private static final String STAR_BADGE = "별";
+    private static final String TREE_BADGE = "트리";
+    private static final String SANTA_BADGE = "산타";
+    private static final int STAR_BADGE_MINIMUM_AMOUNT = 5000;
+    private static final int STAR_BADGE_MAXIMUM_AMOUNT = 10000;
+    private static final int TREE_BADGE_MINIMUM_AMOUNT = 10000;
+    private static final int TREE_BADGE_MAXIMUM_AMOUNT = 20000;
+    private static final int SANTA_BADGE_MINIMUM_AMOUNT = 20000;
+
+    private final Map<BenefitType, Integer> allBenefit;
+
+    public EventResult(Map<BenefitType, Integer> allBenefit) {
+        this.allBenefit = allBenefit;
+    }
+
+    public int calculateTotalBenefitAmount() {
+        int totalBenefitAmount = 0;
+        List<BenefitType> benefitTypes = List.of(BenefitType.values());
+
+        for (BenefitType benefitType : benefitTypes) {
+            totalBenefitAmount += allBenefit.get(benefitType);
+        }
+
+        return totalBenefitAmount;
+    }
+
+    public int calculateTotalDiscountAmount() {
+        int totalDiscountAmount = 0;
+        List<BenefitType> benefitTypes = List.of(BenefitType.values());
+
+        for (BenefitType benefitType : benefitTypes) {
+            totalDiscountAmount += allBenefit.get(benefitType);
+        }
+        if (allBenefit.get(BenefitType.GIFT) == Menu.CHAMPAGNE.getPrice()) {
+            totalDiscountAmount -= Menu.CHAMPAGNE.getPrice();
+        }
+
+        return totalDiscountAmount;
+    }
+
+    public boolean isReceivedGiftBenefit() {
+        return allBenefit.get(BenefitType.GIFT) == Menu.CHAMPAGNE.getPrice();
+    }
+
+    public List<BenefitType> checkWhichBenefitExist() {
+        List<BenefitType> existingBenefit = new ArrayList<>();
+        BenefitType[] benefitTypes = BenefitType.values();
+
+        for (BenefitType benefitType : benefitTypes) {
+            if (allBenefit.get(benefitType) != 0) {
+                existingBenefit.add(benefitType);
+            }
+        }
+
+        return existingBenefit;
+    }
+
+    public String decideEventBadge() {
+        int totalBenefitAmount = calculateTotalBenefitAmount();
+
+        if ((totalBenefitAmount >= STAR_BADGE_MINIMUM_AMOUNT) && (totalBenefitAmount < STAR_BADGE_MAXIMUM_AMOUNT)) {
+            return STAR_BADGE;
+        }
+        if ((totalBenefitAmount >= TREE_BADGE_MINIMUM_AMOUNT) && (totalBenefitAmount < TREE_BADGE_MAXIMUM_AMOUNT)) {
+            return TREE_BADGE;
+        }
+        if ((totalBenefitAmount >= SANTA_BADGE_MINIMUM_AMOUNT)) {
+            return SANTA_BADGE;
+        }
+        return NON_BADGE;
+    }
+
+    public Map<BenefitType, Integer> getAllBenefit() {
+        return Collections.unmodifiableMap(allBenefit);
+    }
+}
\ No newline at end of file

리뷰: 이 if문의 조건도 isReceivedGiftBenefit 메서드를 사용해도 되겠네요!
@@ -0,0 +1,76 @@
+package christmas.domain;
+
+import static christmas.domain.OrderedMenu.ORDER_RE_READ_REQUEST_MESSAGE;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class Order {
+    private static final int MAXIMUM_MENU_QUANTITY = 20;
+
+    private final List<OrderedMenu> order;
+
+    public Order(List<OrderedMenu> order) {
+        validateOrderedMenuNamesNotAllBeverage(order);
+        validateOrderedMenuNamesNotDuplicate(order);
+        validateTotalOrderedMenuQuantity(order);
+
+        this.order = order;
+    }
+
+    private void validateOrderedMenuNamesNotAllBeverage(List<OrderedMenu> order) {
+        List<Boolean> beverageChecker = new ArrayList<>();
+
+        for (OrderedMenu orderedMenu : order) {
+            if (orderedMenu.isBeverage()) {
+                beverageChecker.add(true);
+            }
+            if (!orderedMenu.isBeverage()) {
+                beverageChecker.add(false);
+            }
+        }
+
+        if (!beverageChecker.contains(false)) {
+            throw new IllegalArgumentException(ORDER_RE_READ_REQUEST_MESSAGE);
+        }
+    }
+
+    private void validateOrderedMenuNamesNotDuplicate(List<OrderedMenu> order) {
+        Set<String> duplicateChecker = new HashSet<>();
+
+        for (OrderedMenu orderedMenu : order) {
+            duplicateChecker.add(orderedMenu.getMenuName());
+        }
+        if (duplicateChecker.size() != order.size()) {
+            throw new IllegalArgumentException(ORDER_RE_READ_REQUEST_MESSAGE);
+        }
+    }
+
+    private void validateTotalOrderedMenuQuantity(List<OrderedMenu> order) {
+        int totalQuantity = 0;
+
+        for (OrderedMenu orderedMenu : order) {
+            totalQuantity += orderedMenu.getQuantity();
+        }
+        if (totalQuantity > MAXIMUM_MENU_QUANTITY) {
+            throw new IllegalArgumentException(ORDER_RE_READ_REQUEST_MESSAGE);
+        }
+    }
+
+    public int calculateTotalOrderPrice() {
+        int totalOrderPrice = 0;
+
+        for (OrderedMenu orderedMenu : order) {
+            totalOrderPrice += orderedMenu.calculatePrice();
+        }
+
+        return totalOrderPrice;
+    }
+
+    public List<OrderedMenu> getOrder() {
+        return Collections.unmodifiableList(order);
+    }
+}
\ No newline at end of file

리뷰: 메서드명이 길어도 확실히 이름만 보고도 어떤 역할을 하는지 바로 알 수 있어서 좋은 것 같습니다!
@@ -0,0 +1,21 @@
+package nextstep.subway;
+
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+@RestControllerAdvice
+public class ControllerExceptionHandler {
+
+    @ExceptionHandler(DataIntegrityViolationException.class)
+    public ResponseEntity handleIllegalArgsException(DataIntegrityViolationException e) {
+        return ResponseEntity.badRequest().build();
+    }
+
+    @ExceptionHandler(IllegalArgumentException.class)
+    public ResponseEntity handleIllegalArgumentException(IllegalArgumentException illegalArgumentException){
+        String message = illegalArgumentException.getMessage();
+        return ResponseEntity.badRequest().body(message);
+    }
+}

리뷰: @RestControllerAdvice 를 사용하여 모든 에러를 한군데서 처리해줄 수 있게해준 부분 좋습니다 👍
@@ -0,0 +1,21 @@
+package nextstep.subway;
+
+import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+@RestControllerAdvice
+public class ControllerExceptionHandler {
+
+    @ExceptionHandler(DataIntegrityViolationException.class)
+    public ResponseEntity handleIllegalArgsException(DataIntegrityViolationException e) {
+        return ResponseEntity.badRequest().build();
+    }
+
+    @ExceptionHandler(IllegalArgumentException.class)
+    public ResponseEntity handleIllegalArgumentException(IllegalArgumentException illegalArgumentException){
+        String message = illegalArgumentException.getMessage();
+        return ResponseEntity.badRequest().body(message);
+    }
+}

리뷰: 이 부분은 조금 궁금하여 여쭤봅니다! DataIntegrityViolationException 는 현재 어플리케이션 내에서 언제, 어떤 케이스에서 발생하게 되나요...?
@@ -0,0 +1,38 @@
+package nextstep.subway.line.domain;
+
+import java.util.ArrayList;
+import java.util.List;
+import nextstep.subway.station.domain.Station;
+import org.jgrapht.GraphPath;
+import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
+import org.jgrapht.graph.DefaultWeightedEdge;
+import org.jgrapht.graph.WeightedMultigraph;
+
+public class Lines {
+
+    List<Line> lines = new ArrayList<>();
+
+    public Lines(List<Line> lines) {
+        this.lines = lines;
+    }
+
+    public GraphPath minPath(Station sourceStation, Station targetStation) {
+
+        validatePath(sourceStation, targetStation);
+        WeightedMultigraph<Station, DefaultWeightedEdge> graph = new WeightedMultigraph(DefaultWeightedEdge.class);
+
+        for (Line line : lines) {
+            line.addPathInfo(graph);
+        }
+
+        DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(graph);
+
+        return dijkstraShortestPath.getPath(sourceStation, targetStation);
+    }
+
+    private void validatePath(Station sourceStation, Station targetStation){
+        if(sourceStation.equals(targetStation)){
+            throw new IllegalArgumentException("경로 시작역과 도착역이 일치합니다.");
+        }
+    }
+}

리뷰: 접근제한자가 없는 것 같습니다!
@@ -0,0 +1,38 @@
+package nextstep.subway.line.domain;
+
+import java.util.ArrayList;
+import java.util.List;
+import nextstep.subway.station.domain.Station;
+import org.jgrapht.GraphPath;
+import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
+import org.jgrapht.graph.DefaultWeightedEdge;
+import org.jgrapht.graph.WeightedMultigraph;
+
+public class Lines {
+
+    List<Line> lines = new ArrayList<>();
+
+    public Lines(List<Line> lines) {
+        this.lines = lines;
+    }
+
+    public GraphPath minPath(Station sourceStation, Station targetStation) {
+
+        validatePath(sourceStation, targetStation);
+        WeightedMultigraph<Station, DefaultWeightedEdge> graph = new WeightedMultigraph(DefaultWeightedEdge.class);
+
+        for (Line line : lines) {
+            line.addPathInfo(graph);
+        }
+
+        DijkstraShortestPath dijkstraShortestPath = new DijkstraShortestPath(graph);
+
+        return dijkstraShortestPath.getPath(sourceStation, targetStation);
+    }
+
+    private void validatePath(Station sourceStation, Station targetStation){
+        if(sourceStation.equals(targetStation)){
+            throw new IllegalArgumentException("경로 시작역과 도착역이 일치합니다.");
+        }
+    }
+}

리뷰: 동사구로 메서드를 표현해보는 것은 어떨까요...? 그리고 혹시 제너릭을 안쓰시는 이유가 있으실까요...?
@@ -0,0 +1,38 @@
+package nextstep.subway.path.application;
+
+import nextstep.subway.station.exception.StationNotFoundException;
+import nextstep.subway.line.domain.LineRepository;
+import nextstep.subway.line.domain.Lines;
+import nextstep.subway.path.dto.PathResponse;
+import nextstep.subway.station.domain.Station;
+import nextstep.subway.station.domain.StationRepository;
+import org.jgrapht.GraphPath;
+import org.springframework.stereotype.Service;
+
+@Service
+public class PathService {
+
+    private final StationRepository stationRepository;
+    private final LineRepository lineRepository;
+
+    public PathService(StationRepository stationRepository, LineRepository lineRepository) {
+        this.stationRepository = stationRepository;
+        this.lineRepository = lineRepository;
+    }
+
+    public PathResponse minPath(Long sourceStationId, Long targetStationId) {
+        System.out.println("PathService.minPath");
+
+        Station sourceStation = stationRepository.findById(sourceStationId)
+                .orElseThrow(() -> new StationNotFoundException("경로 시작역이 존재하지 않습니다."));
+        Station targetStation = stationRepository.findById(targetStationId)
+                .orElseThrow(() -> new StationNotFoundException("경로 도착역이 존재하지 않습니다."));
+
+        Lines lines = new Lines(lineRepository.findAll());
+        GraphPath graphPath = lines.minPath(sourceStation, targetStation);
+
+        PathResponse pathResponse = new PathResponse(graphPath.getVertexList(), (int) graphPath.getWeight());
+
+        return pathResponse;
+    }
+}

리뷰: 여기에 혹시 System 함수를 쓰신 이유가 있을까요...? Sysytem 함수는 리소스를 많이 먹어서 최대한 사용하지 않는 것이 좋습니다.
@@ -0,0 +1,38 @@
+package nextstep.subway.path.application;
+
+import nextstep.subway.station.exception.StationNotFoundException;
+import nextstep.subway.line.domain.LineRepository;
+import nextstep.subway.line.domain.Lines;
+import nextstep.subway.path.dto.PathResponse;
+import nextstep.subway.station.domain.Station;
+import nextstep.subway.station.domain.StationRepository;
+import org.jgrapht.GraphPath;
+import org.springframework.stereotype.Service;
+
+@Service
+public class PathService {
+
+    private final StationRepository stationRepository;
+    private final LineRepository lineRepository;
+
+    public PathService(StationRepository stationRepository, LineRepository lineRepository) {
+        this.stationRepository = stationRepository;
+        this.lineRepository = lineRepository;
+    }
+
+    public PathResponse minPath(Long sourceStationId, Long targetStationId) {
+        System.out.println("PathService.minPath");
+
+        Station sourceStation = stationRepository.findById(sourceStationId)
+                .orElseThrow(() -> new StationNotFoundException("경로 시작역이 존재하지 않습니다."));
+        Station targetStation = stationRepository.findById(targetStationId)
+                .orElseThrow(() -> new StationNotFoundException("경로 도착역이 존재하지 않습니다."));
+
+        Lines lines = new Lines(lineRepository.findAll());
+        GraphPath graphPath = lines.minPath(sourceStation, targetStation);
+
+        PathResponse pathResponse = new PathResponse(graphPath.getVertexList(), (int) graphPath.getWeight());
+
+        return pathResponse;
+    }
+}

리뷰: Repository 조회하는 부분이 있는데 readOnly 옵션을 주는 것은 어떨까요....?
@@ -0,0 +1,50 @@
+package nextstep.subway.applicaion;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import nextstep.member.application.MemberService;
+import nextstep.member.domain.LoginMember;
+import nextstep.member.domain.MemberRepository;
+import nextstep.subway.applicaion.dto.FavoriteRequest;
+import nextstep.subway.applicaion.dto.FavoriteResponse;
+import nextstep.subway.domain.Favorite;
+import nextstep.subway.domain.FavoriteRepository;
+import nextstep.subway.domain.Station;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+public class FavoriteService {
+    private final StationService stationService;
+    private final PathService pathService;
+    private final MemberRepository memberRepository;
+    private final FavoriteRepository favoriteRepository;
+
+    public FavoriteService(StationService stationService, PathService pathService,
+        MemberRepository memberRepository, FavoriteRepository favoriteRepository) {
+        this.stationService = stationService;
+        this.pathService = pathService;
+        this.memberRepository = memberRepository;
+        this.favoriteRepository = favoriteRepository;
+    }
+
+    public FavoriteResponse createFavorite(FavoriteRequest favoriteRequest, Long memberId) {
+        Station source = stationService.findById(favoriteRequest.getSource());
+        Station target = stationService.findById(favoriteRequest.getTarget());
+        pathService.findPath(source, target);
+        Favorite favorite = favoriteRepository.save(Favorite.of(memberId, source, target));
+        return FavoriteResponse.from(favorite);
+    }
+
+    @Transactional(readOnly = true)
+    public List<FavoriteResponse> findFavorites(Long memberId) {
+        List<Favorite> favorites = favoriteRepository.findAllByMemberId(memberId);
+        return favorites.stream().map(FavoriteResponse::from).collect(Collectors.toList());
+    }
+
+    public void deleteFavorite(Long favoriteId, Long memberId) {
+        Favorite favorite = favoriteRepository.getById(favoriteId);
+        favorite.hasPermission(memberId);
+        favoriteRepository.delete(favorite);
+    }
+}

리뷰: memberRepository 를 사용하고 있지 않는데요,
즐겨찾기 생성, 조회, 삭제 시 유요한 memberId 인지 확인하지 않아도 될까요? 😄
@@ -22,10 +22,14 @@ public PathService(LineService lineService, StationService stationService) {
     public PathResponse findPath(Long source, Long target) {
         Station upStation = stationService.findById(source);
         Station downStation = stationService.findById(target);
-        List<Line> lines = lineService.findLines();
-        SubwayMap subwayMap = new SubwayMap(lines);
-        Path path = subwayMap.findPath(upStation, downStation);
+        Path path = findPath(upStation, downStation);
 
         return PathResponse.of(path);
     }
+
+    Path findPath(Station upStation, Station downStation) {
+        List<Line> lines = lineService.findLines();
+        SubwayMap subwayMap = new SubwayMap(lines);
+        return subwayMap.findPath(upStation, downStation);
+    }
 }

리뷰: 접근제어자를 생략하신 이유가 있으신가요? 😄
@@ -0,0 +1,39 @@
+package nextstep.subway.applicaion.dto;
+
+import nextstep.subway.domain.Favorite;
+
+public class FavoriteResponse {
+    private Long id;
+    private Long memberId;
+    private StationResponse source;
+    private StationResponse target;
+
+    private FavoriteResponse(Long id, Long memberId,
+        StationResponse source, StationResponse target) {
+        this.id = id;
+        this.memberId = memberId;
+        this.source = source;
+        this.target = target;
+    }
+
+    public static FavoriteResponse from(Favorite favorite) {
+        return new FavoriteResponse(favorite.getId(), favorite.getMemberId(),
+            StationResponse.of(favorite.getSource()), StationResponse.of(favorite.getTarget()));
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public Long getMemberId() {
+        return memberId;
+    }
+
+    public StationResponse getSource() {
+        return source;
+    }
+
+    public StationResponse getTarget() {
+        return target;
+    }
+}

리뷰: 요구사항에 memberId 는 없네요!
요구사항을 확인해주세요 😄
@@ -0,0 +1,49 @@
+package nextstep.subway.ui;
+
+import java.net.URI;
+import java.util.List;
+import nextstep.auth.authorization.AuthenticationPrincipal;
+import nextstep.member.domain.LoginMember;
+import nextstep.subway.applicaion.FavoriteService;
+import nextstep.subway.applicaion.dto.FavoriteRequest;
+import nextstep.subway.applicaion.dto.FavoriteResponse;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/favorites")
+public class FavoriteController {
+
+    private final FavoriteService favoriteService;
+
+    public FavoriteController(FavoriteService favoriteService) {
+        this.favoriteService = favoriteService;
+    }
+
+    @PostMapping
+    public ResponseEntity<FavoriteResponse> createFavorite(
+        @AuthenticationPrincipal LoginMember loginMember,
+        @RequestBody FavoriteRequest favoriteRequest) {
+        FavoriteResponse favoriteResponse = favoriteService.createFavorite(favoriteRequest, loginMember.getId());
+        return ResponseEntity.created(URI.create("/favorites/" + favoriteResponse.getId())).body(favoriteResponse);
+    }
+
+    @GetMapping
+    public ResponseEntity<List<FavoriteResponse>> getFavorites(@AuthenticationPrincipal LoginMember loginMember) {
+        List<FavoriteResponse> favoriteResponses = favoriteService.findFavorites(loginMember.getId());
+        return ResponseEntity.ok(favoriteResponses);
+    }
+
+    @DeleteMapping("/{favoriteId}")
+    public ResponseEntity<Void> deleteFavorite(@AuthenticationPrincipal LoginMember loginMember, @PathVariable Long favoriteId) {
+        favoriteService.deleteFavorite(favoriteId, loginMember.getId());
+        return ResponseEntity.noContent().build();
+    }
+
+}

리뷰: 즐겨찾기 생성 후 반환값에 대한 요구사항을 확인해주세요! 😄 
![스크린샷 2022-02-22 오후 7 58 34](https://user-images.githubusercontent.com/48339310/155118827-d664b3b1-32e7-4255-a58c-e5d09ce3550d.png)
@@ -1,5 +1,6 @@
 package nextstep.subway.domain;
 
+import java.util.Optional;
 import org.jgrapht.GraphPath;
 import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
 import org.jgrapht.graph.SimpleDirectedWeightedGraph;
@@ -22,6 +23,11 @@ public Path findPath(Station source, Station target) {
         DijkstraShortestPath<Station, SectionEdge> dijkstraShortestPath = new DijkstraShortestPath<>(graph);
         GraphPath<Station, SectionEdge> result = dijkstraShortestPath.getPath(source, target);
 
+        Optional.ofNullable(result)
+            .orElseThrow(() -> {
+                throw new IllegalArgumentException("출발역과 도착역이 연결되어 있지 않습니다.");
+            });
+
         List<Section> sections = result.getEdgeList().stream()
                 .map(it -> it.getSection())
                 .collect(Collectors.toList());

리뷰: Optional 을 사용하신 이유가 있으신가요?
어떠한 이점이 있나요? 😄 
```suggestion
        if (Objects.isNull(result)) {
            throw new IllegalArgumentException("출발역과 도착역이 연결되어 있지 않습니다.");
        }
```
@@ -0,0 +1,22 @@
+package codesquad.dto.question;
+
+import lombok.*;
+
+@AllArgsConstructor
+@Getter
+@Setter
+@Builder
+public class QuestionRequestDto {
+    private String writer;
+    private String title;
+    private String contents;
+
+    @Override
+    public String toString() {
+        return "QuestionDto{" +
+                "writer='" + writer + '\'' +
+                ", title='" + title + '\'' +
+                ", contents='" + contents + '\'' +
+                '}';
+    }
+}

리뷰: 기본 생성자를 생성해주신 이유가 있을까요?
@@ -1,22 +1,36 @@
 package codesquad;
 
-import codesquad.repository.ArrayUserRepository;
+import codesquad.repository.QuestionRepositoryImpl;
+import codesquad.repository.UserRepositoryImpl;
+import codesquad.repository.QuestionRepository;
 import codesquad.repository.UserRepository;
+import codesquad.service.QuestionService;
+import codesquad.service.QuestionServiceImpl;
 import codesquad.service.UserService;
 import codesquad.service.UserServiceImpl;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
 @Configuration
 public class AppConfig {
-
+    
     @Bean
     public UserService userService() {
         return new UserServiceImpl(userRepository());
     }
 
     @Bean
     public UserRepository userRepository() {
-        return new ArrayUserRepository();
+        return new UserRepositoryImpl();
+    }
+
+    @Bean
+    public QuestionService questionService() {
+        return new QuestionServiceImpl(questionRepository());
+    }
+
+    @Bean
+    public QuestionRepository questionRepository() {
+        return new QuestionRepositoryImpl();
     }
 }

리뷰: 컨트롤러는 @Controller 어노테이션을 이용해 빈을 등록하고 계시는데, Service와 Repository는 Config 파일에서 빈을 따로 등록해주고 계시는 이유가 궁금합니다!
@@ -7,6 +7,8 @@
 public interface UserRepository {
     void register(UserEntity userEntity);
 
+    void update(String userId, UserEntity userEntity);
+
     UserEntity findById(String userId);
 
     List<UserEntity> findAll();

리뷰: update()는 dto를 넘겨주고 있는데, register()는 엔티티를 넘겨주는 이유가 궁금합니다!
@@ -0,0 +1,30 @@
+package codesquad.service;
+
+import codesquad.entity.QuestionEntity;
+import codesquad.repository.QuestionRepository;
+
+import java.util.List;
+
+public class QuestionServiceImpl implements QuestionService {
+    private final QuestionRepository questionRepository;
+
+    public QuestionServiceImpl(QuestionRepository questionRepository) {
+        this.questionRepository = questionRepository;
+    }
+
+    @Override
+    public void postQuestion(QuestionEntity questionEntity) {
+        questionRepository.post(questionEntity);
+        questionRepository.setBaseTime(questionEntity);
+    }
+
+    @Override
+    public List<QuestionEntity> findQuestions() {
+        return questionRepository.findAll();
+    }
+
+    @Override
+    public QuestionEntity findQuestion(String id) {
+        return questionRepository.findAll().get(Integer.parseInt(id) - 1);
+    }
+}

리뷰: 엔티티를 이용해 데이터를 주고 받으면 어떤 문제가 있을지 고민해보시면 좋을 것 같습니다!