MVC ๊ตฌ์กฐ - ์˜ต์ €๋ฒ„ ํŒจํ„ด ( Observer Pattern )

2025. 9. 8. 17:37ยท๐Ÿ’™ ํ”„๋ก ํŠธ์—”๋“œ(FE)
728x90

 

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

์ด๋Ÿฐ ์ƒํ™ฉ์—์„œ ์ž์ฃผ ์“ฐ์ด๋Š” ๋””์ž์ธ ํŒจํ„ด์ด ๋ฐ”๋กœ ์˜ต์ €๋ฒ„ ํŒจํ„ด(Observer Pattern) ์ž…๋‹ˆ๋‹ค.

 

 


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

์˜ต์ €๋ฒ„ ํŒจํ„ด์€ ํ•œ ๊ฐ์ฒด์˜ ์ƒํƒœ ๋ณ€ํ™”๊ฐ€ ์žˆ์„ ๋•Œ, ๊ทธ ๊ฐ์ฒด๋ฅผ ๊ตฌ๋…(๊ด€์ฐฐ)ํ•˜๋Š” ๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค์—๊ฒŒ ์ž๋™์œผ๋กœ ํ†ต๋ณด๊ฐ€ ์ „๋‹ฌ๋˜๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

  • ์ƒํƒœ๋ฅผ ๊ฐ€์ง„ ๊ฐ์ฒด: Subject (๋˜๋Š” Publisher)
  • ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ๋ฐ˜์‘ํ•˜๋Š” ๊ฐ์ฒด: Observer (๋˜๋Š” Subscriber)

๋ชฉ์ 

์˜ต์ €๋ฒ„ ํŒจํ„ด์˜ ๋ชฉ์ ์€ ๋ชจ๋“ˆ ๊ฐ„์˜ ์˜์กด์„ฑ์„ ๋‚ฎ์ถ”๊ณ  ๊ฒฐํ•ฉ๋„๋ฅผ ์ค„์ด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฐœํ–‰(Publish)–๊ตฌ๋…(Subscribe) ๋ชจ๋ธ๋กœ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๊ตฌ๋…(Subscribe): "์ด ์ผ์ด ๋ฐœ์ƒํ•˜๋ฉด ๋‚˜์—๊ฒŒ ์•Œ๋ ค์ค˜!"๋ผ๊ณ  ์š”์ฒญํ•˜๋Š” ๊ฒƒ
  • ๋ฐœํ–‰(Publish): ์–ด๋–ค ์ผ์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ๊ตฌ๋…์ž๋“ค์—๊ฒŒ ์•Œ๋ฆผ์„ ๋ณด๋‚ด๋Š” ๊ฒƒ

 

์˜ˆ์‹œ

์‹ ๋ฌธ ๊ตฌ๋…์„ ์˜ˆ๋กœ ๋“ค์–ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

  • ์‹ ๋ฌธ์‚ฌ(Subject)๋Š” ์ƒˆ๋กœ์šด ์‹ ๋ฌธ์ด ๋‚˜์˜ค๋ฉด, ๊ตฌ๋…์ž ๋ฆฌ์ŠคํŠธ์— ์žˆ๋Š” ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์‹ ๋ฌธ์„ ๋ฟŒ๋ฆฝ๋‹ˆ๋‹ค.
  • ๊ตฌ๋…์ž(Observer)๋Š” ๊ตฌ๋…์„ ์‹ ์ฒญํ–ˆ๋‹ค๋ฉด ์ž๋™์œผ๋กœ ์‹ ๋ฌธ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค.
  • ๋ˆ„๊ตฐ๊ฐ€ ๊ตฌ๋…์„ ์ทจ์†Œํ•˜๋ฉด, ๊ทธ ์‚ฌ๋žŒ์€ ๋” ์ด์ƒ ์‹ ๋ฌธ์„ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ตฌ๋…์ž๊ฐ€ ์‹ ๋ฌธ์‚ฌ์— ๋งค๋ฒˆ “์˜ค๋Š˜ ์‹ ๋ฌธ ๋‚˜์™”๋‚˜์š”?” ํ•˜๊ณ  ๋ฌผ์–ด๋ณด๋Š” ๋ฐฉ์‹์ด ์•„๋‹ˆ๋ผ, ์‹ ๋ฌธ์‚ฌ๊ฐ€ ์•Œ์•„์„œ ๋ณด๋‚ด์ฃผ๋Š” ๊ตฌ์กฐ๋ผ์„œ ํ›จ์”ฌ ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.


