๐ŸŒ• F-lab ๋ฉ˜ํ† ๋ง ๊ธฐ๋ก

๋ฉ˜ํ† ๋ง ์ดํ›„ ๋ถ€์กฑํ•œ ๋ถ€๋ถ„์„ ์ฑ„์šฐ๊ธฐ ์œ„ํ•œ ๊ธฐ๋ก

โ” ์˜ต์ €๋ฒ„ ํŒจํ„ด์ด๋ž€

์˜ต์ €๋ฒ„ ํŒจํ„ด(observer pattern)์€ ๊ฐ์ฒด์˜ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ๊ด€์ฐฐํ•˜๋Š” ๊ด€์ฐฐ์ž๋“ค, ์ฆ‰ ์˜ต์ €๋ฒ„๋“ค์˜ ๋ชฉ๋ก์„ ๊ฐ์ฒด์— ๋“ฑ๋กํ•˜์—ฌ ์ƒํƒœ ๋ณ€ํ™”๊ฐ€ ์žˆ์„ ๋•Œ๋งˆ๋‹ค ๋ฉ”์„œ๋“œ ๋“ฑ์„ ํ†ตํ•ด ๊ฐ์ฒด๊ฐ€ ์ง์ ‘ ๋ชฉ๋ก์˜ ๊ฐ ์˜ต์ €๋ฒ„์—๊ฒŒ ํ†ต์ง€ํ•˜๋„๋ก ํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค. ์ฃผ๋กœ ๋ถ„์‚ฐ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋ง ์‹œ์Šคํ…œ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. ๋ฐœํ–‰/๊ตฌ๋… ๋ชจ๋ธ๋กœ ์•Œ๋ ค์ ธ ์žˆ๊ธฐ๋„ ํ•˜๋‹ค.
์ข€๋” ๋‹จ์ˆœํ•˜๊ฒŒ ์ƒ๊ฐํ•˜๋ฉด ์–ด๋–ค ๊ฐ์ฒด(A)์˜ ์ƒํƒœ๊ฐ€ ๋ณ€ํ•  ๋•Œ, ๊ทธ์™€ ์—ฐ๊ด€๋œ ๊ฐ์ฒด๋“ค(B)์—๊ฒŒ ์•Œ๋ฆผ์„ ๋ณด๋ƒ„์œผ๋กœ์จ ๊ฐ์ฒด ๊ฐ„์˜ ์˜์กด์„ฑ์„ ๋‚ฎ์ถ”๋Š” ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค.
B๋Š” A๋ฅผ ๊ตฌ๋…ํ•จ์œผ๋กœ์จ , A์—์„œ ์–ด๋–ค ์ด๋ฒคํŠธ๋ฅผ ๋ฐœํ–‰ํ•  ๋•Œ B์˜ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๊ฒŒ๋” ํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค.
A๋Š” Observable, Subject ๋“ฑ์œผ๋กœ ๋ถˆ๋ฆฌ๊ณ  Model์ด ๊ทธ ์—ญํ• ์„ ํ•œ๋‹ค. B๋Š” Observer์ด๋ฉฐ View์— ํ•ด๋‹นํ•œ๋‹ค.

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) {
    this._observers.forEach((observer) => observer(data));
  }
}

์˜ต์ €๋ฒ„ ํŒจํ„ด์„ ์ด์šฉํ•ด ํ•ด๊ฒฐํ•˜๋ ค๋Š” ์ƒํƒœ ๋ณ€๊ฒฝ?

ํ•œ ๊ฐ์ฒด์˜ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ, ์ด ๊ฐ์ฒด์—๊ฒŒ ์˜์กดํ•˜๊ณ  ์žˆ๋Š” ๋ชจ๋“  ๊ฐ์ฒด๋“ค์—๊ฒŒ ์ƒํƒœ ๋ณ€๊ฒฝ์— ๋Œ€ํ•ด ์•Œ๋ฆฌ๋ฉด์„œ ๋™์‹œ์— ์–ด๋–ค ํ–‰๋™์„ ์ทจํ•˜๊ฒŒ ํ•˜๋Š” ๊ฒƒ
๋Š์Šจํ•œ ๊ฒฐํ•ฉ: ๋‘ ๊ฐ์ฒด๊ฐ€ ์ƒํ˜ธ์ž‘์šฉ์„ ํ•˜์ง€๋งŒ, ์„œ๋กœ์— ๋Œ€ํ•ด์„œ๋Š” ์ž˜ ๋ชจ๋ฅด๊ฒŒ ํ•˜๋Š” ๊ฒฐํ•ฉ

  • ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฐ์ฒด(Subject)๋Š” Observer๋“ค์˜ ์ •๋ณด๋ฅผ ๊ตฌ์ฒด์ ์œผ๋กœ ์•Œ ํ•„์š”์—†์ด ์ •๋ณด ์ „๋‹ฌ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

