Skip to content

julie-min/campus-moneybug

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

32 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ’ฐ๊ฐ€๊ณ„๋ถ€ ์ปค๋ฎค๋‹ˆํ‹ฐ ์›น์‚ฌ์ดํŠธ MoneyBug

๐Ÿงญ ๋ชฉ์ฐจ


๐ŸšฉIntroduction

  • MoneyBug๋Š” ์†Œ์…œ์—์„œ ์œ ํ–‰ํ•˜๋Š” ๊ฑฐ์ง€๋ฐฉ์— ์˜๊ฐ์„ ๋ฐ›์•„ ๋งŒ๋“ค์–ด์ง„ ์ปค๋ฎค๋‹ˆํ‹ฐํ˜• ๊ฐ€๊ณ„๋ถ€ ์›น์‚ฌ์ดํŠธ์ž…๋‹ˆ๋‹ค.
  • ์œ ์ €์˜ ์ˆ˜์ž…๊ณผ ์ง€์ถœ์„ ์ž…๋ ฅํ•˜๋Š” ๊ฐ€๊ณ„๋ถ€ ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ์ค‘์‹ฌ์œผ๋กœ
  • ์ €๋ ดํ•œ ๋Œ€๋Ÿ‰ ํ• ์ธ์ œํ’ˆ๊ณผ ์ด๋ฒคํŠธ ์ œํ’ˆ์„ ํŒ๋งคํ•˜์—ฌ ์ˆ˜์ต์„ฑ์„ ๋„๋ชจํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • ์„œ๋กœ์˜ ์ง€์ถœ ๋‚ด์šฉ์— ๋Œ€ํ•ด ํ•จ๊ป˜ ๊ณ ๋ฏผํ•˜๊ณ , ๊ณต์œ ํ•˜๋ฉฐ ๊ฒŒ์‹œ๊ธ€์„ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • 13ํšŒ์ฐจ Java ๋ถ€ํŠธ์บ ํ”„ ํŒŒ์ด๋„ ์ตœ์šฐ์ˆ˜์ƒ์„ ์ˆ˜์ƒํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • ์ด ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋Š” ํŒ€ํ”„๋กœ์ ํŠธ ์™„๋ฃŒ ํ›„ ํŒ€์› ๋ฏผ์ง€์œค์ด ๊ฐœ์ธ์ ์œผ๋กœ ๋ฆฌํŒฉํ† ๋งํ•œ ๋‚ด์šฉ์ด ๋‹ด๊ฒจ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“† Working Period

2023๋…„ 8์›” 1์ผ ~ 9์›” 7์ผ (์•ฝ 1๊ฐœ์›”)


๐Ÿค– Languages & Technologies

ํŽผ์ณ์„œ ํ™•์ธ (๐Ÿ‘ˆ Click)

Back-end

  • Java 8
  • Spring Framework 5.0.1, Spring MVC
  • Spring Security 5
  • Maven
  • Mybatis
  • Eclipse, Visual Studio Code, DBeaver

Front-end

  • HTML
  • CSS
  • JavaScript
  • JQuery 3.7.0
  • BootStrap 4.5.3

Deploy

  • AWS EC2, S3, RDS
  • Tomcat 9.0
  • MySQL 8.0

Collaboration

  • Git, Sourcetree
  • Slack
  • Notion
  • Loop

External API

  • Naver, Kakao, Google Social Login
  • OpenAI
  • Clova OCR
  • I'mport
  • Google chart API

๐Ÿ’ Roles

ํŽผ์ณ์„œ ํ™•์ธ (๐Ÿ‘ˆ Click)
  • [๋ฏผ์ง€์œค] ์†Œ์…œ๋กœ๊ทธ์ธ, ์‡ผํ•‘๋ชฐ, ๊ด€๋ฆฌ์žํŽ˜์ด์ง€
    • ๋„ค์ด๋ฒ„, ๊ตฌ๊ธ€ ์†Œ์…œ๋กœ๊ทธ์ธ
    • ์ƒํ’ˆ ์‡ผํ•‘๋ชฐ ๊ฒŒ์‹œํŒ CRUD
    • ์‡ผํ•‘๋ชฐ ๊ด€๋ฆฌ์žํŽ˜์ด์ง€
    • ์ƒํ’ˆ ๊ฒฐ์ œ (์•„์ž„ํฌํŠธ)
    • Frontend UI ๊ตฌํ˜„
  • [๊ฐ•ํƒœํ—Œ] ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œํŒ
    • ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œํŒ CRUD
    • ๋Œ“๊ธ€, ๋Œ€๋Œ“๊ธ€ CRUD
    • ๊ฒŒ์‹œ๊ธ€ ๊ฒ€์ƒ‰๊ธฐ๋Šฅ, ํŽ˜์ด์ง€๋„ค์ด์…˜
  • [๊น€์˜์›…] ๊ฐ€๊ณ„๋ถ€
    • ์›”๊ฐ„ ์˜ˆ์‚ฐ๊ณผ ๊ณ ์ • ์ง€์ถœ ์„ค์ •
    • ์›”๋‹จ์œ„ ์‚ฌ์šฉํ•œ ๋‚ด์—ญ ํ˜•์‹ ๋ณด๊ณ ์„œ ์‚ฐ์ถœ
    • ๋ณด๊ณ ์„œ ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ, ์ด๋ฉ”์ผ ์ „์†ก
  • [์‹ ํ˜„๋ฒ”] ๊ฐ€๊ณ„๋ถ€
    • ์˜์ˆ˜์ฆ OCR
    • ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…
    • ์ฑ—๋ด‡, ๋งํฌ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
  • [์ด์„œ์˜] ์†Œ์…œ๋กœ๊ทธ์ธ, ์‡ผํ•‘๋ชฐ
    • ์นด์นด์˜ค ์†Œ์…œ๋กœ๊ทธ์ธ, ๋งˆ์ดํŽ˜์ด์ง€
    • ์‡ผํ•‘๋ชฐ ์žฅ๋ฐ”๊ตฌ๋‹ˆ
    • ์ƒํ’ˆ๊ด€๋ฆฌ์ž ๋ฐฐ์†ก๊ด€๋ฆฌ
  • [์žฅ์Šน์ง„] ๊ฐ€๊ณ„๋ถ€
    • ์›”๊ฐ„ ์˜ˆ์‚ฐ๊ณผ ๊ณ ์ • ์ง€์ถœ ์„ค์ •
    • ์›”๋‹จ์œ„ ์‚ฌ์šฉํ•œ ๋‚ด์—ญ ํ˜•์‹ ๋ณด๊ณ ์„œ ์‚ฐ์ถœ
    • ๋ณด๊ณ ์„œ ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ, ์ด๋ฉ”์ผ ์ „์†ก

