Skip to content

แหล่งอ้างอิง

patterns.dev => www.patterns.dev faviconhttps://www.patterns.dev/

refactoring.guru => refactoring.guru faviconhttps://refactoring.guru/

สรุปจาก refactoring

Creational patterns

Singleton pattern

รูปแบบที่รับประกันว่าคลาสจะมีอินสแตนซ์เพียงตัวเดียวและมีจุดเข้าถึงกลาง

ตัวอย่าง:

typescript
class Database {
  private static instance: Database;

  private constructor() {
    // เชื่อมต่อกับฐานข้อมูล
  }

  public static getInstance(): Database {
    if (!Database.instance) {
      Database.instance = new Database();
    }
    return Database.instance;
  }

  public query(sql: string): any {
    // ค้นหาข้อมูล
  }
}

// การใช้งาน
const db1 = Database.getInstance();
const db2 = Database.getInstance();
console.log(db1 === db2); // true - เป็นอินสแตนซ์เดียวกัน

Factory pattern

สร้างอินเตอร์เฟซสำหรับสร้างวัตถุ แต่ให้คลาสย่อยตัดสินใจว่าจะสร้างอินสแตนซ์ของคลาสใด

ตัวอย่าง:

typescript
interface Product {
  operation(): string;
}

class ConcreteProduct1 implements Product {
  operation(): string {
    return "ConcreteProduct1";
  }
}

class ConcreteProduct2 implements Product {
  operation(): string {
    return "ConcreteProduct2";
  }
}

class Creator {
  public createProduct(type: string): Product {
    if (type === "product1") {
      return new ConcreteProduct1();
    } else {
      return new ConcreteProduct2();
    }
  }
}

// การใช้งาน
const creator = new Creator();
const product1 = creator.createProduct("product1");
console.log(product1.operation()); // "ConcreteProduct1"

Abstract Factory pattern

สร้างอินเตอร์เฟซสำหรับสร้างครอบครัวของวัตถุที่เกี่ยวข้องกันโดยไม่ต้องระบุคลาสที่แน่นอน

ตัวอย่าง:

typescript
interface Button {
  render(): void;
}

interface Checkbox {
  render(): void;
}

class WindowsButton implements Button {
  render(): void {
    console.log("Render Windows button");
  }
}

class MacButton implements Button {
  render(): void {
    console.log("Render Mac button");
  }
}

class WindowsCheckbox implements Checkbox {
  render(): void {
    console.log("Render Windows checkbox");
  }
}

class MacCheckbox implements Checkbox {
  render(): void {
    console.log("Render Mac checkbox");
  }
}

interface GUIFactory {
  createButton(): Button;
  createCheckbox(): Checkbox;
}

class WindowsFactory implements GUIFactory {
  createButton(): Button {
    return new WindowsButton();
  }
  createCheckbox(): Checkbox {
    return new WindowsCheckbox();
  }
}

class MacFactory implements GUIFactory {
  createButton(): Button {
    return new MacButton();
  }
  createCheckbox(): Checkbox {
    return new MacCheckbox();
  }
}

Builder pattern

แยกการสร้างวัตถุที่ซับซ้อนออกจากการแสดงผล เพื่อให้สามารถสร้างวัตถุที่แตกต่างกันได้โดยใช้กระบวนการสร้างเดียวกัน

ตัวอย่าง:

typescript
class Car {
  seats: number = 0;
  engine: string = "";
  tripComputer: boolean = false;
  gps: boolean = false;
}

class CarBuilder {
  private car: Car;

  constructor() {
    this.reset();
  }

  public reset(): void {
    this.car = new Car();
  }

  public setSeats(seats: number): CarBuilder {
    this.car.seats = seats;
    return this;
  }

  public setEngine(engine: string): CarBuilder {
    this.car.engine = engine;
    return this;
  }

  public setTripComputer(hasTripComputer: boolean): CarBuilder {
    this.car.tripComputer = hasTripComputer;
    return this;
  }

  public setGPS(hasGPS: boolean): CarBuilder {
    this.car.gps = hasGPS;
    return this;
  }

