๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
  • ์žฅ์›์ต ๊ธฐ์ˆ ๋ธ”๋กœ๊ทธ
๐Ÿคท๐Ÿผ‍โ™€๏ธ Etc.../- ๊ธฐํƒ€

[๊ฐœ๋ฐœ์ž ์ฑ…์ฝ๊ธฐ] ํด๋ฆฐ ์ฝ”๋“œ - ์• ์ž์ผ ์†Œํ”„ํŠธ์›จ์–ด ์žฅ์ธ ์ •์‹  (1์žฅ ๊นจ๋—ํ•œ ์ฝ”๋“œ)

by Wonit 2022. 2. 2.

ํ•ด๋‹น ๊ธ€์€ Robert C.Martin ํด๋ฆฐ ์ฝ”๋“œ ๋ผ๋Š” ์ฑ…์„ ์ฝ๊ณ  ํ•™์Šตํ•œ ๋‚ด์šฉ์„ ์ •๋ฆฌ ๋ฐ ํšŒ๊ณ ํ•˜๋Š” ๊ธ€ ์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ์‚ฌํ•ญ์€ YES 24 ํด๋ฆฐ ์ฝ”๋“œ ์—์„œ ํ™•์ธํ•ด์ฃผ์„ธ์š”.

ํด๋ฆฐ ์ฝ”๋“œ - ์• ์ž์ผ ์†Œํ”„ํŠธ์›จ์–ด ์žฅ์ธ ์ •์‹  (Uncle Bob)

  • ์œ„ํ‚ค๋ถ์Šค
  • ์ง€์€์ด: Robert C.Martin (Uncle Bob)
  • ์˜ฎ๊ธด์ด: ๋ฐ•์žฌํ˜ธ, ์ดํ•ด์˜

 


 

์ด๋ฒˆ ์žฅ์—์„œ ์ด์•ผ๊ธฐํ•˜๊ณ ์ž ํ•˜๋Š” ๊ฒƒ

 

์ฝ”๋“œ๋Š” ์š”๊ตฌ์‚ฌํ•ญ์„ ์ƒ์„ธํ•˜๊ฒŒ ํ‘œํ˜„ํ•˜๋Š” ์ˆ˜๋‹จ.

  • ์šฐ๋ฆฌ์˜ ์ฝ”๋“œ์—์„œ ์š”๊ตฌ์‚ฌํ•ญ์„ ๋“œ๋Ÿฌ๋‚ด์•ผ ํ•œ๋‹ค.

 

๋‚˜์œ ์ฝ”๋“œ๋ž€?

  • ๋‚˜์œ ์ฝ”๋“œ๊ฐ€ ๋‚˜์˜ค๋Š” ์ด์œ 
    • ๋‹จ์ง€ ๋Œ์•„๊ฐ„๋‹ค๋Š” ์‚ฌ์‹ค์— ์•ˆ๋„ํ•จ
    • ์“ฐ๋ ˆ๊ธฐ ์ฝ”๋“œ๊ฐ€ ๋ณด์ด๋ฉด ๋‚˜์˜๋‹ค๋Š” ์‚ฌ์‹ค์„ ์ธ์ง€ํ•˜๊ณ  ์–ธ์  ๊ฐ„ ๊ณ ์น˜๋ฆฌ๋ผ ํ•˜๊ณ  ์ง€๋‚˜๊ฐ
  • ๋‚˜์œ ์ฝ”๋“œ๋Š” ๋‚˜์œ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ฒŒ ๋จ
    • ๋‚˜์œ ์ฝ”๋“œ๋Š” ์ผ์ •์„ ๋งž์ถ”๊ธฐ ์œ„ํ•ด ์ซ“๊ฒจ ๋‚˜์œ ์ฝ”๋“œ๋ฅผ ์–‘์‚ฐ
    • ๋ชจ๋“  ๊ฐœ๋ฐœ์ž๋Š” ๋‚˜์œ ์ฝ”๋“œ๊ฐ€ ํ•ด๊ฐ€ ๋œ๋‹ค๋Š” ๊ฒƒ์„ ์ธ์ง€ํ•˜๊ณ  ์žˆ์Œ
  • ๊ฒฐ๊ตญ ๋‚˜์œ ์ฝ”๋“œ๊ฐ€ ์ฆ๊ฐ€ํ•  ์ˆ˜๋ก ์ƒ์‚ฐ์„ฑ์ด ์ €ํ•˜๋จ
    • ๋‚˜์œ ์ฝ”๋“œ๋ฅผ ๊ณ ์น˜๊ธฐ ์œ„ํ•ด ๋‚˜์œ ์ฝ”๋“œ๋ฅผ ์ƒ์‚ฐ
    • ๊นจ์ง„ ์œ ๋ฆฌ์ฐฝ ์ด๋ก ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊นจ์ง„ ์œ ๋ฆฌ์ฐฝ์ด ๋” ๊นจ์ ธ๋„ ์‹ ๊ฒฝ์„ ์“ฐ์ง€ ์•Š์Œ

 

