@@ -1,158 +1,89 @@
 package codesquad.qua;
 
-import codesquad.answer.Answer;
-import codesquad.answer.AnswerRepository;
-import codesquad.user.User;
-import codesquad.utils.SessionUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
+import codesquad.exception.QuestionDeleteException;
+import codesquad.exception.QuestionEditException;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Controller;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.ui.Model;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpSession;
-import java.util.NoSuchElementException;
 
 @Controller
+@RequiredArgsConstructor
+@Slf4j
 public class QuestionController {
 
-    private final Logger logger = LoggerFactory.getLogger(this.getClass());
-    @Autowired
-    QuestionRepository questionRepository;
-
-    @Autowired
-    AnswerRepository answerRepository;
+    private final QuestionService questionService;
 
     @GetMapping("/questions/form")
     public String createForm(HttpSession session) {
-        User user = SessionUtil.getUserBySession(session);
-
-        if (user == null) {
+        if (!questionService.setCreateForm(session)) {
             return "/login";
         }
 
         return "qna/form";
     }
 
     @PostMapping("/questions")
-    public String create(Question question, HttpSession session) {
-        User user = SessionUtil.getUserBySession(session);
-
-        if (user == null) {
+    public String createQuestion(QuestionDto questionDto, HttpSession session) {
+        if (!questionService.create(questionDto, session)) {
             return "/login";
         }
 
-        question.setWriter(user);
-        questionRepository.save(question);
-        logger.info("user : {}", question.getWriter().getName());
         return "redirect:/";
     }
 
     @GetMapping("/")
-    public String list(Model model) {
-        model.addAttribute("question", questionRepository.findAll());
+    public String showQuestionList(Model model) {
+        model.addAttribute("question", questionService.list());
         return "qna/list";
     }
 
     @GetMapping("/questions/{id}")
-    public String qnaInfo(Model model, @PathVariable("id") Long id) {
-        Question question = findQuestionById(id);
-        model.addAttribute("question", question);
-        model.addAttribute("count", countAnswers(question));
-
+    public String showQuestion(Model model, @PathVariable("id") Long id) {
+        model.addAttribute("question", questionService.findQuestionById(id));
+        model.addAttribute("count", questionService.countAnswers(id));
         return "qna/show";
     }
 
-    @Transactional
     @PutMapping("/questions/{id}")
-    public String update(Question changedQuestion, @PathVariable("id") Long id, HttpSession session) {
-        User user = SessionUtil.getUserBySession(session);
-        Question savedQuestion = findQuestionById(id);
-
-        if (user == null || !isQuestionMatchUser(user, savedQuestion)) {
+    public String updateQuestion(QuestionDto changedQuestion, @PathVariable("id") Long id, HttpSession session) {
+        try {
+            questionService.update(changedQuestion, id, session);
+        } catch (QuestionEditException showException) {
             return "qna/show_failed";
         }
 
-        logger.info("user: {}", user.getName());
-        logger.info("question: {}", savedQuestion.getWriter());
-
-        savedQuestion.update(changedQuestion);
-
         return "redirect:/";
     }
 
     @GetMapping("/questions/{id}/updateForm")
     public String updateForm(Model model, @PathVariable("id") Long id, HttpSession session) {
-        User user = SessionUtil.getUserBySession(session);
-        Question savedQuestion = findQuestionById(id);
-
-        if (user == null || !isQuestionMatchUser(user, savedQuestion)) {
+        try {
+            questionService.setUpdateForm(id, session);
+        } catch (QuestionEditException showException) {
             return "qna/show_failed";
         }
 
-        logger.info("user: {}", user.getName());
-        logger.info("question: {}", savedQuestion.getWriter());
-
-        model.addAttribute("question", savedQuestion);
+        model.addAttribute("question", questionService.findQuestionById(id));
 
         return "qna/updateForm";
     }
 
     @DeleteMapping("/questions/{id}")
-    @Transactional
-    public String remove(@PathVariable("id") Long id, HttpSession session) {
-        User user = SessionUtil.getUserBySession(session);
-        Question savedQuestion = findQuestionById(id);
-
-        logger.info("user: {}", user.getName());
-        logger.info("question: {}", savedQuestion.getWriter());
+    public String removeQuestion(@PathVariable("id") Long id, HttpSession session) {
 
-        if (user == null || !isQuestionMatchUser(user, savedQuestion)) {
+        try {
+            questionService.remove(id, session);
+        } catch (QuestionEditException showException) {
             return "qna/show_failed";
-        }
-
-        if (!canDeleteQuestion(savedQuestion, user)) {
+        } catch (QuestionDeleteException deleteException) {
             return "qna/delete_failed";
         }
 
-        savedQuestion.changeDeleteFlag();
-
-        for (Answer answer : savedQuestion.getAnswers()) {
-            answer.changeDeletedFlag();
-        }
-
         return "redirect:/questions/" + id;
     }
-
-    private Question findQuestionById(Long id) {
-        return questionRepository.findById(id)
-                                 .orElseThrow(NoSuchElementException::new);
-    }
-
-    private boolean isQuestionMatchUser(User loginUser, Question question) {
-        return question.equalsWriter(loginUser);
-    }
-
-    private boolean canDeleteQuestion(Question deletedQuestion, User user) {
-        if (deletedQuestion.hasAnswers()) {
-            for (Answer answer : deletedQuestion.getAnswers()) {
-                if (!answer.equalsWriter(user)) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
-
-    private int countAnswers(Question question) {
-        int count = 0;
-        for (Answer answer : question.getAnswers()) {
-            if (!answer.isDeletedFlag()) {
-                count++;
-            }
-        }
-        return count;
-    }
 }
\ No newline at end of file

리뷰: Question에 대한 Exception을 customizing 한 이유입니다

QuestionEditException은 해당 질문자가 아니기 때문에 삭제할 수 없는 경우,
QuestionDeleteException은 다른 User의 답글이 존재하여 삭제할 수 없는 경우입니다

처음에는 boolean으로 처리하려다가 두 가지 경우가 있게 되어(=두 가지 view)
exception을 만들었습니다