  public getResult(): Car {
    const result = this.car;
    this.reset();
    return result;
  }
}

// การใช้งาน
const builder = new CarBuilder();
const sportsCar = builder
  .setSeats(2)
  .setEngine("SportEngine")
  .setTripComputer(true)
  .setGPS(true)
  .getResult();

Prototype pattern

สร้างวัตถุใหม่โดยการคัดลอกวัตถุที่มีอยู่แล้ว โดยไม่ต้องขึ้นอยู่กับคลาสของวัตถุนั้น

ตัวอย่าง:

typescript
interface Prototype {
  clone(): Prototype;
}

class ConcretePrototype implements Prototype {
  public field1: string;
  public field2: number;

  constructor(prototype?: ConcretePrototype) {
    if (prototype) {
      this.field1 = prototype.field1;
      this.field2 = prototype.field2;
    }
  }

  public clone(): Prototype {
    return new ConcretePrototype(this);
  }
}

// การใช้งาน
const original = new ConcretePrototype();
original.field1 = "value";
original.field2 = 42;

const copy = original.clone() as ConcretePrototype;
console.log(copy.field1); // "value"
console.log(copy.field2); // 42

Structural patterns

Adapter

ช่วยให้อินเตอร์เฟซที่เข้ากันไม่ได้สามารถทำงานร่วมกันได้

ตัวอย่าง:

typescript
interface Target {
  request(): string;
}

class Adaptee {
  public specificRequest(): string {
    return "Specific request";
  }
}

class Adapter implements Target {
  private adaptee: Adaptee;

  constructor(adaptee: Adaptee) {
    this.adaptee = adaptee;
  }

  public request(): string {
    return `Adapter: ${this.adaptee.specificRequest()}`;
  }
}

// การใช้งาน
const adaptee = new Adaptee();
const adapter = new Adapter(adaptee);
console.log(adapter.request()); // "Adapter: Specific request"

Bridge

แยกนามธรรมออกจากการนำไปใช้ เพื่อให้ทั้งสองส่วนสามารถเปลี่ยนแปลงได้อย่างอิสระ

ตัวอย่าง:

typescript
interface Implementation {
  operationImplementation(): string;
}

class ConcreteImplementationA implements Implementation {
  operationImplementation(): string {
    return "ConcreteImplementationA";
  }
}

class ConcreteImplementationB implements Implementation {
  operationImplementation(): string {
    return "ConcreteImplementationB";
  }
}

class Abstraction {
  protected implementation: Implementation;

  constructor(implementation: Implementation) {
    this.implementation = implementation;
  }

  public operation(): string {
    return `Abstraction: ${this.implementation.operationImplementation()}`;
  }
}

class ExtendedAbstraction extends Abstraction {
  public operation(): string {
    return `ExtendedAbstraction: ${this.implementation.operationImplementation()}`;
  }
}

Composite

ช่วยให้สามารถจัดเรียงวัตถุในรูปแบบโครงสร้างต้นไม้ และทำงานกับวัตถุเดี่ยวและกลุ่มวัตถุในแบบเดียวกัน

ตัวอย่าง:

typescript
abstract class Component {
  protected parent: Component | null = null;

  public setParent(parent: Component | null): void {
    this.parent = parent;
  }

  public getParent(): Component | null {
    return this.parent;
  }

  public add(component: Component): void {}
  public remove(component: Component): void {}
  public isComposite(): boolean {
    return false;
  }

  public abstract operation(): string;
}

class Leaf extends Component {
  public operation(): string {
    return "Leaf";
  }
}

class Composite extends Component {
  protected children: Component[] = [];

  public add(component: Component): void {
    this.children.push(component);
    component.setParent(this);
  }

  public remove(component: Component): void {
    const index = this.children.indexOf(component);
    this.children.splice(index, 1);
    component.setParent(null);
  }

  public isComposite(): boolean {
    return true;
  }

  public operation(): string {
    const results = [];
    for (const child of this.children) {
      results.push(child.operation());
    }
    return `Branch(${results.join("+")})`;
  }
}