๊นจ๋—ํ•œ ์ฝ”๋“œ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ํƒœ๋„๋Š”?

 

  • ์ผ์ • ํ•‘๊ณ„, ๋น„๊ฐœ๋ฐœ ํŒ€์˜ ์••๋ฐ• ํ•‘๊ณ„ ๋Œ€์ง€ ๋ง ๊ฒƒ
    • ์ผ์ • ์กฐ์œจ์„ ์‹คํŒจํ•œ ๊ฒƒ๋„ ๋‚˜์œ ์ฝ”๋“œ๋ฅผ ์ƒ์‚ฐํ•˜๋Š” ๊ทผ๋ณธ์  ์›์ธ์ด ๋จ.
    • ๊ฒฐ๊ตญ ์ข‹์€ ์ฝ”๋“œ๋ฅผ ์‚ฌ์ˆ˜ํ•˜๋Š” ๊ฒƒ ์—ญ์ง€ ์šฐ๋ฆฌ ๊ฐœ๋ฐœ์ž์˜ ๋ชซ
      • ์ผ์ •์€ ๋ถˆ๊ฐ€ํ•ญ๋ ฅ์ด๋ผ ์ƒ๊ฐํ–ˆ์—ˆ๋Š”๋ฐ ์ƒ๊ฐํ•ด๋ณด๋‹ˆ ์ด ์—ญ์‹œ ๋‚˜์˜ ๊ฒฐ์ •
    • ์ „๋ฌธ์„ฑ์„ ๊ฐ€์งˆ ๊ฒƒ

 

๊นจ๋—ํ•œ ์ฝ”๋“œ๋Š”?

 

  • ์ข‹์€ ๊ฐœ๋ฐœ์ž๋“ค์ด ์ •์˜ํ•œ ๊นจ๋—ํ•œ ์ฝ”๋“œ
    • ํ•œ ๋ฒˆ์— ํ•œ ๊ฐ€์ง€์— ์ง‘์ค‘ํ•œ๋‹ค.
    • ํ•œ ๊ฐ€์ง€๋ฅผ ์ œ๋Œ€๋กœ ํ•œ๋‹ค.
    • ๋…ผ๋ฆฌ๊ฐ€ ๊ฐ„๋‹จํ•ด์•ผ ๋ฒ„๊ทธ๊ฐ€ ์ˆจ์–ด ๋“ค์ง€ ๋ชปํ•œ๋‹ค.
    • ์„ค๊ณ„์ž์˜ ์˜๋„๋ฅผ ์ˆจ๊ธฐ์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค.
    • ํ•˜๋‚˜๋งŒ ์ œ๊ณตํ•œ๋‹ค.
    • ๋ฌธํ•™์  ์ด์–ด์•ผ ํ•œ๋‹ค.
    • ๋‹จ์ˆœ ๋ช…๋ฃŒํ•ด์•ผ ํ•œ๋‹ค.

 

