• Mindscape ๐Ÿ”ฅ
    • Playlist ๐ŸŽง
  • Algorithm

    • 1018๋ฒˆ: ์ฒด์ŠคํŒ ๋‹ค์‹œ ์น ํ•˜๊ธฐ
    • 1966๋ฒˆ: ํ”„๋ฆฐํ„ฐ ํ
    • Python ์‹œ๊ฐ„ ์ดˆ๊ณผ ๋ฐฉ์ง€๋ฅผ ์œ„ํ•œ ํŒ
    • C++ std::vector ์‚ฌ์šฉ๋ฒ• ์ •๋ฆฌ
    • Vim ์‚ฌ์šฉ ๋งค๋‰ด์–ผ
  • Ubuntu

    • ๋ฆฌ๋ˆ…์Šค ์šฐ๋ถ„ํˆฌ GRUB ํฐํŠธ ๋ณ€๊ฒฝ
    • ์šฐ๋ถ„ํˆฌ ์ด๋ฏธ์ง€ ๋น„๋””์˜ค ์ธ๋„ค์ผ(๋ฏธ๋ฆฌ๋ณด๊ธฐ) ์•ˆ ๋ณด์ž„ ๋ฌธ์ œ ํ•ด๊ฒฐ
    • Wine ํ™˜๊ฒฝ์—์„œ ์นด์นด์˜คํ†ก ์‹คํ–‰ ์‹œ explorer.exe ๋œจ์ง€ ์•Š๊ฒŒ ํ•˜๋Š” ๋ฒ•
    • ์šฐ๋ถ„ํˆฌ Wine ์นด์นด์˜คํ†ก ์‚ฌ์ง„ ์ด๋ฏธ์ง€ ์Šคํฌ๋ฆฐ์ƒท ๋ถ™์—ฌ๋„ฃ๊ธฐ
    • Wine ์นด์นด์˜คํ†ก ์ด๋ชจ์ง€ ๊นจ์ง ๋ฌธ์ œ ํ•ด๊ฒฐ
    • Ubuntu ์œˆ๋„์šฐ ์• ๋‹ˆ๋ฉ”์ด์…˜ ๋„๊ธฐ
  • Wellness

    • ์ฐจ์ „์žํ”ผ (Psyllium Husk)
    • ์—‘์ŠคํŠธ๋ผ ๋ฒ„์ง„ ์˜ฌ๋ฆฌ๋ธŒ์œ  (Extra Virgin Olive Oil)
    • ์ž๊ฐ€๋น„๊ฐ•์„ธ์ฒ™ (Nasal Irrigation)
    • QCY HT08 (MeloBuds Pro Plus)
    • ์ฝ˜์„œํƒ€ (Concerta)
    • ์ธ๋ฐ๋†€ (Inderal)
    • ์„คํŠธ๋ž„๋ฆฐ (Sertraline)
    • ๋ฉœ๋ผํ† ๋‹Œ (Melatonin)
    • ์น˜๊ฒฝ๋ถ€ ๋งˆ๋ชจ์ฆ
    • ๋ฐ”๋ฒจ ์Šค์ฟผํŠธ (Barbell Squat)
  • Humanities

    • Nordvik, Russia
    • North Sentinel Island
    • ๋กฑ๊ณ ๋กฑ๊ณ (Rongorongo)
    • ๋ฐ”๋กœํฌ ์Œ์•… (Baroque Music)
  • Design

    • ๊ตฌ๊ธ€์˜ ์•„์ด์ฝ˜ ๋Œ€๊ฐœํŽธ โ€” 6๋…„ ๋งŒ์˜ ์‹ค์ˆ˜ ์ธ์ •
    • ์ œ๋Ÿด๋“œ ์  ํƒ€ โ€” ๋Ÿญ์…”๋ฆฌ ์Šคํฌ์ธ  ์›Œ์น˜์˜ ์ฐฝ์‹œ์ž
    • ๋ฐ”์šฐํ•˜์šฐ์Šค โ€” ํ˜„๋Œ€ ๋””์ž์ธ์˜ ์›์ 
  • Brands

    • NOMOS Glashรผtte
    • Frรฉdรฉrique Constant
    • KZ (Knowledge Zenith)
    • ์—์ŠคํŠธ๋ผ (AESTURA)
    • JINHAO (้‡‘่ฑช)
    • Herman Miller
    • ๋ฐ์Šค์ปค (DESKER)
    • ๋ฌด์‹ ์‚ฌ ์Šคํƒ ๋‹ค๋“œ (Musinsa Standard)
  • Finance

    • ํ˜„๋Œ€์นด๋“œ ZERO โ€” Edition2 vs Edition3 ๋น„๊ต
    • ์‹ ํ•œ์นด๋“œ ์ฒ˜์Œ
    • S&P 500 ETF ํˆฌ์ž ๊ฐ€์ด๋“œ
    • ํŒŒํ‚นํ†ต์žฅ vs CMA ํ†ต์žฅ
    • ๋ฒ„ํฌ์…” ํ•ด์„œ์›จ์ด (Berkshire Hathaway)
    • ๋น„ํŠธ์ฝ”์ธ(Bitcoin)
  • Products

    • ์˜ค๋””์˜ค ์ธํ„ฐํŽ˜์ด์Šค (Audio Interface)
    • ์ฟ ๋ฃจํ† ๊ฐ€ (KURUTOGA)
    • CX31993 DAC ๋™๊ธ€
    • ํด๋ Œ์ง• ๋ฐ€ํฌ (Cleansing Milk)
    • ํ”ผ์ ฏ ํ† ์ด (Fidget Toy)
    • ThinkPad
  • Programming Languages

    • 8.0. Statement Level Control Structures
    • 8. Subprogram
    • 9. Implementing Subprogram
    • 10.1. Abstract Data Types and Encapsulation Constructs
    • 10.2. Support for Object Oriented Programming
    • 11. Concurrency
    • 12. FPL (1)
    • 13. FPL (2)
    • 14. Exception Handling and Event Handling
    • Final Exam