๐Ÿ”Ž ๊ฒฐ๊ณผ๋ฌผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ

๋กœ๊ทธ์ธ, ๋งˆ์ดํŽ˜์ด์ง€
๊ตฟ์ฆˆ ์‡ผํ•‘๋ชฐ
์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œํŒ
๊ฐ€๊ณ„๋ถ€
๊ฒฐ์ œ
๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€

๐Ÿ“ ERD

๐Ÿง  Main Feature Diagram

๐ŸŽฏ Pain Point (Login)

์†Œ์…œ๋กœ๊ทธ์ธ ์ฝ”๋“œ, ์–ด๋–ป๊ฒŒ ๋” ๊ฐ„๋‹จํ•˜๊ณ  ๊น”๋”ํ•˜๊ฒŒ ๋งŒ๋“ค๊นŒ?

์†Œ์…œ๋กœ๊ทธ์ธ ๋ฃจํŠธ ํ†ต์ผํ•˜์—ฌ ๋‹ค์–‘ํ•œ API ๋ฐ›๊ธฐ

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์›๋ž˜ ๋‹จ์ผ ์†Œ์…œ๋กœ๊ทธ์ธ๋งŒ ๊ธฐํšํ•˜์˜€์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‹ค ๋ชจ๋“  ๋กœ๊ทธ์ธ ๋ฃจํŠธ๋ฅผ ํ†ต์ผํ•˜๊ณ  ๊ณผ์ •์„ ์ผ์›ํ™”ํ•˜์—ฌ 3๊ฐ€์ง€ ์†Œ์…œ๋กœ๊ทธ์ธ API๋ฅผ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๊ณ ,
ํŽธ๋ฆฌ์„ฑ์„ ๋„๋ชจํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
๋„ค์ด๋ฒ„, ์นด์นด์˜ค์˜ ๊ฒฝ์šฐ ์ฝœ๋ฐฑํŽ˜์ด์ง€๋ฅผ ๊ตฌ์„ฑํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•˜์Šต๋‹ˆ๋‹ค.
๊ตฌ๊ธ€ ๋กœ๊ทธ์ธ์˜ ๊ฒฝ์šฐ JWT๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒŒ์„œํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๊ฐ API์˜ ์ž์ฒดํ•จ์ˆ˜๋“ค์€ ์„œ๋กœ ๋ณ€์ˆ˜๋ช…๋„ ๋‹ค๋ฅด๊ณ , ์„ค๋ น ๊ฐ™์€ ๋ณ€์ˆ˜๋ช…์ด์–ด๋„ ์˜๋ฏธ๊ฐ€ ๋‹ฌ๋ž์Šต๋‹ˆ๋‹ค.
๋จผ์ € ๋กœ๊ทธ์ธ์— ํ•„์š”ํ•œ ๊ฐ๊ฐ์˜ ๋ณ€์ˆ˜๋ฅผ ์ฐพ์•„ ์ œ3์˜ ๊ฐ์ฒด๋กœ ์น˜ํ™˜ํ•˜์˜€๊ณ ,
๊ทธ ๊ณผ์ •์„ AJAX๋ฅผ ํ†ตํ•ด ๋™์ผํ•œ ๋ฉ”์„œ๋“œ๋กœ ์œ ๋„ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ๋ฌด์ˆ˜ํžˆ ๋งŽ์€ ๋‹ค์–‘ํ•œ ์†Œ์…œ๋กœ๊ทธ์ธ API๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ณ„๋„์˜ ์ž์ฒด ํšŒ์›DB๋ฅผ ์šด์˜ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— Social ID (JWT) ๊ฐ’์„ ์„ธ์…˜์œผ๋กœ ์„ค์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
์ฒซ ๋กœ๊ทธ์ธ์‹œ, ์ค‘๋ณต์„ ๊ฒ€์ƒ‰ํ•˜์—ฌ ์ฒซ๋ฐฉ๋ฌธ์‹œ ํฌ์ธํŠธ 1,000์› + ํ•„์ˆ˜ ๋‹‰๋„ค์ž„ ์„ค์ •์œผ๋กœ ์žก์•˜์Šต๋‹ˆ๋‹ค.

๐Ÿ“’ Retrospective

ํšŒ๊ณ , ๊ทธ๋ฆฌ๊ณ  ํŒ€ํ”„๋กœ์ ํŠธ๋ฅผ ํ†ตํ•ด ์–ป์€ ๊ฒƒ