์šฐ๋ฆฌ๋Š” ์ €์ž๋‹ค.

 

  • ์šฐ๋ฆฌ๋Š” ์ฝ”๋“œ๋ฅผ ์งœ๊ณ  ๋ˆ„๊ตฐ๊ฐ€๋Š” ์ฝ”๋“œ๋ฅผ ์ฝ์„ ๊ฒƒ์ด๋‹ค.
  • ๋…์ž์™€ ์ž˜ ์†Œํ†ตํ•˜๋Š” ๊ฒƒ ์—ญ์‹œ ์šฐ๋ฆฌ์˜ ์ฑ…์ž„์ด๋‹ค.

 


๋‚˜์˜ ํ•ด์„๊ณผ ํšŒ๊ณ 

 

๋‚˜ ์Šค์Šค๋กœ๊ฐ€ ํด๋ฆฐํ•œ ์ฝ”๋“œ๋ฅผ ์งœ๋‚ด๊ธฐ ์œ„ํ•ด์„œ ๋งŽ์€ ๋…ธ๋ ฅ์„ ํ•˜๊ณ  ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

 

1์žฅ์„ ์ฐฌ์ฐฌํžˆ ์ฝ๊ณ  ๋’ค๋ฅผ ๋Œ์ด์ผœ๋ณด๋ฉด ํด๋ฆฐํ•œ ์ฒ™ํ•˜๋ ค ๋…ธ๋ ฅํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋งŽ์ด ์งฐ๋˜๊ฒƒ ๊ฐ™๋‹ค.

 

๋’ค์— ์ฃผ์„๊ณผ ๊ด€๋ จ๋œ ์ด์•ผ๊ธฐ๊ฐ€ ๋‚˜์˜ค์ง€๋งŒ ์˜๋ฏธ์—†๋Š” ์ฃผ์„๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด์„œ ๊ฐ€์žฅ ํฐ ๊ฒƒ์€ ํ•œ ๋ฒˆ์— ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ผ์„ ํ•˜๋ ค๋Š” ๊ฒฝํ–ฅ์ด ์ฝ”๋“œ ๊ณณ๊ณณ์— ์ˆจ์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•œ ๊ฐ€์ง€๋ฅผ ๋ช…ํ™•ํžˆ ํ•˜์ง€ ๋ชปํ–ˆ๋˜๊ฒƒ ๊ฐ™๋‹ค.

 

์–ธ์  ๊ฐ„ ๊ณ ์น˜๋ฆฌ๋ผ

 

 

์œ„์˜ ์ฝ”๋“œ๋Š” ์ž˜ ๋Œ์•„๊ฐ„๋‹ค๋Š” ์•ˆ๋„๊ฐ์œผ๋กœ ์ธํ•ด์„œ ์–ธ์  ๊ฐ„ ๊ณ ์น˜๋ฆฌ๋ผ ํ•˜๋ฉฐ ์ ˆ๋Œ€ ๊ณ ์น˜์ง€ ์•Š์•˜๋˜ ๋‚˜์˜ ๊ณผ๊ฑฐ๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค..

 

ํ•œ ๋ฒˆ์— ์—ฌ๋Ÿฌ๊ฐ€์ง€๋ฅผ ๊ทธ๋ƒฅ ํ•œ๋‹ค.

 

/**
 * ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋ฌธ์ œ์˜ ์ •๋‹ต์„ ์ €์žฅํ•œ๋‹ค.
 *
 * @param userId : ์š”์ฒญ์„ ๋ณด๋‚ธ ์‚ฌ์šฉ์ž์˜ userId
 * @param quizId : ์š”์ฒญ์— ํฌํ•จ๋œ ํ€ด์ฆˆ์˜ quizId
 * @param request : ์‚ฌ์šฉ์ž์˜ ์ •๋‹ต ๋ฐ์ดํ„ฐ
 * @param tokenUserId : ์š”์ฒญ์„ ๋ณด๋‚ธ ์‚ฌ์šฉ์ž์˜ userId
 */
