# ๐Ÿ“„ Item16 ~ 18


# Item16. number ์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ณด๋‹ค๋Š” Array, ํŠœํ”Œ, ArrayLike๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ

  • Array์— ๋Œ€ํ•œ ํƒ€์ž… ์„ ์–ธ(lib.es5.d.ts์—์„œ ํ™•์ธ ๊ฐ€๋Šฅ)
interface Array<T> {
  // ...
  [n: number]: T;
}
  • ๋Ÿฐํƒ€์ž„์—๋Š” ECMAScript ํ‘œ์ค€์ด ์„œ์ˆ ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ฌธ์ž์—ด ํ‚ค๋กœ ์ธ์‹ํ•˜๋ฏ€๋กœ ์ด ์ฝ”๋“œ๋Š” ์™„์ „ํžˆ ๊ฐ€์ƒ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ํƒ€์ž… ์ฒดํฌ ์‹œ์ ์— ์˜ค๋ฅ˜๋ฅผ ์žก์„ ์ˆ˜ ์žˆ์–ด ์œ ์šฉํ•˜๋‹ค.
const xs = [1, 2, 3];
const x0 = xs[0]; // ์ •์ƒ
const x1 = xs['1']; // ์ธ๋ฑ์Šค ์‹์ด 'number' ํ˜•์‹์ด ์•„๋‹ˆ๋ฏ€๋กœ ์š”์†Œ์— ์•”์‹œ์ ์œผ๋กœ 'any' ํ˜•์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค.

function get<T>(array: T[], k: string): T {
  return array[k]; // ์ธ๋ฑ์Šค ์‹์ด 'number' ํ˜•์‹์ด ์•„๋‹ˆ๋ฏ€๋กœ ์š”์†Œ์— ์•”์‹œ์ ์œผ๋กœ 'any' ํ˜•์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค.
}
  • ํ•œํŽธ Object.keys ๊ฐ™์€ ๊ตฌ๋ฌธ์€ ์—ฌ์ „ํžˆ ๋ฌธ์ž์—ด๋กœ ๋ฐ˜ํ™˜๋œ๋‹ค.
    • string ์ด number์— ํ• ๋‹น๋  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜ ์ฝ”๋“œ์˜ ๋งˆ์ง€๋ง‰ ์ค„์ด ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์ด ์ด์ƒํ•˜๊ฒŒ ๋ณด์ผ ๊ฒƒ์ด๋‹ค.
    • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ํ”ํ•œ ์ผ์ด์ง€๋งŒ, ์ด ์˜ˆ์ œ๊ฐ€ ๋ฐฐ์—ด์„ ์ˆœํšŒํ•˜๊ธฐ์— ์ข‹์€ ๋ฐฉ๋ฒ•์€ ์•„๋‹ˆ๋‹ค.
const keys = Object.keys(xs); // ํƒ€์ž…์ด string[]

for (const key in xs) {
  key; // ํƒ€์ž…์ด string
  const x = xs[key]; // ํƒ€์ž…์ด number
}
  • ์ธ๋ฑ์Šค์— ์‹ ๊ฒฝ ์“ฐ์ง€ ์•Š๋Š”๋‹ค๋ฉด, for~of๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒŒ ๋” ์ข‹๋‹ค.
for (const x of xs) {
  x; // ํƒ€์ž…์ด number
}
  • ๋งŒ์•ฝ ์ธ๋ฑ์Šค์˜ ํƒ€์ž…์ด ์ค‘์š”ํ•˜๋‹ค๋ฉด, number ํƒ€์ž…์„ ์ œ๊ณตํ•ด ์ค„ Array.prototype.forEach๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
xs.forEach((x, i) => {
  i; // ํƒ€์ž…์ด number
  x; // ํƒ€์ž…์ด number
})
  • ๋ฃจํ”„ ์ค‘๊ฐ„์— ๋ฉˆ์ถฐ์•ผ ํ•œ๋‹ค๋ฉด, C ์Šคํƒ€์ผ์ธ for(;;) ๋ฃจํ”„๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