โ” immutable์„ ์œ ์ง€ํ•˜๋ฉด์„œ ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ๋ฒ•

const a = {
  name: 'hodu',
  others: { age: 2, favorite: 'walking' },
};

// age๋งŒ ๋ณ€๊ฒฝํ•˜์—ฌ ๋‹ค๋ฅธ ๊ฐ์ฒด ๋งŒ๋“ค๊ธฐ

// 1) Object.assign() ์ด์šฉ
const b = Object.assign({}, a, {
  others: Object.assign({}, { age: 2, favorite: 'walking' }, { age: 31 }),
});

// 2) spread ์—ฐ์‚ฐ์ž ์ด์šฉ
const b = { ...a, others: { ...a.others, age: 31 } };

โ” SPA ๊ทธ๋ฆฌ๊ณ  ๋ผ์šฐํŒ…

SPA

SPA๋ž€ Single Page Application์˜ ์•ฝ์ž๋กœ, ํ•˜๋‚˜์˜ ํŽ˜์ด์ง€์—์„œ ๋™์ ์œผ๋กœ ์›ํ•˜๋Š” ๋ถ€๋ถ„๋งŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๋ฉฐ ํ™”๋ฉด์„ ๋ฐ”๊ฟ”๊ฐ€๋ฉฐ ํ‘œํ˜„ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
ํด๋ฆญ, ์Šคํฌ๋กค ๋“ฑ์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ์œ„ํ•œ ์ตœ์†Œํ•œ์˜ ์š”์†Œ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚˜๊ณ  ์œ ์ €์˜ ๋ˆˆ์— ํŽ˜์ด์ง€ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚œ๋‹ค๊ณ  ๋ณด์—ฌ์ง€๋Š” ๊ฒƒ ๋˜ํ•œ ์ตœ์ดˆ ๋กœ๋“œ๋œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ†ตํ•ด ๋™์ ์œผ๋กœ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒƒ์ด๋‹ค.(์„œ๋ฒ„์—์„œ ์ƒˆ๋กœ์šด html์„ ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค.)

SPA์˜ ๋‹จ์ 
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ๋™์ ์œผ๋กœ ํ™”๋ฉด ํ˜น์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๊ธฐ ๋•Œ๋ฌธ์—, ์ผ๋ฐ˜์ ์ธ html์„ ํฌ๋กค๋งํ•˜๋Š” ๊ฒ€์ƒ‰ ์—”์ง„์— ์žˆ์–ด ์ตœ์ ํ™”๊ฐ€ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ๋‹ค.
  • ํŽ˜์ด์ง€ ์ดˆ๊ธฐ ๋กœ๋“œ ์‹œ, ์›น๊ณผ ๊ด€๋ จํ•œ ํŒŒ์ผ๋“ค์ด ๋ฒˆ๋“ค๋˜์–ด ์ „์†ก๋˜๊ธฐ์— ์ดˆ๊ธฐ ๋กœ๋“œ ์†๋„๊ฐ€ ๋Š๋ฆด ์ˆ˜ ์žˆ๋‹ค.
    • ์ด๋ฅผ ๊ทน๋ณตํ•˜๊ธฐ ์œ„ํ•ด ์ฝ”๋“œ ์Šคํ”Œ๋ฆฌํŒ…, gzip ์••์ถ• ๋“ฑ์˜ ๋ฐฉ๋ฒ•์ด ์žˆ์œผ๋ฉฐ ์ด๋งˆ์ €๋„ ํ•ด๊ฒฐ์ด ํž˜๋“ค๋ฉด SSR(Server Side Rendering)๋กœ ๋„˜์–ด๊ฐ„๋‹ค.

๋ผ์šฐํŒ…

