๐Ÿ”จ ํ”„๋กœ์ ํŠธ ์ผ์ง€

์ •๋ณด ์ „๋‹ฌ๋ณด๋‹จ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉฐ ๊ฒช์€ ์ ๋“ค, ๋Š๋‚€ ์ ๋“ค์„ ๊ธฐ๋กํ•œ ์ผ์ง€

Project: Yestoday(account book)

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

  • ์œ ์ €๋Š” ์˜ค๋Š˜ ๋„์ „ํ•  ์†Œ๋น„ ๊ธˆ์•ก์„ ์„ค์ •ํ•œ๋‹ค. ์†Œ๋น„ ์‹œ ํ•ด๋‹น ๊ธˆ์•ก๊ณผ ๋‚ด์šฉ์„ ์ž…๋ ฅํ•œ๋‹ค.
  • ๋ฉ”์ธ ํ™”๋ฉด์—๋Š” ์–ด์ œ์™€ ์˜ค๋Š˜์— ๋Œ€ํ•œ ์ •๋ณด๊ฐ€ ๋‚˜์˜จ๋‹ค.
  • ์–ด์ œ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ตœ๊ทผ 1๋…„ ๊ฐ„์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์บ˜๋ฆฐ๋” ๋ทฐ๋กœ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์ฒ˜์Œ ํ”ผ๊ทธ๋งˆ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ๋””์ž์ธ์„ ๋งŒ๋“ค์–ด๋ณด์•˜๋‹ค.

yestoday

๐Ÿฆพ ํ”„๋กœ์ ํŠธ ๋ชฉํ‘œ

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

๐Ÿ˜‚ MV*ํŒจํ„ด๊ณผ ์˜ต์ €๋ฒ„ ํŒจํ„ด ๊ทธ๋ฆฌ๊ณ  ํด๋” ๊ตฌ์กฐ

๊ฐœ๋… ์ฐธ๊ณ  ์ฐธ๊ณ 

ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ํ™˜๊ฒฝ์„ ์„ธํŒ…ํ•˜๊ณ  ์ž ์ด์ œ ์‹œ์ž‘ํ•ด๋ณผ๊นŒ?! ํŒจ๊ธฐ๋กญ๊ฒŒ ์†์„ ์˜ฌ๋ ธ์œผ๋‚˜, MV* ํŒจํ„ด์ด๋‚˜ ์˜ต์ €๋ฒ„ ํŒจํ„ด์€ ์•Œ๊ฒ ๋Š”๋ฐโ€ฆ

  • ๊ทธ๋ž˜์„œ ์ด์ œ ํ”„๋กœ์ ํŠธ๋ฅผ ์œ„ํ•œ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ๋Š” ์–ด๋–ป๊ฒŒ ์งœ์•ผํ•˜์ง€?
  • ๋จธ๋ฆฌ๋กœ๋Š” ๊ฐœ๋…์ด ์ดํ•ด๊ฐ€ ๋๋Š”๋ฐ, ์ด๊ฑธ ์ฝ”๋“œ๋กœ ์–ด๋–ป๊ฒŒ ๋…น์—ฌ๋‚ด์•ผํ•˜์ง€

ํ•˜โ€ฆ ํŠนํžˆ ์œ„์˜ ๋ฌธ์ œ๋“ค์€ ๋ˆ„๊ฐ€ ํ•ด๊ฒฐํ•ด์ค„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋„ ์•„๋‹ˆ๊ณ  ๊ตฌ๊ธ€๋งํ•œ๋‹ค๊ณ  ๋”ฑ ์ง€๊ธˆ ๋‚ด ํ”„๋กœ์ ํŠธ์— ๋งž๊ฒŒ ์ •๋‹ต์ด ๋‚˜์˜จ๋Š ๊ฒƒ๋„ ์•„๋‹ˆ๋ผ์„œ, ์ •๋ง ๋งŽ์ด ํ—ค๋งธ๋‹ค.
๊ฒฐ๋ก ์ ์œผ๋กœ ์ผ๋‹จ์€ MVC ํŒจํ„ด, ์˜ต์ €๋ฒ„ ํŒจํ„ด์„ ๊ณ ๋ คํ•˜์—ฌ ์•„๋ž˜์™€ ๊ฐ™์€ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์งฐ๋‹ค.