for (let i = 0; i < xs.length; i++) {
  const x = xs[i];
  if (x < 0) break;
}
  • ์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ฒ˜๊ฐ€ number๋กœ ํ‘œํ˜„๋˜์–ด ์žˆ๋‹ค๋ฉด ์ž…๋ ฅํ•œ ๊ฐ’์ด number์—ฌ์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜์ง€๋งŒ(for~in ๋ฃจํ”„๋Š” ํ™•์‹คํžˆ ์ œ์™ธ), ์‹ค์ œ ๋Ÿฐํƒ€์ž„์— ์‚ฌ์šฉ๋˜๋Š” ํ‚ค๋Š” string ํƒ€์ž…์ด๋‹ค.
    • number๋ฅผ ์ธ๋ฑ์Šค ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ์ˆซ์ž ์†์„ฑ์ด ์–ด๋–ค ํŠน๋ณ„ํ•œ ์˜๋ฏธ๋ฅผ ์ง€๋‹Œ๋‹ค๋Š” ์˜คํ•ด๋ฅผ ๋ถˆ๋Ÿฌ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.
  • ์–ด๋–ค ๊ธธ์ด๋ฅผ ๊ฐ€์ง€๋Š” ๋ฐฐ์—ด๊ณผ ๋น„์Šทํ•œ ํ˜•ํƒœ์˜ ํŠœํ”Œ์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์— ์žˆ๋Š” ArrayLike ํƒ€์ž…์„ ์‚ฌ์šฉํ•œ๋‹ค.
function checkedAccess<T>(xs: ArrayLike<T>, i: number): T {
  if (i < xs.length) {
    return xs[i];
  }
    
  throw new Error(`๋ฐฐ์—ด์˜ ๋์„ ์ง€๋‚˜์„œ ${i}๋ฅผ ์ ‘๊ทผํ•˜๋ ค๊ณ  ํ–ˆ์Šต๋‹ˆ๋‹ค.`);
}

๐Ÿ’ก ๊ฒฐ๋ก !

  • ๋ฐฐ์—ด์€ ๊ฐ์ฒด์ด๋ฏ€๋กœ ํ‚ค๋Š” ์ˆซ์ž๊ฐ€ ์•„๋‹ˆ๋ผ ๋ฌธ์ž์—ด์ด๋‹ค.
    • ์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ฒ˜๋กœ ์‚ฌ์šฉ๋œ number ํƒ€์ž…์€ ๋ฒ„๊ทธ๋ฅผ ์žก๊ธฐ ์œ„ํ•œ ์ˆœ์ˆ˜ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ์ด๋‹ค.
  • ์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ฒ˜์— number๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋ณด๋‹ค Array๋‚˜ ํŠœํ”Œ, ๋˜๋Š” ArrayLike ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

# Item17. ๋ณ€๊ฒฝ ๊ด€๋ จ๋œ ์˜ค๋ฅ˜ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•ด readonly ์‚ฌ์šฉํ•˜๊ธฐ

  • number ํƒ€์ž…์„ ๋‹ด์€ ๋ฐฐ์—ด์„ ์˜ˆ์‹œ๋กœ ์ƒ๊ฐํ•ด๋ณด์ž.
    • number[]๋Š” readonly number[]๋ณด๋‹ค ๊ธฐ๋Šฅ์ด ๋งŽ์œผ๋ฏ€๋กœ readonly number[]์˜ ์„œ๋ธŒํƒ€์ž…์ด ๋œ๋‹ค.
    • ๋”ฐ๋ผ์„œ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๋ฐฐ์—ด์„ readonly ๋ฐฐ์—ด์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๊ณ  ๊ทธ ๋ฐ˜๋Œ€๋Š” ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