SPA๋ฅผ ํ†ตํ•ด UX(User Experience; ์‚ฌ์šฉ์ž ๊ฒฝํ—˜)๋ฅผ ๋†’์ธ ๊ฒƒ์€ ์ข‹์•˜๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋‹จ์ผ ํŽ˜์ด์ง€์ด๋‹ค ๋ณด๋‹ˆ ์ƒ์‹์ ์œผ๋กœ ์ƒ๊ฐํ•ด๋ด๋„ ํŽ˜์ด์ง€์˜ ์•ž, ๋’ค๋ฅผ ์˜ค๊ฐˆ ์ˆ˜ ์žˆ๋Š” ์•ž์œผ๋กœ๊ฐ€๊ธฐ, ๋’ค๋กœ๊ฐ€๊ธฐ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. ์ฆ‰, ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์ด ๋–จ์–ด์ง€๊ฒŒ ๋œ ๊ฒƒ์ด๋‹ค.
์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅํ•œ ๊ฒƒ์ด client routing ๊ฐœ๋…์ด๋ฉฐ, ๋‹จ์ˆœํ•˜๊ฒŒ ์ƒ๊ฐํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ ์˜์—ญ์—์„œ ๊ฐ€์ƒ์˜ ํŽ˜์ด์ง€ ์ฃผ์†Œ(route)๋ฅผ ๋งŒ๋“ค์–ด ํ™”๋ฉด ์ด๋™์ด ์ผ์–ด๋‚œ ๊ฒƒ์ฒ˜๋Ÿผ ์ž‘๋™ํ•˜๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์ด ๋•Œ, ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ œ๊ณตํ•˜๋Š” history API๋ฅผ ํ™œ์šฉํ•˜๊ฒŒ ๋œ๋‹ค.

  • history.back(): ์„ธ์…˜ ๊ธฐ๋ก ๋ฐ”๋กœ ์ด์ „ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋Š” ๋น„๋™๊ธฐ ๋ฉ”์„œ๋“œ. ๋’ค๋กœ ๊ฐ€๊ธฐ
  • history.forward(): ์„ธ์…˜ ๊ธฐ๋ก ๋ฐ”๋กœ ์ดํ›„ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋Š” ๋น„๋™๊ธฐ ๋ฉ”์„œ๋“œ. ์•ž์œผ๋กœ ๊ฐ€๊ธฐ
  • history.go(): ํŠน์ • ์„ธ์…˜ ๊ธฐ๋ก์œผ๋กœ ์ด๋™ํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ๋ฉ”์„œ๋“œ. 0์€ ํ˜„์žฌ ์œ„์น˜์ด๋ฉฐ -1์€ ์ด์ „, 1์€ ์ดํ›„ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•œ๋‹ค.
  • history.pushState(): ์ฃผ์–ด์ง„ ๋ฐ์ดํ„ฐ๋ฅผ ์„ธ์…˜ ๊ธฐ๋ก ์Šคํƒ์— ๋‹ด๋Š”๋‹ค. ์ง๋ ฌํ™” ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  JavaScript ๊ฐ์ฒด๋ฅผ ์ €์žฅ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • history.replaceState(): ์ตœ๊ทผ ์„ธ์…˜ ๊ธฐ๋ก ์Šคํƒ์˜ ๋‚ด์šฉ์„ ์ฃผ์–ด์ง„ ๋ฐ์ดํ„ฐ๋กœ ๊ต์ฒดํ•œ๋‹ค.

์ฆ‰, history API๋ฅผ ์ด์šฉํ•˜์—ฌ ์ฃผ์†Œ๋ฅผ ์ธ์œ„์ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ณ , ์„œ๋ฒ„๋กœ ์ƒˆ๋กœ์šด ํŽ˜์ด์ง€๋ฅผ ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ history.state์— ๋‹ด์•„๋‘” ์ •๋ณด๋กœ ajax ์š”์ฒญ์„ ๋ณด๋‚ด ํ™”๋ฉด์„ ๊ฐฑ์‹ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

โ” Test 3๊ฐ€์ง€