๊ฐ„๋‹จํ•œ ์ฝ”๋“œ ์˜ˆ์‹œ (JavaScript)

 

๊ธฐ๋ณธ ์ฝ”๋“œ ๊ตฌ์กฐ

์˜ต์ €๋ฒ„ ํŒจํ„ด์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ์—ญํ• ์€ ์„ธ ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.

  1. ๊ตฌ๋…์ž๋ฅผ ๋“ฑ๋กํ•˜๋Š” ๊ธฐ๋Šฅ (subscribe)
  2. ๊ตฌ๋…์ž๋ฅผ ํ•ด์ง€ํ•˜๋Š” ๊ธฐ๋Šฅ (unsubscribe)
  3. ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ ์•Œ๋ฆผ์„ ๋ณด๋‚ด๋Š” ๊ธฐ๋Šฅ (notify)
class Observable {
    constructor() {
        this._observers = new Set();
    }

    subscribe(observer) {
        this._observers.add(observer);
    }

    unsubscribe(observer) {
        this._observers.delete(observer);
    }

    notify(data) {
        this._observers.forEach(observer => observer(data));
    }
}

 

์—ฌ๊ธฐ์„œ๋Š” Set ์ž๋ฃŒ๊ตฌ์กฐ๋ฅผ ์ด์šฉํ•ด ์ค‘๋ณต ์—†๋Š” ๊ตฌ๋…์ž ๋ฆฌ์ŠคํŠธ๋ฅผ ๊ด€๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ตฌ๋…์ž๋Š” subscribe๋ฅผ ํ†ตํ•ด ๋“ฑ๋ก๋˜๊ณ , notify๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉด ๊ตฌ๋…์ž๋“ค์—๊ฒŒ ๋ฐ์ดํ„ฐ๊ฐ€ ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.


ํ˜ธ์ถœ ๊ด€๊ณ„ ํ๋ฆ„

์˜ต์ €๋ฒ„ ํŒจํ„ด์—์„œ ํ˜ธ์ถœ ๊ด€๊ณ„๋Š” ๋‹จ์ˆœํ•ฉ๋‹ˆ๋‹ค.

Observable → Observer

  • Observer๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ์š”์ฒญ(pull)ํ•˜์ง€ ์•Š๊ณ , Observable์ด ์•Œ์•„์„œ ์•Œ๋ ค์ฃผ๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ Observer๋Š” ๋‹จ์ˆœํžˆ ๊ตฌ๋…๋งŒ ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ์ „๋‹ฌ๋ฐ›์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ๋ฐ”๋กœ ๋‹จ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ํ๋ฆ„ (Unidirectional Data Flow) ์ž…๋‹ˆ๋‹ค.

 

 

 

MVC ํŒจํ„ด์— Observer Pattern ์ ์šฉ :  M–V ๊ด€๊ณ„

 

์˜ต์ €๋ฒ„ ํŒจํ„ด์€ MVC(Model–View–Controller) ๊ตฌ์กฐ์—์„œ๋„ ์ž์ฃผ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  • Model: ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ , ๋ณ€ํ™”๊ฐ€ ์ƒ๊ธฐ๋ฉด ์•Œ๋ฆผ์„ ๋ฐœํ–‰ํ•ฉ๋‹ˆ๋‹ค. (Observable ์—ญํ• )
  • View: ์ƒํƒœ๋ฅผ ๊ตฌ๋…ํ•˜๊ณ , ๋ณ€ํ™”๊ฐ€ ์ƒ๊ธฐ๋ฉด ํ™”๋ฉด์„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค. (Observer ์—ญํ• )

์ด๋ฒคํŠธ ๋ฐœ์ƒ → ์ƒํƒœ ๋ณ€๊ฒฝ(Model) → ํ™”๋ฉด ๋ฐ˜์˜(View)

 