const a: number[] = [1, 2, 3];
const b: readonly number[] = a;
const c: number[] = b; // 'readonly number[]' ํƒ€์ž…์€ 'readonly'์ด๋ฏ€๋กœ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ 'number[]' ํƒ€์ž…์— ํ• ๋‹น๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ readonly๋กœ ์„ ์–ธํ•˜๋ฉด ์ƒ๊ธฐ๋Š” ์ผ
    • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ํ•จ์ˆ˜ ๋‚ด์—์„œ ๋ณ€๊ฒฝ์ด ์ผ์–ด๋‚˜๋Š”์ง€ ์ฒดํฌํ•œ๋‹ค.
    • ํ˜ธ์ถœํ•˜๋Š” ์ชฝ์—์„œ๋Š” ํ•จ์ˆ˜๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๋ณด์žฅ์„ ๋ฐ›๊ฒŒ ๋œ๋‹ค.
    • ํ˜ธ์ถœํ•˜๋Š” ์ชฝ์—์„œ ํ•จ์ˆ˜์— readonly ๋ฐฐ์—ด์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๋„ฃ์„ ์ˆ˜๋„ ์žˆ๋‹ค.
  • ๋งŒ์•ฝ ํ•จ์ˆ˜๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ˆ˜์ •ํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด readonly๋กœ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.
    • readonly ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋ช…ํ™•ํ•˜๊ฒŒ ํ•˜๋ฉฐ, ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•œ๋‹ค.
  • readonly๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ณ€๊ฒฝํ•˜๋ฉด์„œ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๊ณ , ๋ณ€๊ฒฝ์ด ๋ฐœ์ƒํ•˜๋Š” ์ฝ”๋“œ๋„ ์‰ฝ๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.

# โญ๏ธ const์™€ readonly์˜ ์ฐจ์ด

function parseTaggedText(lines: string[]): string[][] {
  const paragraph: string[][] = [];
  const currPara: string[] = [];
    
  const addParagraph = () => {
    if (currPara.length) {
      paragraphs.push(currPara);
      currPara.length = 0; // ๋ฐฐ์—ด์„ ๋น„์›€
    }
  };
    
  for (const line of lines) {
    if (!line) {
      addParagraph();
    } else {
      currPara.push(line);
    }
  }
    
  addParagraph();
  return paragraphs;
}
  • ์œ„ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด [[], [], []]์™€ ๊ฐ™์€ ์ž˜๋ชป๋œ ๊ฒฐ๊ณผ๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค.
  • ๋ฐฐ์—ด์„ ๋น„์šฐ๋Š” ์ฝ”๋“œ ๋ถ€๋ถ„์ด ๋ฌธ์ œ์ธ๋ฐ ์ด ๋•Œ currPara๋ฅผ readonly๋กœ ์„ ์–ธํ•˜์—ฌ ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.