์œ ๋‹› ํ…Œ์ŠคํŠธ(unit test)

  • ์ „์ฒด ์ฝ”๋“œ ์ค‘ ์ž‘์€ ๋‹จ์œ„๋ฅผ ๋‹ค๋ฃจ๋Š” ํ…Œ์ŠคํŠธ(์ฃผ๋กœ ํ•จ์ˆ˜ ๋‹จ์œ„)
  • ํ…Œ์ŠคํŠธ์— ๋„คํŠธ์›ค, DB์™€ ๊ฐ™์€ ์™ธ๋ถ€ ๋ฆฌ์†Œ์Šค๊ฐ€ ํฌํ•จ๋œ๋‹ค๋ฉด ์œ ๋‹› ํ…Œ์ŠคํŠธ๊ฐ€ ์•„๋‹ˆ๋‹ค.
  • ์œ ๋‹› ํ…Œ์ŠคํŠธ๋Š” ๊ฐ„๋‹จํ•˜๊ณ  ๋ช…ํ™•ํ•ด์•ผํ•œ๋‹ค. ์˜ˆ์ธก๊ฐ’๊ณผ ์ž…๋ ฅ๊ฐ’์— ๋Œ€ํ•œ ํ•จ์ˆ˜์˜ ์ถœ๋ ฅ๊ฐ’์„ ๋น„๊ต
  • ์ฝ”๋“œ ์ž์ฒด์˜ ์„ค๊ณ„๊ฐ€ ์ข‹์ง€ ๋ชปํ•˜๋‹ค๋ฉด, ์œ ๋‹› ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ๋„ ์–ด๋ ค์›Œ์ง„๋‹ค.
  • ์–ด๋– ํ•œ ๋ถ€๋ถ„์—์„œ ๋ฌธ์ œ๊ฐ€ ์žˆ๊ณ  ๊ณ ์น  ๋ถ€๋ถ„์ด ์–ด๋””์ธ์ง€ ๋ช…ํ™•ํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.

ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ(Integration test)

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

์‹œ์Šคํ…œ ํ…Œ์ŠคํŠธ(System test)

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

๋ธ”๋ž™๋ฐ•์Šค ํ…Œ์ŠคํŠธ: ์†Œํ”„ํŠธ์›จ์–ด์— ๋Œ€ํ•œ ๋‚ด๋ถ€ ๊ตฌ์กฐ๋‚˜ ์ž‘๋™ ์›๋ฆฌ๋ฅผ ๋ชจ๋ฅด๋Š” ์ƒํƒœ์—์„œ ์†Œํ”„ํŠธ์›จ์–ด์˜ ๋™์ž‘์„ ๊ฒ€์‚ฌํ•˜๋Š” ๋ฐฉ๋ฒ•
์ฃผ๋กœ ์˜ฌ๋ฐ”๋ฅธ/์˜ฌ๋ฐ”๋ฅด์ง€ ์•Š์€ ์ž…๋ ฅ์„ ํ•˜๋‚˜ํ•˜๋‚˜ ๋™์›ํ•˜์—ฌ ์˜ฌ๋ฐ”๋ฅธ ์ถœ๋ ฅ์„ ํŒ๋ณ„ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ด๋ฃจ์–ด์ง„๋‹ค.

โ” OOP์˜ 4๋Œ€ ํ•ต์‹ฌ ๊ฐœ๋…(feat. JavaScript)

์บก์Šํ™”(Encapsulation)

  • ๋‚ด๋ถ€์—์„œ๋งŒ ์•Œ๊ณ  ์žˆ์–ด๋„ ๋˜๋Š” ์ •๋ณด๋Š” ์™ธ๋ถ€์— ๊ณต๊ฐœํ•˜์ง€ ์•Š๋Š”๋‹ค.(์ •๋ณด์€๋‹‰)
  • ๋‹จ, ํ•„์š”ํ•œ ๋ถ€๋ถ„์— ํ•œํ•ด์„œ๋งŒ ์™ธ๋ถ€์˜ ์ ‘๊ทผ์€ ํ—ˆ์šฉํ•œ๋‹ค.
  • ๊ณต์‹์ ์œผ๋กœ JavaScript๋Š” ์ง€์›ํ•˜์ง€๋Š” ์•Š๋Š”์ง€๋งŒ, ํด๋กœ์ €๋‚˜ module pattern ๋“ฑ์˜ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„์€ ๊ฐ€๋Šฅ