12. Design Patterns

์ž‘์„ฑ 2026. 6. 12.ยท์ˆ˜์ • 2026. 6. 12.

Learning Goals

  • Design pattern์˜ ๋™๊ธฐ ์ดํ•ด (์†”๋ฃจ์…˜์˜ template๋กœ์„œ)
  • ๋‹ค์–‘ํ•œ design pattern ์œ ํ˜• ํ•™์Šต
  • Design pattern ์‚ฌ์šฉ ์‹œ์  ๋…ผ์˜
  • ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ์œ„ํ•œ ์ ์ ˆํ•œ design pattern ์ ์šฉ

Design Challenges

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

Design Principles

Application์—์„œ ๋ณ€ํ™”ํ•˜๋Š” ๋ถ€๋ถ„์„ ์‹๋ณ„ํ•˜์—ฌ ๋ณ€ํ•˜์ง€ ์•Š๋Š” ๋ถ€๋ถ„๊ณผ ๋ถ„๋ฆฌImpleementation์ด ์•„๋‹Œ interface์— ๋งž์ถฐ programInheritance๋ณด๋‹ค composition์„ ์„ ํ˜ธ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” object ๊ฐ„์˜ loosely coupled design ์ถ”๊ตฌClasses๋Š” extension์— ๋Œ€ํ•ด์„œ ์—ด๋ ค ์žˆ์–ด์•ผ ํ•˜๋‚˜, modification์— ๋Œ€ํ•ด์„œ๋Š” ๋‹ซํ˜€ ์žˆ์–ด์•ผ ํ•จ.

Design Patterns

"๊ฐ ํŒจํ„ด์€ ์šฐ๋ฆฌ ํ™˜๊ฒฝ์—์„œ ๋ฐ˜๋ณต์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์™€ ๊ทธ ๋ฌธ์ œ์— ๋Œ€ํ•œ ํ•ต์‹ฌ ํ•ด๊ฒฐ์ฑ…์„ ์„ค๋ช…ํ•จ. ์ด ํ•ด๊ฒฐ์ฑ…์€ ๋‘ ๋ฒˆ ๋‹ค์‹œ ๋˜‘๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๊ณ ๋„ ๋ฐฑ๋งŒ ๋ฒˆ ์ด์ƒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ" (Christopher Alexander, 1977)

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

Design Patterns Everywhere!

History of Patterns

  • "Pattern"์˜ ๊ฐœ๋…์€ 1977๋…„ Christopher Alexander์˜ A Pattern Language (2543๊ฐœ patterns)์—์„œ ์ฒ˜์Œ ๋“ฑ์žฅ
  • 1990๋…„ Gang of Four or "GoF"(Gamma, Helm, Johnson, Vlissides) ๊ทธ๋ฃน์ด design pattern ์นดํƒˆ๋กœ๊ทธ ํŽธ์ฐฌ
  • 1995๋…„ ์ฑ… Design Patterns: Elements of Reusable Object-Oriented Software๋Š” ์ด ๋ถ„์•ผ์˜ ๊ณ ์ „

Benefits of Using Patterns

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

