Skapande mönster: Factory, Builder, Singleton
Styr objektskapandet på ett tydligt sätt med skapande designmönster.
Skapande mönster: Factory, Builder, Singleton är en gratis lektion i PHP Academy på CoddyKit. Detta är lektion 2 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för PHP Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i PHP Academy innehåller totalt 4 lektioner.
Styra skapandet
Skapandemönster frikopplar vad du behöver från hur det byggs. När konstruktionen är villkorad, består av flera steg eller måste centraliseras skapar utspridda new i kodbasen en koppling mellan anropare och konkreta klasser. Här går vi igenom Factory (och Factory Method), Builder för komplex sammansättning samt Singleton (med dess begränsningar).
Enkel fabrik
En enkel fabrik centraliserar ett skapandebeslut bakom en metod. Anroparen ber om en logisk typ och får en konfigurerad konkret instans utan att känna till klassnamnen.
<?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;
Factory Method
Mönstret Factory Method delegerar instansieringen till underklasser. Basklassen definierar en algoritm som anropar en abstrakt create(); varje underklass bestämmer den konkreta produkten. Detta följer OCP: lägg till en ny skapare utan att ändra befintliga.
<?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;
Abstract Factory
En Abstract Factory skapar familjer av relaterade objekt som måste användas tillsammans (t.ex. en MySqlConnection + MySqlQueryBuilder). Den garanterar att delarna är kompatibla eftersom en fabrik levererar hela uppsättningen. Använd den när en produktfamilj måste förbli internt konsekvent.
Builder: problemet
När ett objekt behöver många valfria parametrar blir konstruktorer till oläsliga listor av positionsargument eller allt längre överlagringar, som PHP inte ens har. Mönstret Builder sätter samman ett komplext objekt steg för steg och returnerar en färdig, giltig produkt i slutet.
Fluent Builder
En fluent builder returnerar $this från varje setter, och därefter skapar build() det oföränderliga resultatet. På så sätt hålls själva produkten enkel, medan sammansättningslogiken flyttas till buildern.
<?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;
Builder jämfört med namngivna konstruktorer
För enklare fall är PHP 8:s namngivna argument och namngivna konstruktorer (statiska fabriksmetoder) ofta bättre än en fullständig builder.
- Använd namngivna argument när all data finns tillgänglig på en gång.
- Använd en builder när sammansättningen sker i flera steg, är villkorad eller återanvänds på flera anropsställen.
<?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)
Singleton
En Singleton garanterar en enda instans med en global åtkomstpunkt. Implementera den med en privat konstruktor och en statisk åtkomstmetod. Den är verkligen användbar för sådant som faktiskt måste vara unikt inom en process, men det är också det mest missbrukade mönstret.
<?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
Varför Singleton orsakar problem
Singletons introducerar dolt globalt tillstånd: anropare hämtar beroendet via Config::instance() i stället för att deklarera det, vilket försämrar testbarhet och parallellism. I modern PHP bör du i stället registrera en enda delad instans i en DI-container (livscykeln ”en enda instans”) och injicera den. Du får en enda instans utan den globala kopplingen.
Välj rätt verktyg
- Simple/Factory Method: dölj konkreta klasser bakom ett skapandebeslut.
- Abstract Factory: skapa kompatibla produktfamiljer.
- Builder: sätt samman komplexa objekt steg för steg.
- Singleton: sista utvägen; föredra delade tjänster som hanteras av containern.
Alla fyra minskar kopplingen till konkreta konstruktorer, vilket gör koden enklare att utöka och testa.
Registerbaserad fabrik
En mer dynamisk fabrik slår upp skapare i ett register, så att nya typer kan registrera sig själva utan att fabriken behöver ändras (äkta OCP). Så fungerar plugin-system och serializerare som vid körning översätter ett typnamn till en konstruktor.
<?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
Snabb kontroll
Välj det bästa skapandeverktyget för scenariot.
Sammanfattning
Du styrde objektskapandet med skapandemönster: fabriker för att dölja konkreta typer och välja produktfamiljer, builders för att sätta samman komplexa objekt på ett fluent sätt samt Singleton med dess avvägningar. Den moderna slutsatsen är att fritt föredra fabriker och builders, men ersätta Singleton med en delad instans som hanteras av en DI-containers livscykel, så att beroenden förblir explicita och testbara.
Lär dig PHP med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 49
- Lektioner
- 195
Vanliga frågor
Är lektionen ”Skapande mönster: Factory, Builder, Singleton” gratis?
Ja – hela texten till ”Skapande mönster: Factory, Builder, Singleton” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i PHP Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i PHP Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Skapande mönster: Factory, Builder, Singleton”?
Styr objektskapandet på ett tydligt sätt med skapande designmönster. Ni övar på PHP Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig PHP Academy?
Du behöver inga förkunskaper. Utbildningen i PHP Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.
Hur lång tid tar lektionen ”Skapande mönster: Factory, Builder, Singleton”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här PHP Academy-lektionen?
Ja. Varje PHP Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- SOLID-principerna i praktiken
- Skapande mönster: Factory, Builder, Singleton
- Strukturella mönster: Adapter, Decorator, Facade
- Beteendemönster: Strategy, Observer, Command