Skip to content

ดีไซน์แพทเทิร์น (Design Patterns)

Creational Patterns

Singleton

คำอธิบาย: ทำให้มั่นใจได้ว่าคลาสจะมีอ็อบเจกต์เพียงตัวเดียว และให้จุดเข้าถึงที่เป็นไปได้จากทุกที่

typescript
class Singleton {
  private static instance: Singleton | null = null;
  private constructor() {}
  static getInstance(): Singleton {
    if (!Singleton.instance) {
      Singleton.instance = new Singleton();
    }
    return Singleton.instance;
  }
}

// การใช้งาน
const s1 = Singleton.getInstance();
const s2 = Singleton.getInstance();
console.log(s1 === s2); // Output: true

Factory

คำอธิบาย: แยกกระบวนการสร้างอ็อบเจกต์ออกจากคลาสหลัก โดยใช้เมทอดสำหรับสร้างอ็อบเจกต์

typescript
interface Pet {
  speak(): string;
}

class Dog implements Pet {
  speak() { return "Woof!"; }
}

class Cat implements Pet {
  speak() { return "Meow!"; }
}

function getPet(pet: "dog" | "cat" = "dog"): Pet {
  const pets: Record<string, Pet> = { dog: new Dog(), cat: new Cat() };
  return pets[pet];
}

// การใช้งาน
const pet = getPet("cat");
console.log(pet.speak()); // Output: Meow!

Builder

คำอธิบาย: แยกกระบวนการสร้างวัตถุซับซ้อนออกจากการแสดงผล เพื่อให้สร้างวัตถุประเภทต่างๆ ได้จากขั้นตอนเดียวกัน

typescript
class Pizza {
  crust = "";
  toppings: string[] = [];
}

class PizzaBuilder {
  private pizza = new Pizza();
  addCrust(crust: string): this {
    this.pizza.crust = crust;
    return this;
  }
  addTopping(topping: string): this {
    this.pizza.toppings.push(topping);
    return this;
  }
  build(): Pizza {
    return this.pizza;
  }
}

// การใช้งาน
const pizza = new PizzaBuilder().addCrust("thin").addTopping("pepperoni").build();

Prototype

คำอธิบาย: สร้างอ็อบเจกต์โดยการคัดลอก (clone) จากอ็อบเจกต์ที่มีอยู่แล้ว

typescript
interface Prototype<T> {
  clone(): T;
}

class ConcretePrototype implements Prototype<ConcretePrototype> {
  value: number;
  constructor(value: number) {
    this.value = value;
  }
  clone(): ConcretePrototype {
    return new ConcretePrototype(this.value);
  }
}

// การใช้งาน
const p1 = new ConcretePrototype(42);
const p2 = p1.clone();
console.log(p1 === p2); // Output: false

2. Structural Patterns

Adapter

คำอธิบาย: แปลง interface ของคลาสให้เข้ากันได้กับอินเตอร์เฟซที่ต้องการ

python
class OldSystem:
    def request(self):
        return "Old System"

class NewSystemAdapter:
    def __init__(self, old_system):
        self.old_system = old_system

    def new_request(self):
        return self.old_system.request()

# การใช้งาน
old = OldSystem()
adapter = NewSystemAdapter(old)
print(adapter.new_request())  # Output: Old System

Bridge

คำอธิบาย: แยกโครงสร้าง (abstraction) ออกจากการใช้งาน (implementation) เพื่อให้พัฒนาแยกกันได้

python
class Color:
    def apply_color(self): pass

class RedColor(Color):
    def apply_color(self): return "Red"

class Shape:
    def __init__(self, color):
        self.color = color

class Circle(Shape):
    def draw(self): return f"Circle filled with {self.color.apply_color()}"

# การใช้งาน
red = RedColor()
circle = Circle(red)
print(circle.draw())  # Output: Circle filled with Red

Composite

คำอธิบาย: จัดกลุ่มวัตถุเป็นโครงสร้างแบบต้นไม้ เพื่อให้ปฏิบัติกับแต่ละวัตถุหรือกลุ่มวัตถุเหมือนกัน

python
class Component:
    def operation(self): pass

class Leaf(Component):
    def operation(self): return "Leaf"

class Composite(Component):
    def __init__(self):
        self.children = []

    def add(self, component):
        self.children.append(component)

    def operation(self):
        results = []
        for child in self.children:
            results.append(child.operation())
        return "Composite(" + "+".join(results) + ")"

# การใช้งาน
leaf1 = Leaf()
leaf2 = Leaf()
composite = Composite()
composite.add(leaf1)
composite.add(leaf2)
print(composite.operation())  # Output: Composite(Leaf+Leaf)

Decorator

คำอธิบาย: เพิ่มพฤติกรรมให้อ็อบเจกต์โดยไม่เปลี่ยนโค้ดเดิม