Architecture vs. Design Patterns

  • Architecture
    • Application ๊ตฌ์กฐํ™”๋ฅผ ์œ„ํ•œ ์ƒ์œ„ ์ˆ˜์ค€์˜ framework
      • "RPC ๊ธฐ๋ฐ˜ client-server"
      • "์ถ”์ƒํ™” ๋ ˆ์ด์–ด๋ง"
      • "CORBA ๊ธฐ๋ฐ˜ ๋ถ„์‚ฐ ๊ฐ์ฒด ์ง€ํ–ฅ system"
  • ๊ณ„์‚ฐ component ๋ฐ ์ƒํ˜ธ์ž‘์šฉ ๊ด€์ ์—์„œ system ์ •์˜
  • Design Patterns
    • Architecture๋ณด๋‹ค ๋‚ฎ์€ ์ˆ˜์ค€ (๋•Œ๋•Œ๋กœ micro-architecture)
    • Application ๋‚ด ํ•˜์œ„ ๋ฌธ์ œ ํ•ด๊ฒฐ์„ ์œ„ํ•œ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํ˜‘์—…
      • Subsystem X๋ฅผ Subsystem Y์—์„œ ์–ด๋–ป๊ฒŒ ๋ถ„๋ฆฌ(decouple)ํ• ๊นŒ?
  • Why Design Patterns?
    • ๋†’์€ ์ถ”์ƒํ™” ์ˆ˜์ค€์—์„œ ๊ฐ์ฒด ์ง€ํ–ฅ ์žฌ์‚ฌ์šฉ ์ง€์›
    • ๊ฐ์ฒด ์ง€ํ–ฅ ๊ตฌํ˜„์„ ์•ˆ๋‚ดํ•˜๊ณ  ์ œ์•ฝํ•˜๋Š” "framework" ์ œ๊ณต

4 Essential Elements of Design Patterns

  • Name: Pattern ์‹๋ณ„
  • Problem: ๋ฌธ์ œ ๋ฐ context ๊ด€์ ์—์„œ pattern ์ ์šฉ ์‹œ์  ๊ธฐ์ˆ 
  • Solution: Design ๊ตฌ์„ฑ ์š”์†Œ, ๊ด€๊ณ„, ์ฑ…์ž„, ํ˜‘์—… ๊ธฐ์ˆ 
  • Consequences: Pattern ์ ์šฉ ๊ฒฐ๊ณผ ๋ฐ trade-off

How to Describe Design Patterns more fully

๋™๋ฃŒ ๊ฐœ๋ฐœ์ž๊ฐ€ pattern์„ ํ‰๊ฐ€, ์„ ํƒ, ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์ •๋ณด ์ „๋‹ฌ์ด ์ค‘์š”

  • Design pattern์„ ์œ„ํ•œ ํ˜•์‹
    • Pattern Name and Classification
    • Intent
    • Also Known As
    • Motivation
    • Applicability
    • Structure
    • Participants
    • Collaborations
    • Consequences
    • Implementation
    • Sample Code
    • Known Uses
    • Related Patterns

Organizing Design Patterns

  • By Purpose (pattern์˜ ์—ญํ•  ๋ฐ˜์˜)
    • Creational Patterns
    • Structural Patterns
    • Behavioral Patterns
  • By Scope: Pattern์ด ์ฃผ๋กœ ์–ด๋””์— ์ ์šฉ๋˜๋Š”์ง€ ๊ตฌ์ฒดํ™”
    • Classes
    • Objects

Design Patterns Space

alt text

Creational Patterns

"System์ด object ์ƒ์„ฑ ๋ฐฉ์‹๊ณผ ๋…๋ฆฝ์ ์ด๋„๋ก ๋งŒ๋“ค์–ด๋ผ."

  • ์ผ๋ฐ˜ constructor๊ฐ€ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ
    • Object ์ƒ์„ฑ ๋ฐฉ์‹/์‹œ์  ์ œ์–ด
    • ์–ธ์–ด ํ•œ๊ณ„ ๊ทน๋ณต (์˜ˆ: keyword/default args ๋ถ€์žฌ)
    • Polymorphic type ์ˆจ๊น€

Named Constructor (Idiom)

  • Creational pattern์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋ฒ•
class Llama {
public
    static Llama create_llama(String name) {
        return new Llama(name);
    }
private: // Making ctor private depends on our needs
    Llama(String name_in){ name = name_in; }
    String name;
};

Scenario: Polymorphic Objects

  • Problem: Client์—๊ฒŒ type์„ ๋…ธ์ถœํ•˜์ง€ ์•Š๊ณ  polymorphic object๋ฅผ ์ƒ์„ฑ ๋ฐ ์‚ฌ์šฉ
  • Solution: ์›ํ•˜๋Š” type์˜ object๋ฅผ ์ƒ์„ฑํ•˜๋˜, base class์˜ object๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜ ์ž‘์„ฑ

Factory Pattern (Function)

  • String์ด factory์— ์ƒ์„ฑํ•  type ์ „๋‹ฌ
Llama llama_factory(String name, String type) {
    if (type == "ninja_llama") {
        return new NinjaLlama(name);
    }
    if (type == "whooping_llama") {
        return new WhoopingLlama(name);
    }
    ...
}