์ƒ์†(Inheritance)

  • ์ƒ์œ„ ํด๋ž˜์Šค์˜ ํ”„๋กœํผํ‹ฐ, ๋ฉ”์„œ๋“œ๋ฅผ ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ๋„ ์‚ฌ์šฉ
  • ์ฆ‰, ์ฝ”๋“œ์˜ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ชฉ์ 
  • ES6์˜ Class์—๋Š” extends, super()์„ ํ†ตํ•ด ์ƒ์†์ด ๊ฐ€๋Šฅ
  • ๋‹จ, ์ด ๋˜ํ•œ JavaScript์˜ prototype chain์„ ํ†ตํ•ด ๊ตฌํ˜„๋˜์–ด์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

์ถ”์ƒํ™”(Abstraction)

  • ๊ตฌํ˜„ํ•˜๋ ค๋Š” ์‹ค์ฒด์— ๋Œ€ํ•ด์„œ ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ์„ ์„ ํƒํ•˜์—ฌ ํด๋ž˜์Šค๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฒƒ
  • โ€˜์ฐจโ€™๋Š” โ€˜๋ฒ„์Šคโ€™์™€ โ€˜์ค‘์žฅ๋น„โ€™ ํด๋ž˜์Šค๋กœ ๊ตฌ๋ถ„์ง€์„ ์ˆ˜ ์žˆ๋‹ค. ํ—ˆ๋‚˜, ๋ฒ„์Šค์™€ ์ค‘์žฅ๋น„๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ์ฆ‰, ์ด๋ ‡๊ฒŒ ํ•„์š”ํ•œ ๋ถ€๋ถ„์„ ์„ ํƒํ•˜์—ฌ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ์ถ”์ƒํ™”
  • ๋‹น์—ฐํžˆ JavaScript์—์„œ๋„ ์ถ”์ƒํ™” ๊ฐ€๋Šฅ!

๋‹คํ˜•์„ฑ(Polymorphism)

  • ๋‹ค์–‘ํ•œ ์„ฑ์งˆ๋กœ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ
  • Java์—์„œ์˜ ์˜ˆ์‹œ
    • ์˜ค๋ฒ„๋ผ์ด๋”ฉ(overriding): A๋ผ๋Š” ํด๋ž˜์Šค๋ฅผ ์ƒ์†ํ•˜๋Š” a๋ผ๋Š” ํ•˜์œ„ ํด๋ž˜์Šค๊ฐ€ ์žˆ์„ ๋•Œ, A์˜ ๋ฉ”์„œ๋“œ๋ฅผ a์—์„œ ์žฌ์ •์˜ํ•˜๋Š” ๊ฒƒ
    • ์˜ค๋ฒ„๋กœ๋”ฉ(overloading): B๋ผ๋Š” ํด๋ž˜์Šค๋‚ด์— add(x, y)๋ผ๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•  ๋•Œ x์™€ y๊ฐ€ int ์ž๋ฃŒํ˜•์ผ ๋•Œ์˜ add์™€ str ์ž๋ฃŒํ˜•์ผ ๋•Œ์˜ add๋ฅผ ๊ฐ™์€ ์ด๋ฆ„์˜ ๋ฉ”์„œ๋“œ๋กœ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ(์ฆ‰, add(x, y)๋Š” x์™€ y๊ฐ€ int๋“ , str์ด๋“  ์ƒ๊ด€์—†์ด ํ•ด๋‹นํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.)
  • JavaScript์—์„œ๋Š” prototype chain์œผ๋กœ ์˜ค๋ฒ„๋ผ์ด๋”ฉ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋‹ค๋งŒ, overloading์˜ ๊ฒฝ์šฐ ๊ณต์‹์ ์ธ ์ง€์›์€ ์—†๋‹ค.(๊ตณ์ด ์–ต์ง€๋กœ ํ•˜์ž๋ฉด, ๋ณ€์ˆ˜์˜ ํƒ€์ž…์„ ์ฒดํฌํ•˜๊ณ  ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๊ธดํ•˜๋‹ค.)
  • JavaScript์— ๋‹คํ˜•์„ฑ์ด ์กด์žฌํ•˜๋Š”๊ฐ€? ๋Š” ์ค‘์š”ํ•œ ๋…ผ์Ÿ๊ฑฐ๋ฆฌ๋Š” ์•„๋‹ˆ๋‹ค!

