รูปแบบการสร้าง: Factory, Builder, Singleton
ควบคุมการสร้างออบเจ็กต์อย่างเป็นระเบียบด้วยรูปแบบการสร้าง
รูปแบบการสร้าง: Factory, Builder, Singleton เป็นบทเรียน PHP Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน PHP Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส PHP Academy มีบทเรียนทั้งหมด 4 บทเรียน
ควบคุมการสร้าง
รูปแบบการสร้างแยก สิ่งที่คุณต้องการ ออกจาก วิธีสร้างสิ่งนั้น เมื่อการสร้างมีเงื่อนไข หลายขั้นตอน หรือต้องรวมศูนย์ การกระจาย new ไปทั่วโค้ดเบสจะทำให้ผู้เรียกผูกติดกับคลาสรูปธรรม ที่นี่เราจะครอบคลุมโรงงาน (รวมถึงเมธอดโรงงาน) ตัวสร้างสำหรับการประกอบที่ซับซ้อน และซิงเกิลตัน (พร้อมข้อควรระวัง)
โรงงานอย่างง่าย
โรงงานอย่างง่าย รวมศูนย์การตัดสินใจสร้างไว้เบื้องหลังเมธอดเดียว ผู้เรียกขอประเภทเชิงตรรกะและได้รับอินสแตนซ์รูปธรรมที่กำหนดค่าแล้ว โดยไม่จำเป็นต้องรู้ชื่อคลาส
<?php
interface Notifier { public function send(string $msg): string; }
final class EmailNotifier implements Notifier {
public function send(string $m): string { return "email: $m"; }
}
final class SmsNotifier implements Notifier {
public function send(string $m): string { return "sms: $m"; }
}
final class NotifierFactory {
public static function make(string $channel): Notifier {
return match ($channel) {
'email' => new EmailNotifier(),
'sms' => new SmsNotifier(),
default => throw new InvalidArgumentException($channel),
};
}
}
echo NotifierFactory::make('sms')->send('Hi'), PHP_EOL;
เมธอดโรงงาน
รูปแบบเมธอดโรงงานเลื่อนการสร้างอินสแตนซ์ไปยังคลาสย่อย คลาสฐานกำหนดอัลกอริทึมที่เรียกใช้เมธอดนามธรรม create() ส่วนคลาสย่อยแต่ละคลาสจะตัดสินใจเลือกผลิตภัณฑ์รูปธรรม วิธีนี้เป็นมิตรต่อ OCP เพราะคุณเพิ่มผู้สร้างรายใหม่ได้โดยไม่ต้องแก้ไขผู้สร้างที่มีอยู่
<?php
abstract class ReportExporter {
abstract protected function create(): string;
public function export(): string {
return 'Exported as ' . $this->create();
}
}
final class PdfExporter extends ReportExporter {
protected function create(): string { return 'PDF'; }
}
final class CsvExporter extends ReportExporter {
protected function create(): string { return 'CSV'; }
}
echo (new PdfExporter())->export(), PHP_EOL;
echo (new CsvExporter())->export(), PHP_EOL;
โรงงานนามธรรม
โรงงานนามธรรมสร้างตระกูลอ็อบเจกต์ที่เกี่ยวข้องกัน ซึ่งต้องใช้ร่วมกัน (เช่น MySqlConnection + MySqlQueryBuilder) วิธีนี้รับประกันว่าส่วนประกอบต่าง ๆ เข้ากันได้ เพราะโรงงานหนึ่งแห่งให้ชุดทั้งหมด ใช้รูปแบบนี้เมื่อตระกูลผลิตภัณฑ์ต้องคงความสอดคล้องกันภายใน
ตัวสร้าง: ปัญหา
เมื่ออ็อบเจกต์ต้องรับพารามิเตอร์เสริมจำนวนมาก ตัวสร้างจะกลายเป็นรายการอาร์กิวเมนต์ตามตำแหน่งที่อ่านยาก หรือเป็นเมธอดโอเวอร์โหลดที่เพิ่มพารามิเตอร์ต่อเนื่อง ซึ่ง PHP ก็ไม่มีให้ใช้ด้วยซ้ำ รูปแบบตัวสร้างจะประกอบอ็อบเจกต์ที่ซับซ้อนทีละขั้นตอน และส่งคืนผลิตภัณฑ์ที่สร้างเสร็จและถูกต้องในตอนท้าย
ตัวสร้างแบบต่อเนื่อง
ตัวสร้างแบบต่อเนื่องจะส่งคืน $this จากเมธอดกำหนดค่าแต่ละเมธอด จากนั้น build() จะสร้างผลลัพธ์ที่เปลี่ยนแปลงไม่ได้ วิธีนี้ทำให้ตัวผลิตภัณฑ์เรียบง่าย และย้ายตรรกะการประกอบไปไว้ในตัวสร้าง
<?php
final class Query {
public function __construct(public readonly string $sql) {}
}
final class QueryBuilder {
private string $table = '';
private array $where = [];
public function from(string $t): self { $this->table = $t; return $this; }
public function where(string $c): self { $this->where[] = $c; return $this; }
public function build(): Query {
$sql = "SELECT * FROM {$this->table}";
if ($this->where) { $sql .= ' WHERE ' . implode(' AND ', $this->where); }
return new Query($sql);
}
}
echo (new QueryBuilder())->from('users')->where('age > 18')->build()->sql, PHP_EOL;
ตัวสร้างกับตัวสร้างที่ตั้งชื่อ
สำหรับกรณีที่ง่ายกว่า อาร์กิวเมนต์แบบตั้งชื่อของ PHP 8 และตัวสร้างที่ตั้งชื่อ (เมธอดโรงงานแบบสแตติก) มักเหมาะกว่าการใช้ตัวสร้างเต็มรูปแบบ
- ใช้อาร์กิวเมนต์แบบตั้งชื่อเมื่อข้อมูลทั้งหมดพร้อมในครั้งเดียว
- ใช้ตัวสร้างเมื่อการประกอบมีหลายขั้นตอน มีเงื่อนไข หรือนำกลับมาใช้ซ้ำในหลายจุดที่เรียกใช้งาน
<?php
final class Money {
private function __construct(public readonly int $cents, public readonly string $cur) {}
public static function fromDollars(float $d): self {
return new self((int) round($d * 100), 'USD');
}
public static function zero(string $cur = 'USD'): self {
return new self(0, $cur);
}
}
var_dump(Money::fromDollars(19.99)->cents); // int(1999)
ซิงเกิลตัน
ซิงเกิลตันรับประกันว่าจะมีอินสแตนซ์เดียวพร้อมจุดเข้าถึงส่วนกลาง ใช้ตัวสร้างส่วนตัวและตัวเข้าถึงแบบสแตติกเพื่อสร้างรูปแบบนี้ รูปแบบนี้มีประโยชน์อย่างแท้จริงกับสิ่งที่ต้องมีเพียงหนึ่งเดียวภายในกระบวนการ แต่ก็เป็นรูปแบบที่ถูกใช้ในทางที่ผิดมากที่สุดเช่นกัน
<?php
final class Config {
private static ?self $instance = null;
private array $data = ['debug' => true];
private function __construct() {}
public static function instance(): self {
return self::$instance ??= new self();
}
public function get(string $k): mixed { return $this->data[$k] ?? null; }
}
var_dump(Config::instance()->get('debug'));
var_dump(Config::instance() === Config::instance()); // true
เหตุใดซิงเกิลตันจึงสร้างปัญหา
ซิงเกิลตันทำให้เกิดสถานะส่วนกลางที่ซ่อนอยู่ ผู้เรียกเข้าถึง Config::instance() แทนการประกาศการพึ่งพา ส่งผลให้ทดสอบและทำงานแบบขนานได้ยาก ใน PHP สมัยใหม่ ควรลงทะเบียนอินสแตนซ์ร่วมเพียงหนึ่งเดียวไว้ในคอนเทนเนอร์ DI (วงจรชีวิตแบบ "อินสแตนซ์เดียว") แล้วฉีดอินสแตนซ์นั้นเข้าไป คุณจะได้อินสแตนซ์เดียวโดยไม่ต้องผูกติดกับสถานะส่วนกลาง
การเลือกเครื่องมือที่เหมาะสม
- อย่างง่าย/เมธอดโรงงาน: ซ่อนคลาสรูปธรรมไว้เบื้องหลังการตัดสินใจสร้าง
- โรงงานนามธรรม: สร้างตระกูลผลิตภัณฑ์ที่เข้ากันได้
- ตัวสร้าง: ประกอบอ็อบเจกต์ที่ซับซ้อนทีละขั้นตอน
- ซิงเกิลตัน: ทางเลือกสุดท้าย ควรเลือกบริการร่วมที่จัดการโดยคอนเทนเนอร์
ทั้งสี่รูปแบบช่วยลดการผูกติดกับตัวสร้างรูปธรรม ทำให้โค้ดขยายและทดสอบได้ง่ายขึ้น
โรงงานที่ใช้รีจิสทรี
โรงงานแบบไดนามิกจะค้นหาผู้สร้างในรีจิสทรี ทำให้ประเภทใหม่ลงทะเบียนตัวเองได้โดยไม่ต้องแก้ไขโรงงาน (เป็นไปตาม OCP อย่างแท้จริง) ระบบปลั๊กอินและตัวทำอนุกรมใช้แนวทางนี้เพื่อแปลงชื่อประเภทเป็นตัวสร้างขณะทำงาน
<?php
interface Shape { public function name(): string; }
final class Circle implements Shape { public function name(): string { return 'circle'; } }
final class Square implements Shape { public function name(): string { return 'square'; } }
final class ShapeRegistry {
private array $creators = [];
public function register(string $key, callable $factory): void {
$this->creators[$key] = $factory;
}
public function create(string $key): Shape {
return ($this->creators[$key] ?? throw new InvalidArgumentException($key))();
}
}
$r = new ShapeRegistry();
$r->register('circle', fn() => new Circle());
$r->register('square', fn() => new Square());
echo $r->create('square')->name(), PHP_EOL; // square
ตรวจสอบอย่างรวดเร็ว
เลือกเครื่องมือสำหรับการสร้างที่เหมาะสมที่สุดสำหรับสถานการณ์นี้
สรุป
คุณควบคุมการสร้างอ็อบเจกต์ด้วยรูปแบบการสร้าง ได้แก่ โรงงานเพื่อซ่อนประเภทรูปธรรมและเลือกตระกูลผลิตภัณฑ์ ตัวสร้างเพื่อประกอบอ็อบเจกต์ที่ซับซ้อนอย่างต่อเนื่อง และซิงเกิลตันพร้อมข้อแลกเปลี่ยนของมัน บทเรียนสำคัญสำหรับแนวทางสมัยใหม่คือ เลือกใช้โรงงานและตัวสร้างได้อย่างอิสระ แต่แทนที่ซิงเกิลตันด้วยวงจรชีวิตอินสแตนซ์ร่วมของคอนเทนเนอร์ DI เพื่อให้การพึ่งพาชัดเจนและทดสอบได้
คำถามที่พบบ่อย
บทเรียน “รูปแบบการสร้าง: Factory, Builder, Singleton” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “รูปแบบการสร้าง: Factory, Builder, Singleton” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส PHP Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส PHP Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “รูปแบบการสร้าง: Factory, Builder, Singleton”
ควบคุมการสร้างออบเจ็กต์อย่างเป็นระเบียบด้วยรูปแบบการสร้าง คุณปฏิบัติ PHP Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน PHP Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน PHP Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “รูปแบบการสร้าง: Factory, Builder, Singleton” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน PHP Academy นี้ได้ไหม
ได้ บทเรียน PHP Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- หลักการ SOLID ในการใช้งานจริง
- รูปแบบการสร้าง: Factory, Builder, Singleton
- รูปแบบโครงสร้าง: Adapter, Decorator, Facade
- รูปแบบพฤติกรรม: Strategy, Observer, Command