public void solveEvaluationQuiz(Long userId,
                                Long evaluationId,
                                Long quizId,
                                SolveQuizRequestData request,
                                Long tokenUserId) {
    if(!userId.equals(tokenUserId)) { // ์ œ์ถœํ•˜๋Š” userId ์™€ ์ €์žฅํ•˜๋ ค๋Š” userId ๊ฐ€ ๋‹ค๋ฅธ ๊ฒฝ์šฐ
        throw new AuthenticationFailedException();
    }

    boolean isMember = evaluationUserRepository.existsByEvaluationIdAndUserId(evaluationId, userId);

    if(!isMember) {
        throw new AuthenticationFailedException();
    }

    boolean evaluationExist = evaluationRepository.existsById(evaluationId);

    if(!evaluationExist) {
        throw new NotFoundException("ํ…Œ์ŠคํŠธ " + evaluationId);
    }

    User user = userRepository.findById(tokenUserId).orElseThrow(
            () -> new NotFoundException("์‚ฌ์šฉ์ž ๋ฒˆํ˜ธ " + tokenUserId));
    EvaluationQuiz evaluationQuiz = evaluationQuizRepository.findById(quizId).orElseThrow(
            () -> new NotFoundException("ํ€ด์ฆˆ ๋ฒˆํ˜ธ " + quizId));

    Optional<QuizSubmit> submit = quizSubmitRepository.findByQuizIdAndUserId(quizId, userId);

    String answer = request.getAnswer();
    QuizSubmit quizSubmit;
    if(submit.isEmpty()) { // ๊ธฐ์กด์— ์ œ์ถœํ•œ ์ •๋‹ต์ด ์—†๋‹ค๋ฉด ์ƒˆ๋กญ๊ฒŒ Submit ์„ ์ œ์ถœ
         quizSubmit = QuizSubmit.builder()
                .answer(answer)
                .evaluationQuiz(evaluationQuiz)
                .user(user)
                .build();
    } else { // ๊ธฐ์กด์— ์ œ์ถœํ•œ ์ •๋‹ต์ด ์žˆ๋‹ค๋ฉด ๊ทธ ์ •๋‹ต์„ ์—…๋ฐ์ดํŠธ
        quizSubmit = submit.get();
        quizSubmit.updateAnswer(answer);
    }

    quizSubmitRepository.save(quizSubmit);
}

 

์ด๋Š” ์ด์ „์— ํ–ˆ๋˜ ํ”„๋กœ์ ํŠธ์˜ ์„œ๋น„์Šค ์ฝ”๋“œ๋ฅผ ์ž ์‹œ ๊ฐ€์ ธ์˜จ ๊ฒƒ์ด๋‹ค.

 

solveEvaluationQuiz ๋ผ๋Š” ๋ฉ”์„œ๋“œ๋Š” ๋„๋Œ€์ฒด๊ฐ€ ๋ฌด์Šจ ์ผ์„ ํ•˜๋ ค๋Š” ๊ฒƒ์ธ์ง€ ์•Œ ์ˆ˜ ์—†์–ด๋ณด์ธ๋‹ค.

 

ํ•œ ๋ฒˆ์— ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ผ์„ ํ•˜๋ ค๊ณ  ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์งˆ์ ์ธ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ๊ฐ์ถ”์–ด์ ธ ์žˆ์—ˆ๋‹ค.

 

์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ์ฝ”๋“œ์˜ 2/3 ์ด validation ํ•˜๋Š”๋ฐ ์ง„ํ–‰๋˜๊ณ  ์žˆ๊ณ  ์‹ค์งˆ์ ์ธ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์€ ์ œ์ผ ์•„๋ž˜์— 6 ~ 8 ์ค„ ๋ฟ์ด ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

๋Œ“๊ธ€