Factory Pattern: Objekte elegant erstellen | Enjyn Gruppe
Hallo Welt
Hallo Welt
Original Lingva Deutsch
Übersetzung wird vorbereitet...
Dieser Vorgang kann bis zu 60 Sekunden dauern.
Diese Seite wird erstmalig übersetzt und dann für alle Besucher gespeichert.
0%
DE Zurück zu Deutsch
Übersetzung durch Lingva Translate

235 Dokumentationen verfügbar

Wissensdatenbank

Factory Pattern Beispiele

Zuletzt aktualisiert: 20.01.2026 um 11:25 Uhr

Factory Pattern: Objekte elegant erstellen

Das Factory Pattern kapselt die Objekterzeugung und macht Code flexibler. Lernen Sie Simple Factory, Factory Method und Abstract Factory.

Warum Factory Pattern?

Problem Lösung durch Factory
Komplexe Objekterzeugung Zentralisierte Erstellungslogik
Viele Konstruktor-Parameter Sprechende Factory-Methoden
Bedingte Objekterzeugung Switch-Logik in Factory
Testbarkeit Factory kann gemockt werden

1. Simple Factory

// ❌ Ohne Factory - Überall verstreute Logik
class PaymentController {
    public function process(string $type): void {
        if ($type === 'creditcard') {
            $processor = new CreditCardProcessor(
                new PaymentGateway(),
                new FraudDetection(),
                new Logger()
            );
        } elseif ($type === 'paypal') {
            $processor = new PayPalProcessor(
                new PayPalAPI(),
                new Logger()
            );
        } elseif ($type === 'bitcoin') {
            $processor = new BitcoinProcessor(
                new BlockchainAPI(),
                new WalletService(),
                new Logger()
            );
        }
        // ...
    }
}
// ✅ Mit Simple Factory
class PaymentProcessorFactory {
    public function __construct(
        private PaymentGateway $gateway,
        private PayPalAPI $paypalApi,
        private BlockchainAPI $blockchainApi,
        private Logger $logger
    ) {}

    public function create(string $type): PaymentProcessorInterface {
        return match($type) {
            'creditcard' => new CreditCardProcessor(
                $this->gateway,
                new FraudDetection(),
                $this->logger
            ),
            'paypal' => new PayPalProcessor(
                $this->paypalApi,
                $this->logger
            ),
            'bitcoin' => new BitcoinProcessor(
                $this->blockchainApi,
                new WalletService(),
                $this->logger
            ),
            default => throw new InvalidArgumentException("Unknown type: {$type}")
        };
    }
}

// Verwendung
class PaymentController {
    public function __construct(
        private PaymentProcessorFactory $factory
    ) {}

    public function process(string $type): void {
        $processor = $this->factory->create($type);
        $processor->process($payment);
    }
}

2. Static Factory Method

class User {
    private function __construct(
        private string $name,
        private string $email,
        private string $role,
        private bool $isVerified
    ) {}

    // Factory Methods
    public static function createAdmin(string $name, string $email): self {
        return new self($name, $email, 'admin', true);
    }

    public static function createMember(string $name, string $email): self {
        return new self($name, $email, 'member', false);
    }

    public static function createGuest(): self {
        return new self('Guest', '', 'guest', false);
    }

    // Named Constructor für komplexe Erstellung
    public static function fromArray(array $data): self {
        return new self(
            $data['name'] ?? throw new InvalidArgumentException('Name required'),
            $data['email'] ?? throw new InvalidArgumentException('Email required'),
            $data['role'] ?? 'member',
            $data['verified'] ?? false
        );
    }

    public static function fromJson(string $json): self {
        $data = json_decode($json, true);
        if (!$data) {
            throw new InvalidArgumentException('Invalid JSON');
        }
        return self::fromArray($data);
    }
}

// Verwendung - Klar und lesbar
$admin = User::createAdmin('Max', 'max@admin.de');
$member = User::createMember('Anna', 'anna@user.de');
$guest = User::createGuest();
$imported = User::fromJson('{"name":"Tom","email":"tom@test.de"}');

3. Factory Method Pattern

// Abstract Creator
abstract class NotificationSender {
    // Factory Method - Subklassen entscheiden welche Notification
    abstract protected function createNotification(string $message): Notification;

    // Template Method nutzt die Factory
    public function send(string $message, User $user): void {
        $notification = $this->createNotification($message);
        $notification->setRecipient($user);
        $notification->send();
        $this->logNotification($notification);
    }

    private function logNotification(Notification $notification): void {
        // Logging...
    }
}

// Concrete Creators
class EmailNotificationSender extends NotificationSender {
    public function __construct(private Mailer $mailer) {}

    protected function createNotification(string $message): Notification {
        return new EmailNotification($message, $this->mailer);
    }
}

class SMSNotificationSender extends NotificationSender {
    public function __construct(private SMSGateway $gateway) {}

    protected function createNotification(string $message): Notification {
        return new SMSNotification($message, $this->gateway);
    }
}

class PushNotificationSender extends NotificationSender {
    public function __construct(private PushService $pushService) {}

    protected function createNotification(string $message): Notification {
        return new PushNotification($message, $this->pushService);
    }
}