Todo App ์˜ˆ์‹œ

์˜ˆ๋ฅผ ๋“ค์–ด Todo ์•ฑ์—์„œ Model์ด todos ๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ , View๋Š” ์ด๋ฅผ ํ™”๋ฉด์— ํ‘œ์‹œํ•œ๋‹ค๊ณ  ํ•ด๋ด…์‹œ๋‹ค.

Model์ด Observable์„ ์ƒ์†๋ฐ›์œผ๋ฉด, ๊ตฌ๋… ๊ด€๋ฆฌ ๋กœ์ง์„ ๋”ฐ๋กœ ์ž‘์„ฑํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

class TodoModel extends Observable {
    constructor() {
        super();
        this.todos = [];
    }

    addTodo(todo) {
        this.todos = [...this.todos, todo];
        this.notify(this.todos);  // Observer๋“ค์—๊ฒŒ ์—…๋ฐ์ดํŠธ๋œ todos ์ „๋‹ฌ
    }
}

  • TodoModel์€ ์ƒˆ๋กœ์šด todo๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ ,
  • ์ƒํƒœ๊ฐ€ ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค notify๋กœ ๊ตฌ๋…์ž(View)์— ์•Œ๋ฆผ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

 

Store-TextView ์˜ˆ์‹œ

// Subject (๋ฐœํ–‰์ž)
const store = {
  state: { issueState: "open" },
  listeners: [],

  setState(patch) {
    this.state = { ...this.state, ...patch };
    this.notify();
  },

  subscribe(fn) {
    this.listeners.push(fn);
  },

  notify() {
    this.listeners.forEach(fn => fn(this.state));
  }
};

// Observer (๊ตฌ๋…์ž)
const TextView = {
  render(state) {
    console.log("ํ˜„์žฌ ์ƒํƒœ:", state.issueState);
  }
};

// ๊ตฌ๋… ์—ฐ๊ฒฐ
store.subscribe(TextView.render);

// ์‹คํ–‰ ์˜ˆ์‹œ
store.setState({ issueState: "closed" });
// ์ถœ๋ ฅ: "ํ˜„์žฌ ์ƒํƒœ: closed"

 

์—ฌ๊ธฐ์„œ store๋Š” Subject, TextView๋Š” Observer ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.
์ด๋ ‡๋“ฏ, store์˜ ์ƒํƒœ๊ฐ€ ๋ฐ”๋€Œ๋ฉด, ์ž๋™์œผ๋กœ TextView.render๊ฐ€ ํ˜ธ์ถœ๋˜๋ฉฐ  ํ™”๋ฉด์„ ๋‹ค์‹œ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

 

  • ์˜ต์ €๋ฒ„ ํŒจํ„ด์€ ๋ฐœํ–‰–๊ตฌ๋… ๋ชจ๋ธ๋กœ, ๋ชจ๋“ˆ ๊ฐ„ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”๊ณ  ๋‹จ๋ฐฉํ–ฅ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.
  • MVC ๊ตฌ์กฐ์—์„œ Model์€ Observable, View๋Š” Observer๊ฐ€ ๋˜์–ด ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ƒํƒœ ๋ณ€ํ™”๊ฐ€ UI์— ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค.
  • ์‹ค๋ฌด์—์„œ๋Š” React, Vue ๊ฐ™์€ ํ”„๋ ˆ์ž„์›Œํฌ ๋‚ด๋ถ€์—์„œ๋„ ์˜ต์ €๋ฒ„ ํŒจํ„ด์ด ๊ธฐ๋ณธ ์›๋ฆฌ๋กœ ํ™œ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค

 

 