python
class Coffee:
    def cost(self): return 5

class MilkDecorator:
    def __init__(self, coffee):
        self._coffee = coffee

    def cost(self):
        return self._coffee.cost() + 2

# การใช้งาน
coffee = Coffee()
milk_coffee = MilkDecorator(coffee)
print(milk_coffee.cost())  # Output: 7

Facade

คำอธิบาย: ให้จุดเข้าถึงเดียวสำหรับระบบซับซ้อน

python
class SubsystemA:
    def operation(self): return "Subsystem A\n"

class SubsystemB:
    def operation(self): return "Subsystem B\n"

class Facade:
    def __init__(self):
        self.a = SubsystemA()
        self.b = SubsystemB()

    def operation(self):
        return self.a.operation() + self.b.operation()

# การใช้งาน
facade = Facade()
print(facade.operation())  
# Output: 
# Subsystem A
# Subsystem B

Flyweight

คำอธิบาย: ลดการใช้ทรัพยากรโดยแบ่งปันข้อมูลที่ซ้ำกันระหว่างอ็อบเจกต์

python
class FlyweightFactory:
    _pool = {}

    @classmethod
    def get_flyweight(cls, key):
        if key not in cls._pool:
            cls._pool[key] = Flyweight(key)
        return cls._pool[key]

class Flyweight:
    def __init__(self, key):
        self.key = key

# การใช้งาน
f1 = FlyweightFactory.get_flyweight("A")
f2 = FlyweightFactory.get_flyweight("A")
print(f1 is f2)  # Output: True

Proxy

คำอธิบาย: ควบคุมการเข้าถึงอ็อบเจกต์ เช่น การตรวจสอบสิทธิ์หรือ lazy loading

python
class RealSubject:
    def request(self): return "Real Subject"

class Proxy:
    def __init__(self):
        self.real_subject = None

    def request(self):
        if not self.real_subject:
            self.real_subject = RealSubject()
        return self.real_subject.request()

# การใช้งาน
proxy = Proxy()
print(proxy.request())  # Output: Real Subject

3. Behavioral Patterns

Chain of Responsibility

คำอธิบาย: ส่งคำขอผ่านสายโซ่ของตัวประมวลผลจนกว่าจะได้รับการตอบสนอง

python
class Handler:
    def __init__(self, successor=None):
        self.successor = successor

    def handle(self, request): pass

class ConcreteHandler(Handler):
    def handle(self, request):
        if request < 10:
            return f"Handled by ConcreteHandler: {request}"
        elif self.successor:
            return self.successor.handle(request)

# การใช้งาน
handler_chain = ConcreteHandler()
response = handler_chain.handle(5)
print(response)  # Output: Handled by ConcreteHandler: 5

Command

คำอธิบาย: แปลงคำสั่งเป็นอ็อบเจกต์ เพื่อให้สามารถจัดเก็บหรือยกเลิกได้

python
class Receiver:
    def action(self): return "Action Performed"

class Command:
    def execute(self): pass

class SimpleCommand(Command):
    def __init__(self, receiver):
        self.receiver = receiver

    def execute(self):
        return self.receiver.action()

# การใช้งาน
receiver = Receiver()
command = SimpleCommand(receiver)
print(command.execute())  # Output: Action Performed

Iterator

คำอธิบาย: ให้จุดเข้าถึงลำดับข้อมูลโดยไม่เปิดเผยโครงสร้างภายใน

python
class MyIterator:
    def __init__(self, collection):
        self.collection = collection
        self.index = 0

    def has_next(self): return self.index < len(self.collection)

    def next(self):
        item = self.collection[self.index]
        self.index += 1
        return item

# การใช้งาน
collection = ["A", "B", "C"]
iterator = MyIterator(collection)
while iterator.has_next():
    print(iterator.next())  # Output: A -> B -> C

Mediator

คำอธิบาย: กลางในการสื่อสารระหว่างอ็อบเจกต์ เพื่อลดการพึ่งพาตรง

python
class Mediator:
    def notify(self, sender, event): pass

class Colleague:
    def __init__(self, mediator):
        self.mediator = mediator

class ConcreteColleague(Colleague):
    def send(self, event):
        self.mediator.notify(self, event)

# การใช้งาน
mediator = Mediator()
colleague = ConcreteColleague(mediator)
colleague.send("Event")  # Mediator จะจัดการเหตุการณ์

Observer

คำอธิบาย: แจ้งเตือนอ็อบเจกต์อื่นเมื่อมีการเปลี่ยนแปลงสถานะ

python
class Subject:
    def __init__(self):
        self._observers = []

    def attach(self, observer):
        self._observers.append(observer)

    def notify(self):
        for observer in self._observers:
            observer.update(self)

class Observer:
    def update(self, subject): pass