Llama steve = llama_factory("Steve", "ninja_llama");

Factory Pattern (Class)

  • Client๊ฐ€ (์•„๋งˆ๋„) static method๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์˜ฌ๋ฐ”๋ฅธ type ์ƒ์„ฑ
class LlamaFactory {
public
    static Llama make_ninja_llama(string name) {
        return new NinjaLlama(name);
    }
    static Llama make_whooping_llama(string name) {
        return new WhoopingLlama(name);
    }
};

Llama steve =
    LlamaFactory.make_ninja_llama("Steve");

Scenario: Difficulty-Based Enemies

  • Polymorphic Enemy class ๊ณ„์ธต ๊ตฌ์กฐ์˜ ์ปดํ“จํ„ฐ ๊ฒŒ์ž„ ๊ตฌํ˜„ ์ค‘. ์„ ํƒ๋œ ๋‚œ์ด๋„์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๋ฒ„์ „์˜ enemy ์ƒ์„ฑ์„ ์›ํ•จ
  • "Normal" ๋‚œ์ด๋„: Regular goomba
  • "Hard" ๋‚œ์ด๋„: Spiked goomba
  • Bad Solution: Enemy ์ƒ์„ฑ ์‹œ์ ๋งˆ๋‹ค ๋‚œ์ด๋„ ํ™•์ธ
// !! DON'T DO THIS !!
Enemy* goomby = nullptr;
if (difficulty == "normal") {
    goomby = new Goomba();
}
else if (difficulty == "hard") {
    goomby = new SpikedGoomba();
}

Solution: Abstract Factory

          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         
          โ”‚AbstractEnemyFactoryโ”‚         
          โ”‚- create_goomba()   โ”‚         
          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜         
                  โ”‚    โ”‚                 
                  โ”‚    โ”‚                 
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”  โ”Œโ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚NormalEnemyFactoryโ”‚  โ”‚HardEnemyFactory โ”‚
โ”‚- create_goomba() โ”‚  โ”‚- create_goomba()โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
// Only have to do this once!
AbstractEnemyFactory factory = null;
if (difficulty == โ€œnormalโ€) {
    factory = new NormalEnemyfactory();
}
else if (difficulty == โ€œhardโ€) {
    factory = new HardEnemyFactory();
}
...
Enemy goomby = factory.create_goomba();
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   
   โ”‚ Enemy โ”‚   
   โ””โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”˜   
       โ”‚       
   โ”Œโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”   
   โ”‚Goomba โ”‚   
   โ””โ”€โ”€โ”€โ–ฒโ”€โ”€โ”€โ”˜   
       โ”‚       
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚Spiked Goombaโ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Scenario: Global Application State

  • Globalํ•˜๊ฒŒ access ๊ฐ€๋Šฅํ•œ application state ํ•„์š”. Data ์ ‘๊ทผ ๋ฐ ๊ฐฑ์‹  ์ œ์–ด ํ•„์š”
  • Bad solution: ์ˆœ์ˆ˜ global ๋ณ€์ˆ˜ (plz no)
  • Less bad solution: ๋ชจ๋“  state`๋ฅผ class์— ๋„ฃ๊ณ  global instance ๋ณด์œ 

Aside: When is Global State OK?

  • ๋ชจ๋“  ๊ณณ์—์„œ access ํ•„์š”, parameter ์ „๋‹ฌ์ด ์ฝ”๋“œ๋ฅผ ๊ณผ๋„ํ•˜๊ฒŒ ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ฆ
  • Parameter ์ „๋‹ฌ ์ค„์ด๋ ค๊ณ  global ๋ณ€์ˆ˜ ์‚ฌ์šฉ์€ BAD
  • Program ์™ธ๋ถ€์— ์ €์žฅ๋œ state (database, web API ๋“ฑ)

๊ฒฝ๊ณ 

Global ๋ณ€์ˆ˜๋Š” ์—ฌ์ „ํžˆ ๋‚˜์จ!

Singleton Pattern

  • "Class๊ฐ€ ๋‹จ ํ•˜๋‚˜์˜ instance`๋งŒ ๊ฐ–๋„๋ก ๋ณด์žฅํ•˜๊ณ , ์ด์— ๋Œ€ํ•œ global ์ ‘๊ทผ ์ง€์  ์ œ๊ณต"
public
- static get_instance() // named ctor

private
- static instance // the one instance
- Singleton() // ctor

Singleton (๊ตฌํ˜„)

class Singleton {
    public static Singleton get_instance() {
        if (Singleton.instance == null) {
            Singleton.instance = new Singleton();
        }
        return Singleton.instance;
    }
    private static Singleton instance = null;
    private Singleton() {
        spams = 42;
        System.out.println("Singleton created");
    }
    // Our global state
    private int spams;
    public int num_spams() {
        return spams;
    }
    public void add_spam() {
        spams += 1;
    }
}