โ” CORS๋ž€ ๋ฌด์—‡์ด๊ณ  ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์„๊นŒ

CORS ์ •์ฑ…์ด๋ž€ ๋‹จ์ˆœํ•˜๊ฒŒ ์ƒ๊ฐํ•˜๋ฉด SOP(Same-Origin Policy)์— ๋Œ€ํ•œ ์˜ˆ์™ธ ์กฐํ•ญ์ด๋‹ค.
๊ธฐ๋ณธ์ ์œผ๋กœ ์›น ๋ธŒ๋ผ์šฐ์ €๋Š” SOP์— ๋”ฐ๋ผ, ๋™์ผํ•œ ์ถœ์ฒ˜(์ถœ์ฒ˜ = ํ”„๋กœํ† ์ฝœ + ํ˜ธ์ŠคํŠธ + ํฌํŠธ)์˜ ๋ฆฌ์†Œ์Šค๋งŒ ๊ณต์œ  ๊ฐ€๋Šฅํ•˜๋‹ค. ํ•˜์ง€๋งŒ ์›น ํŽ˜์ด์ง€๋ฅผ ๊ตฌ์„ฑ ์‹œ ์™ธ๋ถ€์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ๋ฐ–์— ์—†์œผ๋ฏ€๋กœ ์ด์— ๋Œ€ํ•œ ์˜ˆ์™ธ์กฐํ•ญ์œผ๋กœ CORS(Cross-Origin Resource Sharing)๋ฅผ ๋‘๊ณ  ์žˆ๋‹ค.

CORS ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

  • ๋™์ผ ์ถœ์ฒ˜๋กœ ์ด๋™: ์•„์ฃผ ๋‹จ์ˆœํ•˜๊ฒŒ ๊ฐ™์€ ์ถœ์ฒ˜๋กœ ์ด๋™์‹œํ‚จ๋‹ค.
  • ์„œ๋ฒ„์—์„œ Access-Control-Allow-Origin ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
    • ๋ฆฌ์†Œ์Šค์˜ ์ถœ์ฒ˜๊ฐ€ ๋˜๋Š” ์„œ๋ฒ„์—, ๋ชจ๋“  ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์— ๋Œ€ํ•œ cross-origin http ์š”์ฒญ์„ ํ—ˆ๊ฐ€ํ•˜๋Š” Access-Control-Allow-Origin ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•ด์ค€๋‹ค. ๋‹ค๋งŒ, ์ „์ฒด ํ˜ธ์ŠคํŠธ์— ๋Œ€ํ•œ ์š”์ฒญ์„ ํ—ˆ์šฉํ•˜๊ฒŒ ๋˜๊ธฐ์— ๋ณด์•ˆ์— ์ทจ์•ฝํ•ด์ง„๋‹ค.
  • Proxy: Proxy Server๋Š” ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์š”์ฒญ์„ ํ—ˆ์šฉ ๋ฐ ๊ฑฐ๋ถ€ํ•˜๋Š” ์—ญํ• ์„ ์ค‘๊ฐ„์—์„œ ํ•ด์ค„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋ก์‹œ ์„œ๋ฒ„์—์„œ Access-Control-Allow-Origin ํ—ค๋”๋ฅผ ๋‹ด์•„ ์‘๋‹ตํ•ด ์ฃผ๋ฉด ๋œ๋‹ค.
    • proxy๋Š” ํ•„์ˆ˜์ ์ด์ง„ ์•Š์ง€๋งŒ, ๋ฐฑ์—”๋“œ์—์„œ ๊ฐœ๋ฐœ์„œ๋ฒ„๋ฅผ ์œ„ํ•œ CORS๋ฅผ ์„ค์ •์„ ์•ˆํ•ด๋„ ๋˜๊ธฐ์— ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ๋ฅผ ์•„๋‚„ ์ˆ˜ ์žˆ๋‹ค.
    • ํ”„๋ก ํŠธ์—”๋“œ์—์„  webpack-dev-server proxy๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„œ๋ฒ„์ชฝ ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

โ” http์—์„œ https๋กœ s๊ฐ€ ๋ถ™๋Š” ๊ณผ์ •(ssl ์ธ์ฆ์„œ ๋ฐœ๊ธ‰์˜ ์ผ๋ จ ๊ณผ์ •)