// Verwendung
class NotificationService {
    public function notify(User $user, string $message, string $channel): void {
        $sender = match($channel) {
            'email' => new EmailNotificationSender($this->mailer),
            'sms' => new SMSNotificationSender($this->smsGateway),
            'push' => new PushNotificationSender($this->pushService),
            default => throw new InvalidArgumentException()
        };

        $sender->send($message, $user);
    }
}

4. Abstract Factory Pattern

// Abstract Factory - Erstellt Familien zusammengehöriger Objekte
interface UIFactory {
    public function createButton(): Button;
    public function createCheckbox(): Checkbox;
    public function createTextField(): TextField;
}

// Concrete Factory für Light Theme
class LightThemeFactory implements UIFactory {
    public function createButton(): Button {
        return new LightButton();
    }

    public function createCheckbox(): Checkbox {
        return new LightCheckbox();
    }

    public function createTextField(): TextField {
        return new LightTextField();
    }
}

// Concrete Factory für Dark Theme
class DarkThemeFactory implements UIFactory {
    public function createButton(): Button {
        return new DarkButton();
    }

    public function createCheckbox(): Checkbox {
        return new DarkCheckbox();
    }

    public function createTextField(): TextField {
        return new DarkTextField();
    }
}

// Client nutzt nur die Abstraktion
class FormBuilder {
    public function __construct(private UIFactory $factory) {}

    public function buildLoginForm(): Form {
        $form = new Form();

        $form->add($this->factory->createTextField()
            ->setLabel('Username'));

        $form->add($this->factory->createTextField()
            ->setLabel('Password')
            ->setType('password'));

        $form->add($this->factory->createCheckbox()
            ->setLabel('Remember me'));

        $form->add($this->factory->createButton()
            ->setText('Login'));

        return $form;
    }
}

// Verwendung - Theme einfach austauschbar
$factory = $user->prefersDarkMode()
    ? new DarkThemeFactory()
    : new LightThemeFactory();

$builder = new FormBuilder($factory);
$loginForm = $builder->buildLoginForm();

JavaScript Factory Beispiele

// Simple Factory in JavaScript
class UserFactory {
    static createAdmin(name, email) {
        return {
            name,
            email,
            role: 'admin',
            permissions: ['read', 'write', 'delete', 'admin'],
            createdAt: new Date()
        };
    }

    static createMember(name, email) {
        return {
            name,
            email,
            role: 'member',
            permissions: ['read'],
            createdAt: new Date()
        };
    }

    static createFromDTO(dto) {
        const base = {
            name: dto.name,
            email: dto.email,
            createdAt: new Date(dto.created_at || Date.now())
        };

        return dto.is_admin
            ? { ...base, role: 'admin', permissions: ['read', 'write', 'delete', 'admin'] }
            : { ...base, role: 'member', permissions: ['read'] };
    }
}

// Verwendung
const admin = UserFactory.createAdmin('Max', 'max@admin.de');
const member = UserFactory.createMember('Anna', 'anna@user.de');
const imported = UserFactory.createFromDTO(apiResponse);
// Factory mit Registrierung in JavaScript
class HandlerFactory {
    static handlers = new Map();

    static register(type, handler) {
        this.handlers.set(type, handler);
    }

    static create(type, ...args) {
        const Handler = this.handlers.get(type);
        if (!Handler) {
            throw new Error(`Unknown handler type: ${type}`);
        }
        return new Handler(...args);
    }
}

// Handler registrieren
HandlerFactory.register('json', JSONHandler);
HandlerFactory.register('xml', XMLHandler);
HandlerFactory.register('csv', CSVHandler);

// Verwendung
const handler = HandlerFactory.create('json', options);
handler.parse(data);

// Erweiterbar ohne Factory-Code zu ändern
HandlerFactory.register('yaml', YAMLHandler);

Best Practices

// ✅ Factory für komplexe Objekterzeugung
class OrderFactory {
    public function createFromCart(Cart $cart, User $user): Order {
        $order = new Order();
        $order->setUser($user);
        $order->setItems($cart->getItems());
        $order->setShippingAddress($user->getDefaultAddress());
        $order->setTotalPrice($this->calculateTotal($cart));
        $order->setStatus('pending');
        $order->setCreatedAt(new DateTime());

        return $order;
    }
}

// ✅ Factory für Testdaten
class TestDataFactory {
    public static function createUser(array $overrides = []): User {
        return new User(
            name: $overrides['name'] ?? 'Test User',
            email: $overrides['email'] ?? 'test@example.com',
            role: $overrides['role'] ?? 'member'
        );
    }
}

// In Tests
$user = TestDataFactory::createUser(['role' => 'admin']);
💡 Wann welche Factory? Simple Factory: Wenn Sie verschiedene Objekte basierend auf einem Parameter erstellen müssen.
Factory Method: Wenn Subklassen entscheiden sollen, welche Objekte erstellt werden.
Abstract Factory: Wenn Sie Familien zusammengehöriger Objekte erstellen müssen.

Weitere Informationen

Enjix Beta

Enjyn AI Agent

Hallo 👋 Ich bin Enjix — wie kann ich dir helfen?
120