Using the Singleton

  • Exercise: ์ด code์˜ ์ถœ๋ ฅ์€?
public
- static get_instance() // named ctor
- num_spams()
- add_spam() // adds 1 to num_spams

private
- static instance // the one instance
- Singleton() // ctor, prints message
- spams
class Main {
    public static void main(String[] args) {
        int spams = Singleton.get_instance().num_spams();
        System.out.println(spams);
        Singleton.get_instance().add_spam();
        spams = Singleton.get_instance().num_spams();
        System.out.println(spams);
    }
}

Using the Singleton (Solution)

  • Exercise: ์ด code์˜ ์ถœ๋ ฅ์€?
class Main {
    public static void main(String[] args) {
        int spams = Singleton.get_instance().num_spams();
        System.out.println(spams);
        Singleton.get_instance().add_spam();
        spams = Singleton.get_instance().num_spams();
        System.out.println(spams);
    }
}
  • Output
Singleton created
42
43

Singleton.get_instance()

  • ํƒ€์ดํ•‘์ด ๋งŽ์Œ. ๋งŒ์•ฝ ์ด๋ ‡๊ฒŒ ํ•œ๋‹ค๋ฉด?
Singleton s = Singleton.get_instance();
System.out.println(s.num_spams())
  • ๊ทธ๋ž˜์„œ, ์ข‹์€๊ฐ€? ์ข‹์ง€ ์•Š์€๊ฐ€?
  • Singleton.get_instance()๊ฐ€ ๋งค๋ฒˆ ๋™์ผํ•œ object๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ๋ณด์žฅ ์—†์Œ

Singleton: Design Scenario

  • ์นด๋“œ ๊ฒŒ์ž„ Euchre ์ปดํ“จํ„ฐ ๋ฒ„์ „ ๊ตฌํ˜„ ์ค‘. Game class๊ฐ€ ๊ฒŒ์ž„ state ์ €์žฅ
  • Application ์‹œ์ž‘ ์‹œ, Euchre ํ•œ ๊ฒŒ์ž„ ํ”Œ๋ ˆ์ด ํ›„ ์ข…๋ฃŒ
  • Game์„ singleton์œผ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š”๊ฐ€?

Make Game a Singleton?

  • ์ฐฌ์„ฑ
    • Application์— Game instance๊ฐ€ ํ•˜๋‚˜๋งŒ ์กด์žฌ
  • ๋ฐ˜๋Œ€
    • Game instance๊ฐ€ ์šฐ์—ฐํžˆ ํ•˜๋‚˜์ผ ๋ฟ, ํ•˜๋‚˜๋งŒ ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ์š”๊ตฌ์‚ฌํ•ญ ์—†์Œ
    • Singleton ํŒจํ„ด์€ application ์š”๊ตฌ์‚ฌํ•ญ์ด ๋‹จ ํ•˜๋‚˜์˜ instance ์กด์žฌ๋ฅผ ๋ช…์‹œํ•  ๋•Œ๋งŒ ์‚ฌ์šฉ
    • Singleton ํŒจํ„ด์€ ๋ชจ๋“  ๊ฒƒ์„ global๋กœ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ๋ณ€๋ช…์ด ์•„๋‹˜

Structural Patterns

  • ๊ธฐ์กด class interface๋กœ๋ถ€ํ„ฐ ์ƒˆ๋กœ์šด class interface ๊ตฌ์ถ•
  • ๊ตฌํ˜„ ์„ธ๋ถ€์‚ฌํ•ญ ์ˆจ๊น€
  • ๋” ๊น”๋”ํ•˜๊ณ  ํŠนํ™”๋œ interface ์ œ๊ณต
  • ์ต์ˆ™ํ•œ๊ฐ€?

Adapter Pattern

  • "Class์˜ interface๋ฅผ client๊ฐ€ ๊ธฐ๋Œ€ํ•˜๋Š” ๋‹ค๋ฅธ interface๋กœ ๋ณ€ํ™˜"
  • "Gang of Four" Design Patterns book
  • alt text
  • Problem: ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์€ ์žˆ์ง€๋งŒ ์›ํ•˜๋Š” ๋ฐฉ์‹์ด ์•„๋‹Œ object ๋ณด์œ 
    • ์‚ฌ์šฉํ•˜๊ธฐ ๋ฒˆ๊ฑฐ๋กญ๊ณ /๋ถˆํŽธํ•จ. Bug ๋ฐœ์ƒ ์‰ฌ์›€
  • Example
    • Iterator๋Š” ์žˆ์ง€๋งŒ collection์€ ์—†์Œ
    • For-each loop ์‹คํ–‰ ์›ํ•จ. Iterator๋กœ๋Š” ๋ถˆ๊ฐ€๋Šฅ, Iterable ํ•„์š”