์˜ต์ €๋ฒ„ ํŒจํ„ด์˜ ์žฅ์ 

  1. ๊ฒฐํ•ฉ๋„ ๊ฐ์†Œ
    • Subject๋Š” Observer์˜ ๊ตฌ์ฒด์ ์ธ ๋™์ž‘์„ ๋ชฐ๋ผ๋„ ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ƒฅ “์ƒํƒœ ๋ฐ”๋€Œ์—ˆ์–ด!”๋งŒ ์•Œ๋ฆฌ๋ฉด ๋.
  2. ์œ ์—ฐ์„ฑ ์ฆ๊ฐ€
    • ์ƒˆ๋กœ์šด Observer๋ฅผ ์ถ”๊ฐ€ํ•˜๋”๋ผ๋„ Subject ์ฝ”๋“œ๋ฅผ ์ˆ˜์ •ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.
  3. ์ž๋™ํ™”๋œ ๋ฐ˜์‘
    • ์ƒํƒœ ๋ณ€๊ฒฝ → ์•Œ๋ฆผ → UI ์—…๋ฐ์ดํŠธ๊ฐ€ ์ž๋™์œผ๋กœ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค.

 

  • ๋ทฐ๋ฅผ ์ง์ ‘ ์ผ์ผํžˆ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ ๋„, ๋ชจ๋ธ์— ๊ด€์‹ฌ์ด ์žˆ๋‹ค๊ณ  ๊ตฌ๋…์„ ํ•ด๋‘๊ณ , ์ž๋™์œผ๋กœ ๋ณ€๊ฒฝ๋˜๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • = Controller ์—์„œ ์ด๋ฒคํŠธ ๋ฐœ์ƒ์‹œ ๊ด€๋ จ๋œ ๋ทฐ๋ฅผ ์ง์ ‘ ์ผ์ผํžˆ ์—…๋ฐ์ดํŠธํ•˜์ง€ ์•Š์•„๋„ ๋ฉ๋‹ˆ๋‹ค.
  • Model ๊ฐ’๋งŒ ๋ฐ”๋€Œ๋ฉด ๊ทธ์™€ ์—ฐ๊ด€ํ•œ View ๊ฐ€ ์ž๋™์œผ๋กœ ๋ฐ”๋€๋‹ˆ๋‹ค

 

 

 


์ฃผ์˜ํ•  ์ 

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

์˜ต์ €๋ฒ„ ํŒจํ„ด์€ “์ƒํƒœ ๋ณ€ํ™” → ์ž๋™ ๋ฐ˜์‘”์ด๋ผ๋Š” ๋‹จ์ˆœํ•œ ์•„์ด๋””์–ด์—์„œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. 


ํ”„๋ก ํŠธ์—”๋“œ ํ”„๋ ˆ์ž„์›Œํฌ(React, Vue)์—์„œ ์ƒํƒœ ๊ด€๋ฆฌ(Store–View ๊ตฌ์กฐ)์— ๋งŽ์ด ์‘์šฉ๋˜๊ณ ,
๋ฐฑ์—”๋“œ์—์„œ๋„ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์•„ํ‚คํ…์ฒ˜๋ฅผ ์„ค๊ณ„ํ•  ๋•Œ ์ž์ฃผ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

 

 

 ํ•ต์‹ฌ์€ “๋‚ด๊ฐ€ ์ผ์ผ์ด ์ƒํƒœ๋ฅผ Pulling ํ•˜์ง€ ์•Š์•„๋„, ์ƒํƒœ๊ฐ€ ๋ฐ”๋€Œ๋ฉด ์ž๋™์œผ๋กœ ์•Œ๋ฆผ์ด ์ „๋‹ฌ๋œ๋‹ค”๋Š” ์ ์ž…๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿผ ์ด์–ด์„œ React์—์„œ ์˜ต์ €๋ฒ„ ํŒจํ„ด์ด ์–ด๋–ป๊ฒŒ ํ™œ์šฉ๋˜๋Š”์ง€๋ฅผ ์˜ˆ์‹œ๋กœ ๋ณด์—ฌ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.


React์—์„œ์˜ ์˜ต์ €๋ฒ„ ํŒจํ„ด

React๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์˜ต์ €๋ฒ„ ํŒจํ„ด๊ณผ ์œ ์‚ฌํ•œ ๊ฐœ๋…์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • ์ƒํƒœ(state) ๊ฐ€ ๋ฐ”๋€Œ๋ฉด,
  • ์ด๋ฅผ ๊ตฌ๋…ํ•˜๊ณ  ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž๋™์œผ๋กœ ๋‹ค์‹œ ๋ Œ๋”๋ง๋ฉ๋‹ˆ๋‹ค.