ํŒ€์›์ธ ์ € ๋ฏผ์ง€์œค๋งŒ์˜ ๊ฐœ์ธ์ ์ธ ์˜๊ฒฌ์„ ๋‹ด์•˜์Šต๋‹ˆ๋‹ค.

ํŽผ์ณ์„œ ํ™•์ธ (๐Ÿ‘ˆ Click)

๐Ÿ’ก ์„ธ์ƒ์— ์™„์ „ํžˆ ๋˜‘๊ฐ™์€ ์„œ๋น„์Šค๋Š” ์—†๋‹ค

ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ํ•˜๋‚˜์˜ ์„œ๋น„์Šค, ์›น์‚ฌ์ดํŠธ๊ฐ€ ๋งŒ๋“ค์–ด์ง€๊ธฐ๊นŒ์ง€ ์ˆ˜๋งŽ์€ ์‚ฌ๋žŒ๋“ค์˜ ๊ณ ๋ฏผ์ด ์Œ“์—ฌ์•ผํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋งŒํผ ์ด ๋ชจ๋“  ํŒ€์›๋“ค์˜ ์•„์ด๋””์–ด๊ฐ€ ๋ชจ์—ฌ ์™„์ „ํžˆ ์ƒˆ๋กœ์šด ๊ฒฝ์šฐ์˜ ์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์™œ ๊ฐœ๋ฐœ์ž๋กœ ํ•˜์—ฌ๊ธˆ ์ปค๋ฎค๋‹ˆ์ผ€์ด์…˜์ด ๊ทธํ† ๋ก ์ค‘์š”ํ•œ ์—ญ๋Ÿ‰์ด๋ผ๊ณ  ํ•˜๋Š” ๊ฒƒ์ธ์ง€ ์•Œ๊ฒŒ๋˜๋Š” ์ˆœ๊ฐ„์ด์—ˆ์Šต๋‹ˆ๋‹ค.

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

๐Ÿ’Ž ํ€„๋ฆฌํ‹ฐ ์ด์ „์— ์™„์„ฑ์ด ์žˆ๋‹ค

๊ฐ€๊ณ„๋ถ€ ์ปค๋ฎค๋‹ˆํ‹ฐ๋Š” ์‚ฌ์‹ค ์š”์ฆ˜ ์œ ํ–‰ํ•˜๋Š” '๊ฑฐ์ง€๋ฐฉ' ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ ์ฐฉ์•ˆํ•˜์—ฌ ๋งŒ๋“ค์–ด์ง„ ์œ ๋จธ๋Ÿฌ์Šคํ•˜๊ณ  ์žฌ๋ฏธ๋‚œ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋ˆ„๊ตฌ๋ณด๋‹ค ์œ ์ €์˜ ์ฐธ์—ฌ๊ฐ€ ๋ˆ๋ฒŒ๋ ˆ์นœ๊ตฌ๋“ค ์‚ฌ์ดํŠธ๋ฅผ ๋”์šฑ '๋ˆ๋ฒŒ๋ ˆ'๋‹ต๊ฒŒ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ ํ•ต์‹ฌ ํ‚ฌ๋Ÿฌ์ปจํ…์ธ ๊ฐ€ ๋  ์ˆ˜ ์žˆ๋Š” ์‚ด๊นŒ?๋ง๊นŒ? ๊ฒŒ์‹œํŒ์ด ํ•ด๋‹น ๊ฒŒ์‹œํŒ์„ ๋‹ด๋‹นํ•˜๋Š” ๋ฉค๋ฒ„์˜ ์ดํƒˆ๋กœ ์ธํ•ด ์™„์„ฑ๋˜์ง€ ๋ชปํ–ˆ์Šต๋‹ˆ๋‹ค. ์ค‘๋„ ์ดํƒˆ๋กœ ์ธํ•ด ์ตœ์ข… ํŒ€ํ”„๋กœ์ ํŠธ์—์„œ ์ œ์™ธํ•˜๊ฒŒ ๋˜์—ˆ๊ณ  ์ด๋Š” ์ƒ๋‹นํžˆ ์•„์‰ฌ์šด ๊ฒฐ๊ณผ๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

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

๐Ÿค ๋ฌด์—‡๋ณด๋‹ค ์ค‘์š”ํ•œ ๊ฒƒ์€ ์ƒ๋Œ€๋ฐฉ์— ๋Œ€ํ•œ ์กด์ค‘

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

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



๐Ÿš€ 1st Refactoring : 1์ฐจ ๋ฆฌํŒฉํ† ๋ง

ํ”„๋กœ์ ํŠธ๊ฐ€ ๋๋‚œ ํ›„, ํŒ€์› ๋ฏผ์ง€์œค ๊ฐœ์ธ์˜ ๋ฆฌํŒฉํ† ๋ง์œผ๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒˆ๋กญ๊ฒŒ ๋นŒ๋“œํ•œ ๊ณผ์ •์„ ๊ธฐ์ˆ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

1-1. ๊ธฐ์กด ์žฅ๋ฐ”๊ตฌ๋‹ˆ, ๊ฒฐ์ œ๋ฐฉ์‹์˜ ํ•œ๊ณ„

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