function parseTaggedText(lines: string[]): string[][] {
  const paragraph: string[][] = [];
  // ์„ ์–ธ๋ถ€๋ฅผ let์„ ๋ฐ”๊พธ๊ณ  readonly๋ฅผ ์ถ”๊ฐ€ํ•จ์œผ๋กœ์จ ํ•œ์ชฝ์˜ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ์„ฑ์„ ๋˜ ๋‹ค๋ฅธ ์ชฝ์œผ๋กœ ์˜ฎ๊ธด ๊ฒƒ์ด๋‹ค.
  // currPara ๋ณ€์ˆ˜๋Š” ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ฐฐ์—ด์„ ์ž์œ ๋กญ๊ฒŒ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๊ทธ ๋ฐฐ์—ด ์ž์ฒด๋Š” ๋ณ€๊ฒฝํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋œ๋‹ค.
  let currPara: readonly string[] = [];
    
  const addParagraph = () => {
    if (currPara.length) {
      paragraphs.push(currPara);
      currPara = []; // ๋ฐฐ์—ด์„ ๋น„์›€
    }
  };
    
  for (const line of lines) {
    if (!line) {
      addParagraph();
    } else {
      currPara = currPara.concat([line]); // push์™€ ๋‹ฌ๋ฆฌ concat์€ ์›๋ณธ์„ ์ˆ˜์ •ํ•˜์ง€ ์•Š๊ณ  ์ƒˆ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•จ
    }
  }
    
  addParagraph();
  return paragraphs;
}
  • ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ parargraphs์— ๋Œ€ํ•œ ์˜ค๋ฅ˜๋Š” ๋‚จ์•„ ์žˆ๋‹ค. ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์€ ์ด ์„ธ ๊ฐ€์ง€ ์ด๋‹ค.

    • currPara์˜ ๋ณต์‚ฌ๋ณธ์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•
      • currPara๋Š” readonly๋กœ ์œ ์ง€๋˜์ง€๋งŒ, ๋ณต์‚ฌ๋ณธ์€ ์›ํ•˜๋Š” ๋Œ€๋กœ ๋ณ€๊ฒฝ์ด ๊ฐ€๋Šฅํ•˜๋ฏ€๋กœ ์˜ค๋ฅ˜๋Š” ์‚ฌ๋ผ์ง„๋‹ค.
    paragraphs.push([...currPara]);
    
    • paragraphs(๊ทธ๋ฆฌ๊ณ  ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ํƒ€์ž…)๋ฅผ readonly string[]์˜ ๋ฐฐ์—ด๋กœ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฐฉ๋ฒ•
    const paragraphs: (readonly string[])[] = [];
    
    • ๋ฐฐ์—ด์˜ readonly ์†์„ฑ์„ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•œ ๋‹จ์–ธ๋ฌธ์„ ์“ฐ๋Š” ๋ฐฉ๋ฒ•
    paragraphs.push(currPara as string[]);
    
  • readonly๋Š” ์–•๊ฒŒ ๋™์ž‘ํ•œ๋‹ค๋Š” ๊ฒƒ์— ์œ ์˜ํ•ด์•ผ ํ•œ๋‹ค.

    • ๋งŒ์•ฝ ๊ฐ์ฒด์˜ readonly ๋ฐฐ์—ด์ด ์žˆ๋‹ค๋ฉด, ๊ทธ ๊ฐ์ฒด ์ž์ฒด๋Š” readonly๊ฐ€ ์•„๋‹ˆ๋‹ค.
const dates: readonly Date[] = [new Date()];
dates.push(new Date()); // ~~~ 'readonly Date[]' ํ˜•์‹์— 'push' ์†์„ฑ์ด ์—†์Šต๋‹ˆ๋‹ค.
dates[0].setFullYear(2037); // ์ •์ƒ
  • ๋น„์Šทํ•œ ๊ฒฝ์šฐ๋กœ Readonly ์ œ๋„ค๋ฆญ์ด ์žˆ๋‹ค.
interface Outer {
  inner: {
    x: number;
  }
}

const o: Readonly<Outer> = { inner: { x: 0 } };
o.inner = { x: 1 }; // ~~~ ์ฝ๊ธฐ ์ „์šฉ ์†์„ฑ์ด๊ธฐ ๋•Œ๋ฌธ์— 'inner'์— ํ• ๋‹นํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค/
o.inner.x = 1; // ์ •์ƒ
  • ์ค‘์š”ํ•œ ์ ์€ readonly ์ ‘๊ทผ์ œ์–ด์ž๋Š” inner์— ์ ์šฉ๋˜๋Š” ๊ฒƒ์ด์ง€ x๋Š” ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์ด๋‹ค.

    • ํ˜„์žฌ ์‹œ์ ์—๋Š” ๊นŠ์€ readonly ํƒ€์ž…์ด ๊ธฐ๋ณธ์œผ๋กœ ์ง€์›๋˜์ง€ ์•Š์ง€๋งŒ, ์ œ๋„ค๋ฆญ์„ ๋งŒ๋“ค๋ฉด ๊นŠ์€ readonly ํƒ€์ž…์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ๊ทธ๋Ÿฌ๋‚˜ ์ œ๋„ค๋ฆญ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์€ ๊นŒ๋‹ค๋กญ๊ธฐ ๋•Œ๋ฌธ์— ts-essentials์— ์žˆ๋Š” DeepReadonly ์ œ๋„ค๋ฆญ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
  • ์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ฒ˜์—๋„ readonly๋ฅผ ์จ์„œ ์ฝ๊ธฐ๋Š” ํ—ˆ์šฉํ•˜๋˜ ์“ฐ๊ธฐ๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