์ธํ„ฐ๋„ท ์ƒ์—์„œ ์›น ๋ธŒ๋ผ์šฐ์ €(Client)์™€ ์›น ์„œ๋ฒ„(Server)๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ฃผ๊ณ  ๋ฐ›๊ธฐ ์œ„ํ•ด์„œ๋Š” ์„œ๋กœ ์•”ํ˜ธํ™”ํ•˜์—ฌ ํ†ต์‹ ์„ ํ•ด์•ผํ•œ๋‹ค.
SSL(Secure Socket Layer)์€ ์›น ๋ธŒ๋ผ์šฐ์ €์™€ ์„œ๋ฒ„๊ฐ„ ์•”ํ˜ธํ™” ํ†ต์‹ ์„ ์œ„ํ•œ ํ”„๋กœํ† ์ฝœ์ด๋ฉฐ, SSL์ธ์ฆ์„œ๋Š” SSL ๊ธฐ๋ฐ˜ํ•˜์—์„œ ๋ธŒ๋ผ์šฐ์ €์™€ ์„œ๋ฒ„๊ฐ€ ์•”ํ˜ธํ™” ํ†ต์‹ ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ์ธ์ฆ์„œ(์ œ3์˜ ์‹ ๋ขฐ๊ธฐ๊ฐ„์ด ์ธ์ฆํ•œ)๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

SSL์ธ์ฆ์„œ์˜ 3๊ฐ€์ง€ ๊ธฐ๋Šฅ

  • ์ •๋ณด ์œ ์ถœ ๋ฐฉ์ง€: ํ‘œ์ค€ ์•”ํ˜ธํ™” ๊ธฐ๋ฒ•์„ ํ†ตํ•ด ์ „์†ก์ž์˜ ์ •๋ณด๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ „์†ก
  • ๊ธฐ์—… ์‹ค์ฒด์„ฑ ํ™•์ธ: ์˜ˆ๋ฅผ ๋“ค์–ด, ์ฟ ํŒก์— ์ฃผ๋ฌธ์„ ํ•  ๋•Œ ์ฟ ํŒก์ด๋ผ๋Š” ๊ธฐ์—…์˜ ์‹ค์ฒด์„ฑ(์‚ฌ์—…์ž ๋“ฑ๋ก๊ณผ ๊ฐ™์€)์„ ํ™•์ธ ํ›„์— ์ฟ ํŒก์— SSL ์ธ์ฆ์„œ๋ฅผ ๋ฐœ๊ธ‰
  • ์œ„์กฐ์‚ฌ์ดํŠธ ๋ฐฉ์ง€: ์‚ฌ์ดํŠธ์˜ ์ง„์œ„ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จ

์•”ํ˜ธํ™”

๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ฉ”์‹œ์ง€๋ฅผ ์•”ํ˜ธํ™”ํ•˜์—ฌ ์„œ๋ฒ„์— ์ „์†กํ•˜๋ฉด, ์„œ๋ฒ„๋Š” ์•”ํ˜ธํ™”ํ‚ค(๋น„๋ฐ€ํ‚ค)๋กœ ์•”ํ˜ธํ™”๋œ ๋ฉ”์‹œ์ง€๋ฅผ ํ•ด๋…(๋ณตํ˜ธํ™”)ํ•˜๋Š” ๊ณผ์ •์ด ์ด๋ค„์ง„๋‹ค.

  • ๋Œ€์นญํ‚ค ์•”ํ˜ธํ™”: ๋ฉ”์‹œ์ง€๋ฅผ ์•”ํ˜ธํ™”ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋น„๋ฐ€ํ‚ค์™€ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณตํ˜ธํ™”ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋น„๋ฐ€ํ‚ค๊ฐ€ ๊ฐ™์€ ๊ฒฝ์šฐ

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

  • ๋น„๋Œ€์นญํ‚ค ์•”ํ˜ธํ™”(๊ณต๊ฐœํ‚ค ์•”ํ˜ธํ™”): ์†ก์‹ ์ž์™€ ์ˆ˜์‹ ์ž๊ฐ€ ๊ฐ๊ฐ 2๊ฐœ์˜ ํ‚ค๋ฅผ ์ƒ์„ฑํ•˜๋Š”๋ฐ, ํ•˜๋‚˜๋Š” ๊ฐœ์ธํ‚ค์ด๊ณ  ๋‚˜๋จธ์ง€ ํ•˜๋‚˜๋Š” ๊ณต๊ฐœํ‚ค
    • ๊ณต๊ฐœํ‚ค๋กœ ์•”ํ˜ธํ™”ํ•˜๋ฉด ๊ฐœ์ธํ‚ค๋กœ ๋ณตํ˜ธํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ณ , ๊ฐœ์ธํ‚ค๋กœ ์•”ํ˜ธํ™”ํ•˜๋ฉด ๊ณต๊ฐœํ‚ค๋กœ ๋ณตํ˜ธํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.
    • ์ฆ‰, ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์„œ๋ฒ„์˜ ๊ณต๊ฐœํ‚ค๋กœ ์•”ํ˜ธํ™”๋ฅผ ํ•˜์—ฌ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๊ณ , ์„œ๋ฒ„๋Š” ์„œ๋ฒ„์˜ ๊ฐœ์ธํ‚ค๋กœ ๋ณตํ˜ธํ™”๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค.
    • ๋ฐ˜๋Œ€๋กœ ์„œ๋ฒ„๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ ๊ณต๊ฐœํ‚ค๋กœ ์•”ํ˜ธํ™”, ๋ธŒ๋ผ์šฐ์ €๋Š” ๋ธŒ๋ผ์šฐ์ €์˜ ๊ฐœ์ธํ‚ค๋กœ ๋ณตํ˜ธํ™”ํ•˜์—ฌ ๋” ์•ˆ์ „ํ•œ๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