์ƒํ’ˆ์„ ์„ธ๋ถ€์„ ํƒํ•˜๋Š” ๊ณผ์ •์ด 2์ฐจ๋ก€ ๋“ค์–ด๊ฐ€๋‹ค๋ณด๋‹ˆ, ๋ณต์žกํ•œ ๋ฆฌ์ŠคํŠธ์˜ ํ˜•ํƒœ๊ฐ€ ๋œ ๊ฒƒ์ด ๋ฌธ์ œ์˜€์Šต๋‹ˆ๋‹ค.
์˜ˆ์ปจ๋Œ€, 10๊ฐœ์˜ ์ƒํ’ˆ ์ค‘ 5๊ฐœ๋ฅผ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ๋„ฃ๊ณ , ์œ ์ €๋Š” ์žฅ๋ฐ”๊ตฌ๋‹ˆ์—์„œ๋„ ์ƒํ’ˆ์„ 3๊ฐœ๋งŒ ์„ ํƒํ•˜์—ฌ ์ฃผ๋ฌธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

JSON ๋ฐฐ์—ด๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์ „์†กํ•˜์—ฌ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ฐ’์ด ๋™์‹œ์— ๋„˜์–ด๊ฐˆ ์ˆ˜ ์žˆ๋„๋ก ํ•˜์˜€์Šต๋‹ˆ๋‹ค.


์žฅ๋ฐ”๊ตฌ๋‹ˆ์—์„œ ์ƒํ’ˆ์„ ํƒ์€ ๋ฌผ๋ก  ์ˆ˜๋Ÿ‰์„ ์ตœ์ข… ํ™•์ •ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ํ•„์ˆ˜์ ์œผ๋กœ ๋ฆฌ์ŠคํŠธ์˜ ํ˜•ํƒœ๋กœ ์„ ํƒ์‹œ๋งˆ๋‹ค ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ด์ฃผ๋Š” ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ฃผ๋ฌธ์„œ์˜ View์—์„œ ๋‹ค์‹œ ๋ถ„ํ•ดํ•˜์—ฌ ํ•ด๋‹น ์š”์†Œ๋“ค์„ ๋ชจ๋‘ ๋‚˜์—ดํ•œ ๋’ค, ๋‹ค์‹œ ๊ฒฐ์ œ์— ํ•„์š”ํ•œ ์š”์†Œ๋“ค๋งŒ ์ถ”๋ ค JSON ๋ฐฐ์—ด๋กœ ์„œ๋ฒ„์— ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

View์—์„œ ์ œ์ด์ฟผ๋ฆฌ๋ฅผ ํ†ตํ•ด ์ด์ค‘ ์–ด๋ ˆ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ผํ•œ ์ˆœ์„œ๋กœ ์ˆœํ™˜ํ•˜๋ฉฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์„œ๋ฒ„๋กœ ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