์ฆ‰, store → view ๊ตฌ์กฐ์™€ ๊ฑฐ์˜ ๋˜‘๊ฐ™์Šต๋‹ˆ๋‹ค.


๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ

import React, { useState } from "react";

function App() {
  const [issueState, setIssueState] = useState("open");

  return (
    <div>
      <TextView issueState={issueState} />
      <Menu setIssueState={setIssueState} />
    </div>
  );
}

function TextView({ issueState }) {
  return <p>ํ˜„์žฌ ์ƒํƒœ: {issueState}</p>;
}

function Menu({ setIssueState }) {
  return (
    <div>
      <button onClick={() => setIssueState("open")}>Open</button>
      <button onClick={() => setIssueState("closed")}>Close</button>
    </div>
  );
}

export default App;

๋™์ž‘ ์„ค๋ช…

  1. App ์ปดํฌ๋„ŒํŠธ๋Š” ์ƒํƒœ(issueState)๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
    → ์ด๊ฒŒ ๋ฐ”๋กœ Subject ์—ญํ• ์ž…๋‹ˆ๋‹ค.
  2. TextView ์ปดํฌ๋„ŒํŠธ๋Š” issueState๋ฅผ props๋กœ ๋ฐ›์•„ ํ™”๋ฉด์„ ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.
    → ์ด๊ฒŒ ๋ฐ”๋กœ Observer์ž…๋‹ˆ๋‹ค.
  3. ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ setIssueState๋กœ ์ƒํƒœ๋ฅผ ๋ฐ”๊พธ๋ฉด, React๋Š” ์ž๋™์œผ๋กœ ํ•ด๋‹น ์ƒํƒœ๋ฅผ ๊ตฌ๋…ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ฐพ์•„ ๋ฆฌ๋ Œ๋”๋งํ•ฉ๋‹ˆ๋‹ค.

์ •๋ฆฌ

  • ์ „ํ†ต์ ์ธ ์˜ต์ €๋ฒ„ ํŒจํ„ด์—์„œ๋Š” Subject → notify → Observer ๊ตฌ์กฐ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.
  • React์—์„œ๋Š” ์ด ํ๋ฆ„์ด state → ๋ฆฌ๋ Œ๋”๋ง → UI ์—…๋ฐ์ดํŠธ๋กœ ์ถ”์ƒํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋•๋ถ„์— ๊ฐœ๋ฐœ์ž๋Š” notify() ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ์ž‘์„ฑํ•  ํ•„์š” ์—†์ด, useState๋‚˜ useReducer๋งŒ์œผ๋กœ ์˜ต์ €๋ฒ„ ํŒจํ„ด์˜ ์ด์ ์„ ๋ˆ„๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ต์ €๋ฒ„ ํŒจํ„ด์€ ๋‹จ์ˆœํ•œ ์ด๋ก ์ด ์•„๋‹ˆ๋ผ, React์˜ ๊ทผ๊ฐ„์— ๋…น์•„ ์žˆ๋Š” ๊ฐœ๋…์ด๋ผ๊ณ  ์ดํ•ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

'๐Ÿ’™ ํ”„๋ก ํŠธ์—”๋“œ(FE)' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Webpack Tree Shaking ๋™์ž‘ ์›๋ฆฌ  (0) 2025.09.17
Webpack + Babel + TypeScript ์„ค์ • ๊ฐ€์ด๋“œ  (0) 2025.09.16
[Javascript] ์ด๋ฒคํŠธ ์ „ํŒŒ & ์ด๋ฒคํŠธ ์œ„์ž„  (1) 2025.09.08
[CoderPad] ๋ฆฌ์•กํŠธ ๊ฐ€์ƒ ์Šคํฌ๋กค (Virtualized List)  (5) 2025.06.22
Next.js 12 ์—์„œ React Query v4 + SSR ํ™œ์šฉํ•˜๊ธฐ  (0) 2025.05.01
'๐Ÿ’™ ํ”„๋ก ํŠธ์—”๋“œ(FE)' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • Webpack Tree Shaking ๋™์ž‘ ์›๋ฆฌ
  • Webpack + Babel + TypeScript ์„ค์ • ๊ฐ€์ด๋“œ
  • [Javascript] ์ด๋ฒคํŠธ ์ „ํŒŒ & ์ด๋ฒคํŠธ ์œ„์ž„
  • [CoderPad] ๋ฆฌ์•กํŠธ ๊ฐ€์ƒ ์Šคํฌ๋กค (Virtualized List)