SSL ์ธ์ฆ ๊ณผ์ •

  • ์„œ๋ฒ„๊ฐ€ ์„œ๋ฒ„์˜ ๊ณต๊ฐœํ‚ค(SSL ์ธ์ฆ์„œ) ์†ก์‹ 
  • ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์„œ๋ฒ„์˜ ๊ณต๊ฐœํ‚ค๋ฅผ ๊ฒ€์ฆ(์ธ์ฆ๊ธฐ๊ด€์— ๊ฒ€์ฆ์„ ์š”์ฒญ)

    ------๊ฒ€์ฆ ์™„๋ฃŒ ํ›„-------

  • ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋Œ€์นญํ‚ค ์ƒ์„ฑ
  • ๋ธŒ๋ผ์šฐ์ €๋Š” ๊ฒ€์ฆ๋œ ์„œ๋ฒ„์˜ ๊ณต๊ฐœํ‚ค๋กœ ๋Œ€์นญํ‚ค๋ฅผ ์•”ํ˜ธํ™” ๋ฐ ์†ก์‹ 
  • ์„œ๋ฒ„๋Š” ์„œ๋ฒ„์˜ ๊ฐœ์ธํ‚ค๋กœ ๋Œ€์นญํ‚ค๋ฅผ ๋ณตํ˜ธํ™”

    ------๋ธŒ๋ผ์šฐ์ €์™€ ์„œ๋ฒ„๊ฐ€ ๋Œ€์นญํ‚ค๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๊ตํ™˜-------

  • ์ด์ œ ๋ธŒ๋ผ์šฐ์ €๋Š” ๋Œ€์นญํ‚ค๋กœ ๋ฉ”์‹œ์ง€ ์•”ํ˜ธํ™” ๋ฐ ์ „์†ก
  • ์„œ๋ฒ„๋Š” ๋Œ€์นญํ‚ค๋กœ ์ˆ˜์‹ ํ•œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณตํ˜ธํ™”
๐Ÿš— Reference

์œ„ํ‚ค๋ฐฑ๊ณผ-์˜ต์ €๋ฒ„ ํŒจํ„ด
์˜ต์ €๋ฒ„ํŒจํ„ด
ํ…Œ์ŠคํŠธ(1)
ํ…Œ์ŠคํŠธ(2)
์œ„ํ‚ค๋ฐฑ๊ณผ-์‹œ์Šคํ…œ ํ…Œ์ŠคํŠธ
์œ„ํ‚ค๋ฐฑ๊ณผ-๋ธ”๋ž™๋ฐ•์Šค ํ…Œ์ŠคํŠธ
SOP์™€ CORS
SSL, ๊ทธ๋ฆฌ๊ณ  ์•”ํ˜ธํ™”