let obj: { readonly [k: string]: number } = {};
// ๋˜๋Š” Readonly<{[k: string]: number}>
obj.hi = 45; // ~~ ํ˜•์‹์˜ ์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ฒ˜๋Š” ์ฝ๊ธฐ๋งŒ ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค.
obj = {...obj, hi: 12}; // ์ •์ƒ
obj = {...obj, bye: 345}; // ์ •์ƒ


# Item18. ๋งคํ•‘๋œ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ’์„ ๋™๊ธฐํ™”ํ•˜๊ธฐ

interface ScatterProps {
  // The Data
  xs: number[];
  ys: number[];
    
  // Display
  xRange: [number, number];
  yRange: [number, number];
    
  // Events
  onClick: (x: number, y: number, index: number) => void;
}

const REQUIRES_UPDATE: {[k in keyof ScatterProps]: boolean} = {
  xs: true,
  ys: true,
  xRange: true,
  yRange: true,
  color: true,
  onClick: false,
};

function shouldUpdate(
  oldProps: ScatterProps,
  newProps: ScatterProps
) {
  let k: keyof ScatterProps;
      
  for (k in oldProps) {
    if (oldProps[k] !== newProps[k] && REQUIRES_UPDATE[K]) {
      return true;
    }
  }
      
  return false;
}
  • [k in keyof ScatterProps]์€ ํƒ€์ž… ์ฒด์ปค์—๊ฒŒ REQUIRES_UPDATE๊ฐ€ ScatterProps๊ณผ ๋™์ผํ•œ ์†์„ฑ์„ ๊ฐ€์ ธ์•ผ ํ•œ๋‹ค๋Š” ์ •๋ณด๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
  • ๋‚˜์ค‘์— ScatterProps์— ์ƒˆ๋กœ์šด ์†์„ฑ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ ๋‹ค์Œ ์ฝ”๋“œ์™€ ๊ฐ™์€ ํ˜•ํƒœ๊ฐ€ ๋  ๊ฒƒ์ด๊ณ  REQUIRES_UPDATE์˜ ์ •์˜์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
interface ScatterProps {
  // ...
  onDoubleClick: () => void;
}

const REQUIRES_UPDATE: {[k in keyof ScatterProps]: boolean} = {
  // ~~~ 'onDoubleClick' ์†์„ฑ์ด ํƒ€์ž…์— ์—†์Šต๋‹ˆ๋‹ค.
}
  • ๋งŒ์•ฝ ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๊ฐ€ ๋œ๋‹ค.
const PROPS_REQUIRING_UPDATE: (keyof ScatterProps)[] = [
  'xs',
  'ys',
  // ...
];
  • ๋งคํ•‘๋œ ํƒ€์ž…์€ ํ•œ ๊ฐ์ฒด๊ฐ€ ๋˜ ๋‹ค๋ฅธ ๊ฐ์ฒด์™€ ์ •ํ™•ํžˆ ๊ฐ™์€ ์†์„ฑ์„ ๊ฐ€์ง€๊ฒŒ ํ•  ๋•Œ ์ด์ƒ์ ์ด๋‹ค.
  • ๋งคํ•‘๋œ ํƒ€์ž…์„ ์‚ฌ์šฉํ•ด์„œ ๊ด€๋ จ๋œ ๊ฐ’๊ณผ ํƒ€์ž…์„ ๋™๊ธฐํ™”ํ•˜๋„๋ก ํ•œ๋‹ค.
  • ์ธํ„ฐํŽ˜์ด์Šค์— ์ƒˆ๋กœ์šด ์†์„ฑ์„ ์ถ”๊ฐ€ํ•  ๋•Œ, ์„ ํƒ์„ ๊ฐ•์ œํ•˜๋„๋ก ๋งคํ•‘๋œ ํƒ€์ž…์„ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค.