본문으로 건너뛰기

เนื้อหาภาษาไทย / 태국어 콘텐츠

시스템 가이드 검수 완료된 콘텐츠

การใช้ Design Patterns: Factory Pattern

บทความนี้แนะนำ Factory Pattern ซึ่งเป็น Design Pattern ที่ช่วยในการสร้าง Object โดยไม่ต้องระบุ Class ที่จะสร้างโดยตรง ทำให้โค้ดมีความยืดหยุ่นและง่ายต่อการเปลี่ย...

การใช้ Design Patterns: Factory Pattern

ในบทความก่อนหน้า เราได้เรียนรู้เกี่ยวกับ Singleton Pattern ซึ่งเป็น Design Pattern ที่ช่วยให้เราควบคุมการสร้าง Object ให้มีเพียง Instance เดียว ในบทนี้ เราจะมาทำความรู้จักกับ Factory Pattern ซึ่งเป็น Design Pattern ที่ช่วยให้เราสร้าง Object โดยไม่ต้องระบุ Class ที่จะสร้างโดยตรง ทำให้โค้ดของเรามีความยืดหยุ่นและง่ายต่อการเปลี่ยนแปลงมากขึ้น

Factory Pattern คืออะไร

Factory Pattern เป็น Creational Design Pattern ที่ให้ Interface สำหรับการสร้าง Object แต่ปล่อยให้ Subclass ตัดสินใจว่าจะสร้าง Object ของ Class ไหน พูดง่ายๆ คือ Factory Pattern เปรียบเสมือนโรงงานที่รับคำสั่ง (Interface) แล้วผลิตสินค้า (Object) ที่แตกต่างกันไปตามคำสั่งนั้น

ทำไมต้องใช้ Factory Pattern?

ลองจินตนาการว่าเรามี Class ที่ต้องสร้าง Object ที่แตกต่างกันไปตามเงื่อนไขบางอย่าง เช่น ประเภทของผู้ใช้งาน, ระบบปฏิบัติการ, หรือรูปแบบการแสดงผล ถ้าเราสร้าง Object โดยตรงใน Class นั้น โค้ดของเราจะซับซ้อนและยากต่อการเปลี่ยนแปลง หากเราต้องการเพิ่มประเภทใหม่ เราจะต้องแก้ไข Class เดิม ซึ่งอาจทำให้เกิด Bug และทำให้โค้ดของเราไม่ยืดหยุ่น

Factory Pattern ช่วยแก้ปัญหานี้ โดยการแยกส่วนการสร้าง Object ออกจาก Class ที่ใช้งาน Object ทำให้เราสามารถเพิ่มประเภทใหม่ได้ง่ายๆ โดยไม่ต้องแก้ไข Class เดิม นอกจากนี้ Factory Pattern ยังช่วยลดการ Coupling ระหว่าง Class ทำให้โค้ดของเรามีความยืดหยุ่นและง่ายต่อการทดสอบ

การ Implement Factory Pattern

Factory Pattern มีหลายรูปแบบ แต่รูปแบบที่พบบ่อยที่สุดคือ Simple Factory, Factory Method, และ Abstract Factory ในบทนี้ เราจะเน้นที่ Simple Factory ซึ่งเป็นรูปแบบที่ง่ายที่สุดและเหมาะสำหรับผู้เริ่มต้น

Simple Factory

Simple Factory เป็น Class ที่มี Method สำหรับการสร้าง Object โดย Method นั้นจะรับ Parameter ที่ระบุประเภทของ Object ที่ต้องการสร้าง และจะ return Object ที่ถูกต้องตามประเภทนั้น

ตัวอย่างเช่น สมมติว่าเรามี Interface PaymentMethod และ Class ที่ Implement Interface นี้ 2 Class คือ CreditCardPayment และ PayPalPayment

interface PaymentMethod {
  public function pay(float $amount): bool;
}

class CreditCardPayment implements PaymentMethod {
  public function pay(float $amount): bool {
    // logic สำหรับการจ่ายด้วยบัตรเครดิต
    echo "จ่ายด้วยบัตรเครดิตจำนวน {$amount} บาท\n";
    return true;
  }
}

class PayPalPayment implements PaymentMethod {
  public function pay(float $amount): bool {
    // logic สำหรับการจ่ายด้วย PayPal
    echo "จ่ายด้วย PayPal จำนวน {$amount} บาท\n";
    return true;
  }
}

เราสามารถสร้าง Simple Factory เพื่อสร้าง Object ของ PaymentMethod ได้ดังนี้:

class PaymentMethodFactory {
  public static function create(string $type): PaymentMethod {
    switch ($type) {
      case 'credit_card':
        return new CreditCardPayment();
      case 'paypal':
        return new PayPalPayment();
      default:
        throw new InvalidArgumentException("Invalid payment method type: {$type}");
    }
  }
}

การใช้งาน

เราสามารถใช้งาน Factory ได้ดังนี้:

try {
  $paymentMethod = PaymentMethodFactory::create('credit_card');
  $paymentMethod->pay(100);

  $paymentMethod = PaymentMethodFactory::create('paypal');
  $paymentMethod->pay(200);

  $paymentMethod = PaymentMethodFactory::create('invalid_type'); // จะ throw Exception
} catch (InvalidArgumentException $e) {
  echo "Error: " . $e->getMessage() . "\n";
}

ข้อดีและข้อเสียของ Simple Factory

  • ข้อดี:
    • ลดการ Coupling ระหว่าง Class
    • ง่ายต่อการเพิ่มประเภทใหม่
    • ทำให้โค้ดมีความยืดหยุ่นและง่ายต่อการเปลี่ยนแปลง
  • ข้อเสีย:
    • Factory Class อาจมีขนาดใหญ่และซับซ้อน หากมีประเภทให้สร้างจำนวนมาก
    • Factory Class อาจกลายเป็น God Object ที่ทำทุกอย่าง

ข้อดีและข้อเสียของ Factory Pattern โดยรวม

Factory Pattern ไม่ได้มีแค่ Simple Factory รูปแบบเดียว แต่ไม่ว่าจะเป็น Factory Method หรือ Abstract Factory ก็มีข้อดีข้อเสียที่ควรพิจารณา ดังนี้:

ข้อดี:

  • Abstraction of Object Creation: Factory Pattern ช่วยซ่อนความซับซ้อนในการสร้าง Object จาก Client Code Client Code ไม่จำเป็นต้องรู้ว่า Object ถูกสร้างอย่างไร หรือต้องมี Parameter อะไรบ้าง
  • Loose Coupling: ลดการพึ่งพากันระหว่าง Class Client Code พึ่งพาเพียง Factory Interface เท่านั้น ไม่ได้พึ่งพา Concrete Class โดยตรง
  • Flexibility and Extensibility: ง่ายต่อการเพิ่มประเภท Object ใหม่ โดยไม่ต้องแก้ไข Client Code
  • Centralized Object Creation Logic: รวม Logic การสร้าง Object ไว้ในที่เดียว ทำให้ง่ายต่อการบำรุงรักษาและปรับปรุง

ข้อเสีย:

  • Increased Complexity: อาจเพิ่มความซับซ้อนให้กับ Codebase โดยเฉพาะอย่างยิ่งหากใช้ Factory Pattern ที่ซับซ้อน เช่น Abstract Factory
  • Potential for Over-Engineering: หากใช้ Factory Pattern ในสถานการณ์ที่ไม่จำเป็น อาจทำให้ Codebase ซับซ้อนเกินความจำเป็น
  • Maintenance Overhead: เมื่อเพิ่มประเภท Object ใหม่ อาจต้องแก้ไข Factory Class ซึ่งอาจส่งผลกระทบต่อ Code ที่ใช้งาน Factory

Trade-offs และแนวปฏิบัติที่ดี

การเลือกใช้ Design Pattern ใดๆ ก็ตาม ย่อมมี Trade-offs เสมอ การใช้ Factory Pattern ก็เช่นกัน เราควรพิจารณา Trade-offs เหล่านี้อย่างรอบคอบก่อนตัดสินใจใช้งาน:

  • Complexity vs. Flexibility: Factory Pattern ช่วยเพิ่มความยืดหยุ่นให้กับ Code แต่ก็อาจเพิ่มความซับซ้อนด้วยเช่นกัน หากความยืดหยุ่นไม่ใช่สิ่งจำเป็น อาจไม่คุ้มค่าที่จะใช้ Factory Pattern
  • Coupling vs. Cohesion: Factory Pattern ช่วยลด Coupling แต่ก็อาจลด Cohesion ได้เช่นกัน หาก Factory Class ทำหน้าที่มากเกินไป อาจทำให้ Class นั้นขาด Cohesion

แนวปฏิบัติที่ดี:

  • Use Factory Pattern when needed: อย่าใช้ Factory Pattern เพียงเพราะคิดว่ามันเป็น Design Pattern ที่ดี ควรใช้เมื่อจำเป็นต้องสร้าง Object ที่แตกต่างกันไปตามเงื่อนไข
  • Keep Factory Simple: พยายามทำให้ Factory Class มีขนาดเล็กและง่ายต่อการเข้าใจ หลีกเลี่ยงการใส่ Logic ที่ซับซ้อนลงใน Factory
  • Consider Alternatives: ก่อนที่จะใช้ Factory Pattern ลองพิจารณาทางเลือกอื่น เช่น Dependency Injection หรือ Service Locator
  • Test Thoroughly: ทดสอบ Factory Class อย่างละเอียดเพื่อให้แน่ใจว่ามันสร้าง Object ที่ถูกต้องตามเงื่อนไข

สรุป

Factory Pattern เป็น Design Pattern ที่มีประโยชน์ในการสร้าง Object โดยไม่ต้องระบุ Class ที่จะสร้างโดยตรง ทำให้โค้ดของเรามีความยืดหยุ่นและง่ายต่อการเปลี่ยนแปลงมากขึ้น อย่างไรก็ตาม การใช้ Factory Pattern ก็มี Trade-offs ที่ต้องพิจารณา เราควรเลือกใช้ Factory Pattern เมื่อจำเป็นเท่านั้น และควรพยายามทำให้ Factory Class มีขนาดเล็กและง่ายต่อการเข้าใจ ในบทถัดไป เราจะพูดถึง Queues และ Background Processing ซึ่งเป็นเทคนิคที่ใช้ในการจัดการงานที่ใช้เวลานาน โดยไม่ทำให้ Application ของเรา Block

Office.in.th Custom Service

이 구조를 바탕으로 시스템을 개발하거나 맞춤 변경하고 싶으신가요?

Office.in.th는 엔터프라이즈 웹 애플리케이션, API 연동, 공공/민간 업무 관리 시스템을 설계·개발하며 장기 지원을 제공합니다.

소프트웨어 개발 서비스 보기