public void printAll(Iterator itr) {
    // error: must implement Iterable
    for (String s : itr) {
        System.out.println(s);
    }
}

Adapter in Action

  • Solution: ์ œ๊ณต๋œ ๊ธฐ๋Šฅ๊ณผ ์›ํ•˜๋Š” ๊ธฐ๋Šฅ ์‚ฌ์ด๋ฅผ ์—ฐ๊ฒฐํ•˜๋Š” adapter object ์ƒ์„ฑ
public class IterableAdapter implements Iterable {
    private Iterator iterator;
    public IterableAdapter(Iterator itr) {
        this.iterator = itr;
    }
    public Iterator iterator() {
        return iterator;
    }
}
...
public void printAll(Iterator itr) {
    IterableAdapter adapter = new IterableAdapter(itr);
    for (String s : adapter) { ... } // works
}

Adapter Pattern (More Examples)

  • C++ fstream ์ดˆ๊ธฐ ๊ตฌํ˜„
  • C FILE macro๋ฅผ ์œ„ํ•œ Adapter

Other Structural Patterns

  • Composite: Client๊ฐ€ ๊ฐœ๋ณ„ object์™€ object ๊ทธ๋ฃน์„ ๋™์ผํ•˜๊ฒŒ ์ฒ˜๋ฆฌ
    • ์˜ˆ: PowerPoint์—์„œ object ์„ ํƒ ๋ฐ ์ด๋™
  • Proxy: "๋‹ค๋ฅธ object์— ๋Œ€ํ•œ ์ ‘๊ทผ ์ œ์–ด๋ฅผ ์œ„ํ•ด surrogate(๋Œ€๋ฆฌ์ž) ๋˜๋Š” placeholder ์ œ๊ณต"
    • ์˜ˆ: std::vector::reference

Composite Pattern

  • Example: ๊ทธ๋ฆฌ๊ธฐ ํŽธ์ง‘๊ธฐ ๊ฐ™์€ ๊ทธ๋ž˜ํ”ฝ application
    • ๋‹จ์ˆœ component๋กœ ๋ณต์žกํ•œ ๋‹ค์ด์–ด๊ทธ๋žจ ๊ตฌ์ถ•

alt text

Behavioral Patterns

  • "Behavioral ํŒจํ„ด์€ algorithm ๋ฐ object ๊ฐ„ ์ฑ…์ž„ ํ• ๋‹น๊ณผ ๊ด€๋ จ"
  • ์ด๋ฏธ ๋ณธ Behavioral pattern: Iterator pattern
  • ๊ตฌํ˜„ ๋ฐฉ์‹๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ container ์ˆœํšŒ๋ฅผ ์œ„ํ•œ ํ†ต์ผ๋œ interface

Scenario: โ€œLock-onโ€ in Action-Adventure Game

"ํ”Œ๋ ˆ์ด์–ด ์บ๋ฆญํ„ฐ๊ฐ€ ์ ์—๊ฒŒ โ€œlock-onโ€(์ด๋™๊ณผ ์ƒ๊ด€์—†์ด ์ ์„ ํ–ฅํ•ด ์–ผ๊ตด์„ ๋Œ๋ฆผ)ํ•  ์ˆ˜ ์žˆ๋Š” ์ปดํ“จํ„ฐ ๊ฒŒ์ž„์„ ๊ตฌํ˜„ ์ค‘์ด๋‹ค. lock-on๋œ ์ ์ด ์“ฐ๋Ÿฌ์ง€๋ฉด ์บ๋ฆญํ„ฐ๋Š” ํ•ด๋‹น ์ ์„ ๋” ์ด์ƒ ์กฐ์ค€ํ•˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค."

โ€œLock-onโ€: Not-so-good Implementation

  • Enemy๊ฐ€ ์“ฐ๋Ÿฌ์ง€๋ฉด, player character์˜ release_lock_on() ํ˜ธ์ถœ
class Player {
    public void
    release_lock_on(Enemy enemy) {
        if (enemy == locked_on) {
            locked_on = null;
        }
    }
    private Enemy locked_on;
}