์—ฐ์žŽ(lotus leaf)
์—ฐ์žŽ(lotus leaf)
  • ์—ฐ์žŽ(lotus leaf)
    lotus' s develog ๐Ÿƒ
    ์—ฐ์žŽ(lotus leaf)
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (79)
      • โœ๏ธ ๊ฐœ๋ฐœํšŒ๊ณ ๋ก (5)
      • ๐Ÿงฎ ์•Œ๊ณ ๋ฆฌ์ฆ˜ (3)
      • ๐Ÿ’™ ํ”„๋ก ํŠธ์—”๋“œ(FE) (19)
        • HTML (0)
        • CSS (0)
        • Javascript (0)
        • React (0)
        • Next.js (0)
        • webpack & babel (0)
      • ๐Ÿ’ป ๋ฐฑ์—”๋“œ(BE) (2)
        • Nest.js (0)
        • Express.js (0)
        • MySQL (1)
      • โš™๏ธ ์ธํ”„๋ผ(Devops) (2)
      • ๐Ÿค– AI (1)
      • ๐ŸŒ WEB (8)
      • ๐Ÿ’ป CS (16)
        • ์ž๋ฃŒ๊ตฌ์กฐ (0)
        • ์ปดํ“จํ„ฐ ๋„คํŠธ์›Œํฌ (1)
        • ์šด์˜์ฒด์ œ (0)
        • ์ธ๊ณต์ง€๋Šฅ (8)
        • ์›น ๋ณด์•ˆ (1)
        • ํด๋ผ์šฐ๋“œ ์ปดํ“จํŒ… (6)
      • ๐Ÿ–‹๏ธ DevLog (1)
      • ๐Ÿฆพ ๋กœ๋ณดํ‹ฑ์Šค (4)
      • ๐Ÿ“— ๋„ค์ด๋ฒ„๋ถ€์ŠคํŠธ์บ ํ”„ ์›น ๋ชจ๋ฐ”์ผ (0)
      • ๐ŸŽฎ Unity(C#) (10)
      • ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด (4)
        • C (4)
        • C++ (0)
        • Java (0)
        • Python (0)
      • MSA (1)
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
    • ํƒœ๊ทธ
    • ๋ฐฉ๋ช…๋ก
  • ๋งํฌ

  • ๊ณต์ง€์‚ฌํ•ญ

  • ์ธ๊ธฐ ๊ธ€

  • ํƒœ๊ทธ

    gaussian rbf svm
    ์กฐํ•ฉ
    ๊ธฐ์ดˆ์•Œ๊ณ ๋ฆฌ์ฆ˜
    ์•Œ๊ณ ๋ฆฌ์ฆ˜
    next.js12
    advaned detail
    ์ŠคํŒธ๋ฉ”์ผ๋ถ„๋ฅ˜๊ธฐ
    c์–ธ์–ด
    c++
    C
    soft margin svm
    nav2
    Devops #๋Œ€๊ทœ๋ชจํŠธ๋ž˜ํ”ฝ์ฒ˜๋ฆฌ
    ํŒŒ์ผํŠธ๋ฆฌ
    ros workspace
    turtlebot
    hard margin svm
    ์ดํ™”์—ฌ์ž๋Œ€ํ•™๊ต #๋„์ „ํ•™๊ธฐ์ œ
    auto-scaling
    ros bridge
    client-streaming
    isaac automator
    ์ŠคํŒธ๋ถ„๋ฅ˜๊ธฐ
    ๋ฆฌ์•กํŠธ
    deploy-aws
    ์ฝ”๋”ํŒจ๋“œ
    ๋ฐฑ์ค€
    C#
    AWS
    ์ˆœ์—ด
  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.6
์—ฐ์žŽ(lotus leaf)
MVC ๊ตฌ์กฐ - ์˜ต์ €๋ฒ„ ํŒจํ„ด ( Observer Pattern )
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”