$(function() {
	$('#payOrder').click(function() {
		let IMP = window.IMP; // ์ƒ๋žต ๊ฐ€๋Šฅ
		    IMP.init('iamport'); // 'iamport' ๋Œ€์‹  ์ œ๊ณต๋œ "์ œํœด์‚ฌ ์‹๋ณ„์ฝ”๋“œ" ์‚ฌ์šฉ
		        
		    let orderItems = [
		         <c:forEach items="${newBasketList}" var="newBasket" varStatus="status">
		         <c:forEach items="${newProductList}" var="product">
		        	 <c:if test="${newBasket.productId eq product.productId}">
		        	      {
		        	        "basketSeq": "${newBasket.seq}",
		        	        "userId": "${newBasket.userId}",
		        	        "userName": "${memberDTO.userName}",
		        	        "address": $('#address-1').val() + " " + $('#address-2').val(),
		        	        "tel": $('#tel').val(),
		        	        "productPrice": "${product.productPrice}",
		        	    	"discountPrice": $('#discountPrice').val(),
		        	        "point": $('#point').val(),
		        	        "totalPrice": $('#totalPrice').val()
		        	         }<c:if test="${!status.last}">,</c:if>
		        	        </c:if>
		        	    </c:forEach>
		         </c:forEach>
		        ];

์ฒซ ๋ฒˆ์งธ ๋ฆฌํŒฉํ† ๋ง์€ ์ด๋ ‡๊ฒŒ JSON๋ฐฐ์—ด ๊ฐ์ฒด ์ƒ์„ฑ์„ ํ†ตํ•œ ๋ฐ์ดํ„ฐ ๊ตฌํ˜„์— ๋ชฉํ‘œ๋ฅผ ๋‘์—ˆ์Šต๋‹ˆ๋‹ค.

1-2. Trouble Shooting

๋ฆฌํŒฉํ† ๋ง์„ ์ง„ํ–‰ํ•˜๋ฉฐ ๋ฐœ๊ฒฌํ•œ ์‚ฌํ•ญ์€, ์—ฌ๋Ÿฌ ์‚ฌ๋žŒ์ด ์ฝ”๋“œ๋ฆฌ๋ทฐ์™€ ์˜ค๋ฅ˜์ •์ •์— ๋™์‹œ์— ์ฐธ์—ฌํ•˜๋‹ค๋ณด๋‹ˆ ์ฒ˜์Œ ์ฝ”๋“œ ์ž‘์„ฑ์ž์˜ ์˜๋„๋Œ€๋กœ ๋ณ€์ˆ˜๋‚˜ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ํ™œ์šฉํ•˜์ง€ ์•Š์•˜๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

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

๋„ค์ด๋ฐ ๊ด€๋ จํ•ด์„œ๋„ ์‰ฝ๊ฒŒ ์•Œ์•„๋ณผ ์ˆ˜ ์žˆ๋„๋ก ๋ณ€์ˆ˜๋ช…์„ newProductList, usedBasketSeq, memberOrderInfo๋“ฑ์œผ๋กœ ์žฌ์ •๋ฆฝํ•˜์—ฌ ์œ ์ง€๋ณด์ˆ˜์˜ ํŽธ๋ฆฌ์„ฑ์„ ๋„๋ชจํ•˜์˜€์Šต๋‹ˆ๋‹ค.

@PostMapping("product/orderlist")
public String submitOrder(
	@RequestParam("totalAmount") String totalAmount,
	@RequestParam("selectedId") List<String> selectedIdsStr,
	@RequestParam("seletedSeq") List<String> selectedSeqsStr,
		...(์ค‘๋žต)... 
		Model model, 
		HttpSession session) {

			...(์ค‘๋žต)...

			List<BasketDTO> newBasketList = basketService.getOrderlists(selectedSeqs);        
			List<ProductDTO> newProductList = productService.getProductsByIds(selectedIds);     

			String userNickname = (String) session.getAttribute("userNickname");

			...(์ค‘๋žต)...

			model.addAttribute("newBasketList", newBasketList);
			model.addAttribute("newProductList", newProductList);

1-3. ๊ฒฐ์ œ์‹œ ์ฃผ๋ฌธ๋‚ด์—ญ ์ €์žฅ์˜ ํšจ์œจ์„ฑ ๋„๋ชจ

๊ฒฐ์ œ ํ›„์— ๊ณ ๊ฐ์˜ ์ฃผ๋ฌธ๋‚ด์—ญ์„ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•ด์„œ, ๊ฒฐ์ œ ๊ณผ์ •์—์„œ ์ด 3๋ฒˆ์˜ ์ ˆ์ฐจ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด์—๋Š” memberDTO, basketDTO,productDTO ๋ชจ๋‘๋ฅผ ์ฃผ๋ฌธ์„œ๋กœ ๋„˜๊ฒจ ๊ทธ ๋ฐ์ดํ„ฐ๋“ค์„ orderlist๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ View ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•ด ์ฃผ๋ฌธ๋‚ด์—ญ์— ์ €์žฅ์ด ๋˜์–ด์•ผํ•˜๋Š” ์š”์†Œ๋“ค๋งŒ ์ถ”๋ ค ๋ฐฐ์—ด ํ˜•์‹์˜ JSON์„ ๋งŒ๋“ค์—ˆ๊ณ , ์ด๋ฅผ OrderListDTO ๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๋„˜๊ฒจ์ฃผ์—ˆ์Šต๋‹ˆ๋‹ค.

request๋ฅผ ์ง์ ‘ ํ•ธ๋“ค๋ง ํ•˜์ง€ ์•Š๊ณ , JSON์œผ๋กœ ๋„˜์–ด์˜จ ์ •๋ณด๋“ค์„ Jackson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ DTO์— ๋„ฃ์—ˆ์Šต๋‹ˆ๋‹ค.

ํŠนํžˆ, ์žฅ๋ฐ”๊ตฌ๋‹ˆ์—์„œ๋ถ€ํ„ฐ ๋„˜์–ด์˜จ ์„ ํƒํ•œ ์ƒํ’ˆ๋“ค์€ ๋ณต์ˆ˜๊ฐœ๋กœ์จ ์ด๋ฅผ ๋ฆฌ์ŠคํŠธ๋กœ ํ‘œํ˜„ํ•˜๋ฉด ๋ฆฌ์ŠคํŠธ ์•ˆ์— ๋ฐฐ์—ด์ด n๊ฐœ ์žˆ๋Š” ์ƒํƒœ์ž…๋‹ˆ๋‹ค. ์ฆ‰ basketDTO์™€ productDTO๋Š” ๋ฆฌ์ŠคํŠธ๋กœ ์˜ค๊ณ , memberDTO๋Š” 1๋ช…์˜ ์œ ์ € ์ •๋ณด๊ฐ€ ๋ฐฐ์—ด๋กœ ๋“ค์–ด์™”์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋ฆฌ์ŠคํŠธ๊ฐ€ ์„ž์ด๋‹ค๋ณด๋‹ˆ ์„œ๋ฒ„๋‹จ์—์„œ memberOrderInfo๋ฅผ ํ†ตํ•ด ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด ์‚ฌ์šฉ์ž์˜ ์ •๋ณด๋งŒ์„ ์ถ”์ถœํ•˜์—ฌ ๊ฒฐ์ œ๋‚ด์—ญ ์ €์žฅ์— ์ด์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.

@PostMapping("product/paySuccess") 
@ResponseBody
public int payOrder(@RequestBody List<OrderListDTO> orderItems, HttpSession session){ 
		
	/* ๊ฒฐ์ œ๋‚ด์—ญ ์ค‘ ์‚ฌ์šฉ์ž์— ๊ด€ํ•œ ์ •๋ณด๋ฅผ ์ถ”์ถœ */
	List<String> memberOrderInfo = new ArrayList<>();
	if (!orderItems.isEmpty()) {
		OrderListDTO userInfo = orderItems.get(0);

		String infos = String.format(
		"userId=%s, userName=%s, address=%s, tel=%s, discountPrice=%s, totalPrice=%s",
		userInfo.getUserId(), userInfo.getUserName(), userInfo.getAddress(),
		userInfo.getTel(), userInfo.getDiscountPrice(), userInfo.getTotalPrice()
		);

		memberOrderInfo.add(infos);
	}	
	int result = productService.payOrder(orderItems);

๐Ÿš€ 2nd Refactoring : 2์ฐจ ๋ฆฌํŒฉํ† ๋ง

2-1. ๋‚˜์˜ ๊ณ ๋ฏผ : ์ง„์งœ ์‡ผํ•‘๋ชฐ์€ ์ด๋ ‡๊ฒŒ ๊ณ„์‚ฐ๋˜์ง€ ์•Š์•„!

๋‘ ๋ฒˆ์งธ ๋ฆฌํŒฉํ† ๋ง์€ ์ „๋ฐ˜์ ์ธ ์‡ผํ•‘๋ชฐ ๊ธฐ๋Šฅ์˜ ์ˆ˜์ •์ž…๋‹ˆ๋‹ค.
๊ทธ ์ด์œ ๋Š” ๊ธฐ์กด์˜ ๊ตฌ์กฐ๊ฐ€ ํ˜„์‹ค์ ์ธ ์‡ผํ•‘๋ชฐ ๊ฒฐ์ œ ๋ฐฉ์‹์„ ๋”ฐ๋ฅด์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์•„๋ž˜ ๊ทธ๋ฆผ์—์„œ ๋ณด์‹ค ์ˆ˜ ์žˆ๋“ฏ, ๊ธฐ์กด ์‡ผํ•‘๋ชฐ ์ฃผ๋ฌธ๋‚ด์—ญ์€ ๊ณ ๊ฐ์œผ๋กœ ํ•˜์—ฌ๊ธˆ ์˜๋ฏธ์—†๋Š” ๋ฐฑ์—”๋“œ์˜ ์‹œํ€€์Šค ๋„˜๋ฒ„๋ฅผ ๋ณด์—ฌ์ฃผ๊ณ  ์žˆ๊ณ , ๊ฐ ์ƒํ’ˆ๋ณ„ ํ• ์ธ์•ก์„ ๋„์ถœํ•˜์ง€ ์•Š๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์ €๋Š” ์ด์ „ ์ปค๋ฆฌ์–ด๋กœ ๋„ค์ด๋ฒ„ D2C๋ชฐ์„(๊ทœ๋ชจ ์›” 10์–ต์ด์ƒ) ์ง์ ‘ ์šด์˜ํ•ด๋ดค๊ณ  ERP์— ์ด์ปค๋จธ์Šค ๋กœ์ง์„ ๋„์ž…ํ•œ ๊ฒฝํ—˜๋„ ์žˆ๊ณ , ์นดํŽ˜24๋ฅผ ํ†ตํ•ด ๋ธŒ๋žœ๋“œ๋ชฐ์„ ์ œ์ž‘ํ•œ ๊ฒฝํ—˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝํ—˜์œผ๋กœ ์œ„ ๊ทธ๋ฆผ๊ณผ ๊ฐ™์ด ์—ฌ๋Ÿฌ๊ฐœ์˜ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฒˆํ˜ธ์™€ ํ• ์ธ๊ธˆ์•ก์ด 1๊ฐœ์˜ ์ฃผ๋ฌธ๋ชฉ๋ก์— ๋‚˜์—ด๋˜๋Š” ๊ฒƒ์€ ์ด์ƒํ•œ ๋ฐฉ์‹์ด๋ผ๊ณ  ์ƒ๊ฐ์ด ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ ์‡ผํ•‘๋ชฐ์—์„œ๋Š” ํ• ์ธ์„ ๊ธฐ์ค€์œผ๋กœ ๊ธฐ๋Šฅ์„ ์„ธ๋ถ„ํ™”ํ•ด์•ผ๋งŒ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ๋“ค์–ด ์ตœ์ดˆ์ฃผ๋ฌธ๊ธˆ์•ก์€ ์ •๊ฐ€์—์„œ ๊ฐœ๋ณ„์ƒํ’ˆํ• ์ธ๊ธˆ์•ก์„ ๋นผ๊ณ  ๋ฐฐ์†ก๋น„๋ฅผ ๋”ํ•œ ๊ธˆ์•ก์ด ๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๊ณ ๊ฐ์ด ์„ ํƒํ•˜์ง€์•Š์•„๋„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒํ’ˆ์— ๋ถ€๊ณผ๋˜๋Š” ๊ธฐ๋ณธ ํ• ์ธ์ด๋ฉฐ productDTO์— ํฌํ•จ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹ค๋งŒ, ์ ๋ฆฝ๊ธˆ์ด๋ผ๋Š” ๊ฒƒ์€ ํฌ์ธํŠธ,๋งˆ์ผ๋ฆฌ์ง€์˜ ๊ฐœ๋…์œผ๋กœ ํŒ๋งค์žฅ๋ ค๊ธˆ์— ํ•ด๋‹นํ•˜์—ฌ ๋ถ€๊ฐ€๊ฐ€์น˜์„ธ ๊ณผ์„ธํ‘œ์ค€์˜ ๋Œ€์ƒ์ด ๋˜๋ฉฐ, ๋”ฐ๋ผ์„œ ์ฃผ๋ฌธ๋ชฉ๋ก์—๋Š” ์ „์ฒด ์ƒํ’ˆ์˜ ํ• ์ธ์œผ๋กœ ๋ณ„๋„ ๊ณ„์‚ฐ๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์˜์ˆ˜์ฆ์ƒ์—๋Š” ๊ฐœ๋ณ„ ๊ธˆ์•ก์˜ ํ• ์ธ์œผ๋กœ ๋“ค์–ด๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์—…์žฅ๋ณ„๋กœ ๊ทธ ์ •๋ฅ ์„ ์ •ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

์ €๋Š” ๋Œ€์ค‘์ ์œผ๋กœ ์ต์ˆ™ํ•œ ๋„ค์ด๋ฒ„ ์‡ผํ•‘์˜ ํ‘œ์ค€๋ฐฉ์‹์„ ๋”ฐ๋ผ ์ „์ฒดํ• ์ธ ์—ญ์‹œ ๊ทธ ๋น„์œจ๋กœ ํ• ์ธ์„ ๋งค๊ธฐ๋Š” ๊ธฐ๋Šฅ์„ ๋„์ž…ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” ์ „๋ฐ˜์ ์ธ ํŽ˜์ด์ง€์™€ ์ปจํŠธ๋กค๋Ÿฌ๋ณ„ ์ฝ”๋“œ ํ๋ฆ„์ด ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

2-2. ๋‹จ๊ณ„๋ณ„ ํ• ์ธ ์ ์šฉ๊ณผ ๊ณ„์‚ฐ

- ์ •๊ฐ€: PRODUCT_ORIPRICE
- ๊ฐœ๋ณ„ ์ƒํ’ˆํ• ์ธ: INDIV_DISCOUNT
- ์ตœ์ดˆ ์ฃผ๋ฌธ๊ธˆ์•ก: PRODUCT_PRICE
- ์ ๋ฆฝ๊ธˆ ์‚ฌ์šฉ: POINT_TOUSE
- ๊ฐœ๋ณ„ ํ• ์ธํ™˜์‚ฐ: INDIV_DISCOUNT
- ์˜์ˆ˜ ๊ธˆ์•ก๊ณ„์‚ฐ: PRODUCT_CALPRICE

์ด๋ ‡๊ฒŒ ์˜์ˆ˜๊ธˆ์•ก์„ ์ •ํ•˜๊ฒŒ ๋œ ์ด์œ ๋Š”, ์ฃผ๋ฌธ ๋‹จ๊ณ„์—์„œ ๊ฐ ์ƒํ’ˆ์˜ ํ• ์ธ ๊ธˆ์•ก์ด ๋งˆ์ผ๋ฆฌ์ง€(ํฌ์ธํŠธ) ์‚ฌ์šฉ์— ๋”ฐ๋ผ ๋™์ ์œผ๋กœ ๊ฒฐ์ •๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

โ‘  ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ์ƒํ’ˆ์€ ํŒ๋งค์ž๊ฐ€ 1์ฐจ ํ• ์ธํ•˜์—ฌ ์ƒํ’ˆ๋ชฉ๋ก์— ๊ฒŒ์‹œ๋œ๋‹ค. (์ตœ์ดˆ ์ฃผ๋ฌธ ๊ธˆ์•ก)
โ‘ก ๊ณ ๊ฐ์ด n๊ฐœ์˜ ์ƒํ’ˆ์„ ์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ๋‹ด๊ณ ์‹ถ์€ ๊ฒƒ๋งŒ ๋‹ด์œผ๋ฉด ์ฃผ๋ฌธ๋ฒˆํ˜ธ null๋กœ ํ•ด์„œ ์žฅ๋ฐ”๊ตฌ๋‹ˆ๊ฐ€ ์ƒ๊ธด๋‹ค.
์ด๋•Œ 1์ฐจ ์„ ํƒ์ด ์ด๋ฃจ์–ด์ง€๋ฉฐ, ์ƒํ’ˆ๊ณผ ์žฅ๋ฐ”๊ตฌ๋‹ˆ๋Š” ์ผ๋Œ€์ผ ๊ด€๊ณ„์ผ ๊ฒƒ์ด๋‹ค.
โ‘ข ์žฅ๋ฐ”๊ตฌ๋‹ˆ์—์„œ ๋‹ค์‹œ n๊ฐœ์˜ ์ƒํ’ˆ๋“ค์„ ์„ ํƒ(2์ฐจ ์„ ํƒ)ํ•ด์„œ ์ฃผ๋ฌธ์„œ๋กœ ์ด๋™
โ‘ฃ ์ฃผ๋ฌธ์„œ์—์„œ ์ž์‹ ์˜ ํฌ์ธํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 2์ฐจ ํ• ์ธ์„ ๋ฐ›๊ฒŒ ๋œ๋‹ค.
โ‘ค ์ „์ฒด ๊ธˆ์•ก์—์„œ ํฌ์ธํŠธ๋งŒํผ ํ• ์ธ๋œ ๊ธˆ์•ก์ด ๊ฒฐ์ œ๋œ๋‹ค.
โ‘ฅ ๊ฒฐ์ œ ์™„๋ฃŒ์‹œ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ํ…Œ์ด๋ธ”์— ํ•ด๋‹น ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋ฒˆํ˜ธ๋“ค์— ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐ๋“ค์—๋Š” ์ฃผ๋ฌธ๋ฒˆํ˜ธ๊ฐ€ ์ƒ๊ธฐ๊ณ  ๋™์‹œ์— ์•ˆ๋ณด์ด๊ฒŒ ์ฒ˜๋ฆฌ๋œ๋‹ค.
โ‘ฆ ์ฃผ๋ฌธํ…Œ์ด๋ธ”์—๋Š” ์ฃผ๋ฌธ๋ฒˆํ˜ธ๊ฐ€ ์ƒ๊ธด ๋ฐ์ดํ„ฐ๋“ค์˜ ํ–‰์ด ์ƒ๊ธด๋‹ค.
โ‘ง ์œ„์— ์ ์€ ์˜์ˆ˜๊ธˆ์•ก ๊ณ„์‚ฐ ํ•จ์ˆ˜์— ๋”ฐ๋ผ ๊ฐ ์ƒํ’ˆ๊ธˆ์•ก์˜ ์‹ค์ œ ํ• ์ธ์ ์šฉ๋œ ๊ธˆ์•ก์ด ์ฃผ๋ฌธ ํžˆ์Šคํ† ๋ฆฌ์— ์ €์žฅ๋œ๋‹ค.

2-3. DB ์—…๋ฐ์ดํŠธ ๋ฐ Transaction ์„ค์ •

๊ฒฐ์ œ์™€ ๋™์‹œ์— ๋ชจ๋“  ๊ฒƒ๋“ค์ด ์ฒ˜๋ฆฌ๋˜๋Š” ๊ตฌ์กฐ์ƒ ์ด๋ฅผ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์„ค์ •ํ•˜์—ฌ
์ฃผ๋ฌธ ์‹ ๊ทœ ์ฟผ๋ฆฌ ์ฒ˜๋ฆฌ์™€, ๋งˆ์ผ๋ฆฌ์ง€ ์ฐจ๊ฐ, ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ฒ˜๋ฆฌ, ์˜์ˆ˜๊ธˆ์•ก ํ•จ์ˆ˜๊ณ„์‚ฐ์„ ๋™์‹œ์— ์ง„ํ–‰ํ•˜์˜€์Šต๋‹ˆ๋‹ค.



์‹ ๊ทœ ์ฟผ๋ฆฌ์— ๋Œ€ํ•œ ๋ถ€๋‹ด๊ณผ ๋ฒˆ๊ฑฐ๋กœ์›€์„ ์ค„์ด๊ธฐ ์œ„ํ•ด,
๊ฐœ๋ณ„ ๋ฆฌ์ŠคํŠธ๋กœ insert ํ›„ ์ „์ฒด ๊ณ„์‚ฐ ๊ธˆ์•ก์„ insert ํ•˜๋Š” ๋ฐฉ์‹์—์„œ ๋ฒ—์–ด๋‚˜
๋ฆฌ์ŠคํŠธ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๊ฑฐ๊ธฐ์— ์ „์ฒด ๊ณ„์‚ฐ ๊ธˆ์•ก์„ add ํ•˜๊ณ ,
๊ฐœ๋ณ„ ๊ฐ์ฒด๋งŒ ๋ถˆ๋Ÿฌ์™€ ์˜์ˆ˜๊ณ„์‚ฐ ํ•จ์ˆ˜๋กœ ํ™˜์‚ฐํ•œ ๋’ค ๋‹ค์‹œ ๊ฐœ๋ณ„ ๋ฐฐ์—ด์— addํ•˜์—ฌ ํ•œ๋ฒˆ์— insert ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

2-4. ์ตœ์ข… ๊ฒฐ์ œ์™„๋ฃŒ ํŽ˜์ด์ง€

๐Ÿš€ 3rd Refactoring : 3์ฐจ ๋ฆฌํŒฉํ† ๋ง

3-1. Spring Security ์ ์šฉ

๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€์— Spring Security๋ฅผ ๋„์ž…ํ•˜์—ฌ ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
ํšŒ์› ์†Œ์…œ๋กœ๊ทธ์ธ ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ์›นํŽ˜์ด์ง€ ์ž์ฒด ํšŒ์›DB๊ฐ€ ์•„์˜ˆ ์—†๊ณ ,
DB๋‚ด์— ์†Œ์…œ token์™ธ์—๋Š” ๋ณด์œ ํ•˜๋Š” ํšŒ์› ๊ฐœ์ธ์ •๋ณด๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„๋กœ ์„ค์ •ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.
๋‹ค๋งŒ ๊ธฐ์กด ๊ด€๋ฆฌ์ž ๋กœ๊ทธ์ธ์€ ๋‹จ์ˆœ ๋น„๋ฐ€๋ฒˆํ˜ธ ์ผ์น˜์—ฌ๋ถ€๋ฅผ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ํ™•์ธํ•˜๋Š” ์ˆ˜์ค€์ด์—ˆ๊ธฐ์—
๋‹ค์ค‘ ๋กœ๊ทธ์ธ์ด ๊ฐ€๋Šฅํ•˜๋„๋ก DB๋ฅผ ๋งˆ๋ จํ•˜์˜€์Šต๋‹ˆ๋‹ค.

@Service
public class ManagerService {
	
	@Autowired
	BCryptPasswordEncoder passwordEncoder;

	public boolean managerLogin(ManagerDTO managerDTO) {
		String getPw = managerDAO.managerLogin(managerDTO);
		if(passwordEncoder.matches(managerDTO.getManagerPassword(), getPw)) {
			return true;
		}
		return false;
	}

๊ด€๋ฆฌ์ž์— ์‹œํ๋ฆฌํ‹ฐ๋ฅผ ๋„์ž…ํ•˜๊ธฐ ์œ„ํ•ด ๋ณ„๋„์˜ table์„ ๋งŒ๋“ค์—ˆ๊ณ , MVC๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค.
BCryptPasswordEncoder๋ฅผ ํ†ตํ•ด ํŒจ์Šค์›Œ๋“œ salt์•”ํ˜ธํ™” ํ•˜์˜€์Šต๋‹ˆ๋‹ค.
์—ฌ๋Ÿฌ ๋ช…์˜ ๊ด€๋ฆฌ์ž๋ฅผ ๋™์‹œ์— ๋“ฑ๋กํ•˜๊ณ  ๋กœ๊ทธ์ธํ•  ์ˆ˜ ์žˆ๋Š” ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค์–ด ์šด์˜ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

3-2. ์ตœ์ข… ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€


About

๐Ÿ’ฐ๊ฐ€๊ณ„๋ถ€ ์ปค๋ฎค๋‹ˆํ‹ฐ ์›นํ”„๋กœ์ ํŠธ ๐Ÿ’ธ

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published