class Enemy {
    // Called when the enemy is defeated
    public void on_death() {
        // Global accessor for the player
        // character
        get_player().release_lock_on(this);
    }
}
  • ์ด ์ ‘๊ทผ ๋ฐฉ์‹์˜ ๋ฌธ์ œ์ ์€?
    • Player`์™€ Enemy๊ฐ€ tightly coupled (๊ฐ•ํ•˜๊ฒŒ ๊ฒฐํ•ฉ)
    • ํ•˜๋‚˜๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ๋‹ค๋ฅธ ํ•˜๋‚˜๋„ ๋ณ€๊ฒฝํ•ด์•ผ ํ•จ
    • Player๊ฐ€ ๋‘˜ ์ด์ƒ์ด๋ผ๋ฉด?
    • Enemy๋ฅผ ์“ฐ๋Ÿฌ๋œจ๋ฆด ๋•Œ player์˜ "score"๋ฅผ ๊ฐฑ์‹ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด?
    • Enemy ์‚ฌ๋ง ์‹œ ์ƒˆ๋กœ์šด ์ž‘์—… ์ถ”๊ฐ€ ์‹œ, Enemy class๋ฅผ ์ˆ˜์ •ํ•˜๊ณ  ์ƒˆ feature์™€ couple`ํ•ด์•ผ ํ•จ

Observer Pattern (a.k.a. โ€œPublish-Subscribeโ€)

"๊ฐ์ฒด ๊ฐ„ ์ผ๋Œ€๋‹ค ์ข…์†์„ฑ์„ ์ •์˜ํ•˜์—ฌ, ๊ฐ์ฒด์˜ ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ๋ชจ๋“  ์ข…์† ๊ฐ์ฒด๊ฐ€ ์ž๋™์œผ๋กœ ํ†ต์ง€๋ฐ›๊ณ  update๋˜๋„๋ก ํ•œ๋‹ค."

alt text

Note: ๊ตฌ๋…/๊ตฌ๋… ์ทจ์†Œ๋Š” ๊ตฌํ˜„์— ๋”ฐ๋ผ ์ •์  or ๋น„์ •์ ์ผ ์ˆ˜ ์žˆ์Œ.

class Subject {
    public static void subscribe(Observer observer) {
        subscribers.Add(observer);
    }
    public static void unsubscribe(Observer observer)
    {
        subscribers.Remove(observer);
    }
    public static void change_state() {
        foreach (Observer observer in subscribers) {
            observer.update();
        }
    }
    private static List subscribers
        = new List();
}

class Observer {
    public void update() {
        System.out.println("Received update");
    }
}

class MainClass {
    public static void Main (string[] args) {
        Observer observer1 = new Observer();
        Observer observer2 = new Observer();
        Subject.subscribe(observer1);
        Subject.change_state();
        Subject.subscribe(observer2);
        Subject.change_state();
        Subject.unsubscribe(observer2);
        Subject.change_state();
    }
}
  • Exercise: "Received update"๊ฐ€ ๋ช‡ ๋ฒˆ ์ถœ๋ ฅ๋˜๋Š”๊ฐ€?

Observer for โ€œLock-onโ€ Feature

alt text

Abstract๋ž€ โ€œํŒŒ์ƒ ํด๋ž˜์Šค๋Š” ์ด method๋ฅผ ๋ฐ˜๋“œ์‹œ ์žฌ์ •์˜ํ•ด์•ผ ํ•œ๋‹คโ€๋Š” ์˜๋ฏธ

Observer for โ€œLock-onโ€ Feature (Implementation)

class Enemy {
    public static void subscribe(EnemyObserver observer) {
        subscribers.Add(observer);
    }
    public static void unsubscribe(EnemyObserver observer) {
        subscribers.Remove(observer);
    }
    public void on_death() {
        foreach (EnemyObserver observer in subscribers) {
            observer.update_enemy_defeated(this);
        }
    }
    private static List subscribers
        = new List();
}

interface EnemyObserver {
    void update_enemy_defeated(Enemy enemy);
}

class Player: EnemyObserver {
    public void update_enemy_defeated(Enemy enemy) {
        if (enemy == target) {
            target = null;
        }
    }
    public void lock_on(Enemy enemy) {
        target = enemy;
    }
    private Enemy target;
}

Observer update_ Functions

  • ์—ฌ๋Ÿฌ update_ ํ•จ์ˆ˜๋Š” ์„ธ๋ถ„ํ™” ์œ ์ง€
  • Update์— ๊ด€์‹ฌ ์—†๋Š” observer๋Š” ๋ฌด์‹œ ๊ฐ€๋Šฅ (๋นˆ ๊ตฌํ˜„)
  • Observer๊ฐ€ data๋ฅผ ๊ฐ€์ ธ์˜ค๊ฒŒ(pull) ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค, ์ƒˆ data๋ฅผ parameter๋กœ ์ „๋‹ฌ(push)ํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ 

Scenario: Damage-Dealing in Action Game