# การใช้งาน
subject = Subject()
observer = Observer()
subject.attach(observer)
subject.notify()  # Observer.update() ถูกเรียก

State

คำอธิบาย: เปลี่ยนพฤติกรรมของอ็อบเจกต์ตามสถานะที่เปลี่ยนแปลง

python
class State:
    def handle(self): pass

class Context:
    def __init__(self, state):
        self.state = state

    def set_state(self, state):
        self.state = state

    def request(self):
        return self.state.handle()

# การใช้งาน
class HappyState(State):
    def handle(self): return "Happy Mood"

context = Context(HappyState())
print(context.request())  # Output: Happy Mood

Strategy

คำอธิบาย: เปลี่ยนอัลกอริทึมขณะทำงานได้

python
class Strategy:
    def execute(self, a, b): pass

class AddStrategy(Strategy):
    def execute(self, a, b): return a + b

class SubtractStrategy(Strategy):
    def execute(self, a, b): return a - b

# การใช้งาน
strategy = AddStrategy()
print(strategy.execute(5, 3))  # Output: 8

Template Method

คำอธิบาย: กำหนดโครงสร้างของอัลกอริทึมในคลาสแม่ โดยอนุญาตให้คลาสลูกแทนที่ขั้นตอนเฉพาะ

python
class Game:
    def initialize(self): pass
    def play(self): pass
    def end(self): pass

    def template_method(self):
        self.initialize()
        self.play()
        self.end()

class Cricket(Game):
    def initialize(self): print("Cricket Initialized")

# การใช้งาน
game = Cricket()
game.template_method()  # Output: Cricket Initialized

Visitor

คำอธิบาย: เพิ่มการทำงานใหม่ให้อ็อบเจกต์โดยไม่แก้ไขคลาสเดิม

python
class Element:
    def accept(self, visitor): pass

class ConcreteElement(Element):
    def accept(self, visitor):
        visitor.visit(self)

class Visitor:
    def visit(self, element): pass

# การใช้งาน
element = ConcreteElement()
visitor = Visitor()
element.accept(visitor)  # Visitor.visit() ถูกเรียก

สรุปและตารางเปรียบเทียบ

Patternประเภทวัตถุประสงค์กรณีใช้งาน
SingletonCreationalจำกัดให้มีอ็อบเจกต์เพียงตัวเดียวDatabase Connection, Logger
FactoryCreationalสร้างอ็อบเจกต์ตามเงื่อนไขสร้างอ็อบเจกต์จาก Input
BuilderCreationalสร้างวัตถุซับซ้อนทีละขั้นตอนสร้าง Object Graph
PrototypeCreationalสร้างอ็อบเจกต์โดย Cloningปรับแต่งอ็อบเจกต์จากต้นฉบับ
AdapterStructuralแปลง InterfaceIntegrate Legacy Systems
BridgeStructuralแยก Abstraction กับ ImplementationGUI Libraries, Cross-Platform Code
CompositeStructuralจัดกลุ่มอ็อบเจกต์เป็น TreeFile System Navigation
DecoratorStructuralเพิ่มฟังก์ชันแบบ DynamicAdding Features to UI Components
FacadeStructuralให้จุดเข้าถึงเดียวสำหรับระบบที่ซับซ้อนSimplify Complex APIs
FlyweightStructuralแชร์อ็อบเจกต์เพื่อประหยัด MemoryText Editors, Large Datasets
ProxyStructuralควบคุมการเข้าถึงอ็อบเจกต์Lazy Loading, Security Control
Chain of Resp.Behavioralส่งคำขอผ่านโซ่Approvals, Event Handling
CommandBehavioralแปลงคำสั่งเป็นอ็อบเจกต์Undo/Redo, Transactional Systems
IteratorBehavioralเข้าถึง Collection โดยไม่รู้โครงสร้างTraversing Data Structures
MediatorBehavioralลดการเชื่อมโยงตรงระหว่างอ็อบเจกต์Chat Rooms, UI Components Communication
ObserverBehavioralแจ้งเตือนการเปลี่ยนแปลงEvent Listeners, MVC
StateBehavioralเปลี่ยนพฤติกรรมตามสถานะWorkflows, Game Characters
StrategyBehavioralเปลี่ยนอัลกอริทึมขณะทำงานPayment Methods, Sorting Algorithms
Template MethodBehavioralกำหนดโครงสร้างอัลกอริทึมFramework Development
VisitorBehavioralเพิ่มการทำงานโดยไม่แก้ไขคลาสเดิมOperations on Complex Object Structures

สรุป:

  • Creational → ควบคุมการสร้างอ็อบเจกต์
  • Structural → จัดระเบียบความสัมพันธ์ระหว่างอ็อบเจกต์
  • Behavioral → จัดการการสื่อสารและการโต้ตอบระหว่างอ็อบเจกต์