ํด๋”๊ตฌ์กฐ

  • interfaces: ์˜ต์ €๋ฒ„ ํŒจํ„ด์„ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์˜ต์ €๋ฒ„ ํŒจํ„ด์—์„œ observable ๋ชจ๋“ˆ์— ๋Œ€ํ•œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ์—ˆ๋‹ค.
export default class Observable {
  constructor() {
    this._observers = new Set();
  }
  subscribe(observer) {
    this._observers.add(observer);
  }
  unsubscribe(observer) {
    this._observers = [...this._observers].filter((subscriber) => subscriber !== observer);
  }
  notify(data) {
    // ์—ฌ๊ธฐ์„œ subscriber๋Š” ํ•จ์ˆ˜
    this._observers.forEach((subscriber) => subscriber(data));
  }
}
  • models: ๋ชจ๋ธ์€ ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์˜์—ญ์œผ๋กœ ์œ„์˜ observable ๋ชจ๋“ˆ์„ ์ƒ์†ํ•˜๋ฉฐ ๊ฐ๊ฐ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ด๋‹นํ•œ๋‹ค.

    • ChallengeMoney.model.js: ๋„์ „ ๊ธˆ์•ก์— ๊ด€ํ•œ ๋ฐ์ดํ„ฐ ๋‹ด๋‹น
    • SpendItem.model.js: ์†Œ๋น„ ํ’ˆ๋ชฉ(์ด๋ฆ„ + ๊ธˆ์•ก)์— ๊ด€ํ•œ ๋ฐ์ดํ„ฐ ๋‹ด๋‹น
    • Date.model.js: ๋‚ ์งœ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ ๋‹ด๋‹น
  • views: ์œ„์˜ model ๋ชจ๋“ˆ๋“ค์„ ํ™œ์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ view๋ฅผ ๊ฐ–๋Š”๋‹ค. ์ด ๋•Œ, ํŽ˜์ด์ง€ ๋ณ„๋กœ ๋‚˜๋ˆ„์–ด์„œ ํด๋”๋ฅผ ๊ตฌ์„ฑํ•˜๊ณ  ๋‹ค์–‘ํ•œ view๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

๋ทฐ ํด๋”๊ตฌ์กฐ

  • app.js: ์›นํŽ™ entry์ด๊ธฐ๋„ ํ•˜๋ฉด์„œ ๋ชจ๋“  ๋ชจ๋“ˆ๋“ค์„ ๊ฐ€์ ธ์™€ ์ตœ์ข… ๋กœ์ง์„ ๋‹ด๋‹นํ•  ํŒŒ์ผ

์‚ฌ์‹ค ์ •๋ง ๋ณ„ ๊ฑฐ ์•„๋‹ ์ˆ˜ ์žˆ๋Š” ๋‚ด์šฉ์ด๊ณ , ํ‹€๋ ธ์„ ์ˆ˜๋„(?) ์žˆ์ง€๋งŒ ์ •๋ง ํ˜น์‹œ๋ผ๋„ ํ˜น์—ฌ๋ผ๋„ ํ”„๋กœ์ ํŠธ๋ฅผ ์‹œ์ž‘ํ•˜๊ธฐ์— ์•ž์„œ ํด๋” ๊ตฌ์กฐ์— ๋Œ€ํ•œ ๊ฐ์ด ์˜ค์ง€ ์•Š๋Š” ๋ถ„๋“คํ•œํ…Œ ๋„์›€์ด ๋˜๋ฉด ์ข‹๊ฒ ๋‹ค.