"ํ”Œ๋ ˆ์ด์–ด ์บ๋ฆญํ„ฐ๊ฐ€ ๋‹ค์–‘ํ•œ ์ ๊ณผ ์ „ํˆฌ๋ฅผ ๋ฒŒ์ด๋Š” ์ปดํ“จํ„ฐ ๊ฒŒ์ž„์„ ์ œ์ž‘ ์ค‘์ด๋‹ค. ํ”Œ๋ ˆ์ด์–ด๋‚˜ ์ ์ด ๊ณต๊ฒฉ์„ ๋ฐ›์œผ๋ฉด ํ”ผํ•ด๋ฅผ ์ž…๊ณ , ์ฒด๋ ฅ์ด 0์ด ๋˜๋ฉด ์‚ฌ๋ง, ํ”Œ๋ ˆ์ด์–ด๊ฐ€ ์‚ฌ๋งํ•˜๋ฉด ๊ฒŒ์ž„์ด ์ข…๋ฃŒ๋œ๋‹ค. ์ ์ด ์‚ฌ๋งํ•˜๋ฉด ์•„์ดํ…œ์„ dropํ•œ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ํ”Œ๋ ˆ์ด์–ด/์ ์€ ๋’ค๋กœ ๋ฐ€๋ ค๋‚˜๋ฉฐ ์†Œ๋ฆฌ๋ฅผ ๋‚ด๋ฑ‰๋Š”๋‹ค."

Damage-Dealing: First Design

  • ์ฐธ๊ณ : receive_hit()์€ Actor๊ฐ€ damage ์ž…์„ ๋•Œ ํ˜ธ์ถœ๋จ alt text
class Actor {
    public void receive_hit(float damage) {
        health -= damage;
    }
    public float get_health() { return health; }
    private float health = 42;
    public void apply_knockback() {
        System.out.println("Knocked back!");
    }
}

class Enemy extends Actor {
    public void receive_hit(float damage) {
        base.receive_hit(damage);
        if (get_health() <= 0) {
            System.out.println("Dropped an item");
        }
        else {
            System.out.println("Weah");
            apply_knockback();
        }
    }
}

class Player extends Actor {
    public void receive_hit(float damage) {
        base.receive_hit(damage);
        if (get_health() <= 0) {
            System.out.println("Game over");
        }
        else {
            System.out.println("Ow");
            apply_knockback();
        }
    }
}

Template Method Pattern

"โ€œ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ณจ๊ฒฉ์„ ํ•˜๋‚˜์˜ ์ž‘์—…์œผ๋กœ ์ •์˜ํ•˜๊ณ  ์ผ๋ถ€ ๋‹จ๊ณ„๋ฅผ ํ•˜์œ„ ํด๋ž˜์Šค๋กœ ๋ฏธ๋ฃจ๋Š” ํŒจํ„ด์ด๋‹ค. templete method ํŒจํ„ด์€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๊ตฌ์กฐ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์œผ๋ฉด์„œ ํ•˜์œ„ ํด๋ž˜์Šค๊ฐ€ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ํŠน์ • ๋‹จ๊ณ„๋ฅผ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.โ€"

Damage-Dealing: Template Method

alt text

Damage-Dealing: Template Method (Implementation)

Abstract class Actor {
    public void receive_hit(float damage) {
        health -= damage;
        if (get_health() <= 0) {
            on_death();
        }
        else {
            play_damaged_sound();
            apply_knockback();
        }
    }
    protected void on_death();
    protected void play_damaged_sound();
    // Other members same as before
}

class Enemy extends Actor {
    protected void on_death() {
        System.out.println("Dropped an item");
    }
    protected void play_damaged_sound() {
        System.out.println("Weah");
    }
}

class Player extends Actor {
    protected void on_death() {
        System.out.println("Game over");
    }
    protected void play_damaged_sound() {
        System.out.println("Ow");
    }
}

Template Method: The โ€œHollywood Principleโ€

  • ์ฒซ ๊ตฌํ˜„: Derived class๊ฐ€ Base class์˜ receive_hit() ํ˜ธ์ถœ
  • Template method ๊ตฌํ˜„: Non-virtual base class receive_hit()์ด derived class method ํ˜ธ์ถœ

"Donโ€™t call us, weโ€™ll call you!"

Exercise: Updating our Algorithm

  • Knock back๋  ์ˆ˜ ์—†๋Š” TurretEnemy ์ถ”๊ฐ€ ๊ฐ€์ •
  • ์ƒˆ enemy type ํฌํ•จํ•˜๋„๋ก design ์ˆ˜์ • [UML ๋‹ค์ด์–ด๊ทธ๋žจ: Slide 54์™€ ๋™์ผ]
์ตœ๊ทผ ์ˆ˜์ •: 26. 6. 12. ์˜คํ›„ 3:28
Contributors: kmbzn, Claude Sonnet 4.6

BUILT WITH

CloudflareNode.jsGitHubGitVue.jsJavaScriptVSCodenpm

All trademarks and logos are property of their respective owners.
ยฉ 2026 kmbzn ยท MIT License