0Pricing
PHP Academy · Lezione

Pattern comportamentali: Strategy, Observer, Command

Modellate comportamento e comunicazione con i pattern comportamentali.

Pattern comportamentali: Strategy, Observer, Command è una lezione PHP Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento PHP Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso PHP Academy include 4 lezioni in totale.

Modellare il comportamento

I pattern comportamentali regolano il modo in cui gli oggetti collaborano e distribuiscono le responsabilità. Ci concentreremo su tre pattern che compaiono continuamente nei sistemi PHP reali:

  • Strategy — sostituire un algoritmo a runtime.
  • Observer — trasmettere eventi agli ascoltatori interessati.
  • Command — trasformare una richiesta in un oggetto che è possibile accodare, registrare o annullare.

Strategy: l'idea

Il pattern Strategy definisce una famiglia di algoritmi intercambiabili dietro un'unica interfaccia e consente al client di scegliere a runtime. Sostituisce l'ampio switch qui sotto con il polimorfismo: il contesto delega l'operazione alla strategia che contiene.

<?php
// The smell Strategy removes: branching on a type code
function price(string $type, float $base): float {
    switch ($type) {
        case 'standard': return $base + 5;
        case 'express':  return $base + 15;
        default: throw new InvalidArgumentException($type);
    }
}
echo price('express', 10), PHP_EOL; // 25

Strategy nel codice

Qui il costo di spedizione dipende dal corriere scelto. Ogni strategia incapsula un algoritmo di tariffazione; il contesto rimane invariato quando si aggiunge un nuovo corriere.

<?php
interface ShippingStrategy { public function cost(float $weight): float; }
final class Standard implements ShippingStrategy {
    public function cost(float $w): float { return 5 + $w * 0.5; }
}
final class Express implements ShippingStrategy {
    public function cost(float $w): float { return 15 + $w * 1.2; }
}

final class Cart {
    public function __construct(private ShippingStrategy $strategy) {}
    public function setStrategy(ShippingStrategy $s): void { $this->strategy = $s; }
    public function quote(float $weight): float { return $this->strategy->cost($weight); }
}

$cart = new Cart(new Standard());
echo $cart->quote(10), PHP_EOL;     // 10
$cart->setStrategy(new Express());
echo $cart->quote(10), PHP_EOL;     // 27

Strategy con le closure

In PHP una strategia non richiede sempre una classe. Nei casi semplici, una callable o la sintassi delle callable di prima classe è una strategia perfettamente valida. Utilizzi classi complete quando l'algoritmo ha uno stato o dipendenze propri; utilizzi le closure per scelte semplici e senza stato.

<?php
$strategies = [
    'asc'  => fn(array $a) => sort($a) ? $a : $a,
    'desc' => fn(array $a) => rsort($a) ? $a : $a,
];
$data = [3, 1, 2];
print_r($strategies['desc']($data)); // [3,2,1]

Observer: l'idea

Il pattern Observer consente a un soggetto di notificare molti osservatori quando il suo stato cambia, senza sapere chi siano. In questo modo si disaccoppia la sorgente di un evento dai relativi handler, fornendo le basi per sistemi di eventi, hook e aggiornamenti reattivi.

Observer nel codice

Il soggetto mantiene un elenco di osservatori e chiama update() su ciascuno di essi. È possibile aggiungere nuovi listener senza modificare la logica del soggetto.

<?php
interface Observer { public function update(string $event): void; }

final class OrderSubject {
    private array $observers = [];
    public function subscribe(Observer $o): void { $this->observers[] = $o; }
    public function placed(string $id): void {
        foreach ($this->observers as $o) { $o->update("order $id placed"); }
    }
}
final class EmailObserver implements Observer {
    public function update(string $e): void { echo "email: $e" . PHP_EOL; }
}
final class AuditObserver implements Observer {
    public function update(string $e): void { echo "audit: $e" . PHP_EOL; }
}

$subject = new OrderSubject();
$subject->subscribe(new EmailObserver());
$subject->subscribe(new AuditObserver());
$subject->placed('42');

Observer o PSR-14

Nel PHP moderno, Observer viene spesso espresso tramite i dispatcher di eventi PSR-14: un dispatcher inoltra un oggetto evento ai listener registrati. Il modello mentale è lo stesso (soggetto = evento, osservatori = listener), ma un dispatcher li disaccoppia ulteriormente e supporta gli eventi interrompibili. SplObserver/SplSubject esistono nella SPL, ma oggi vengono usati raramente.

Command: l'idea

Il pattern Command incapsula una richiesta come oggetto: l'azione, il relativo ricevitore e i suoi parametri. Poiché la richiesta è ora un dato, è possibile accodarla, registrarla, ritentarla o annullarla. Il comando più semplice concretizza un'intenzione come valore, come mostrato di seguito.

<?php
final class SendEmail {
    public function __construct(
        public readonly string $to,
        public readonly string $subject
    ) {}
}
// The request is now data you can store, serialize, or enqueue
$cmd = new SendEmail('user@example.com', 'Welcome');
echo json_encode($cmd), PHP_EOL;

Command nel codice

Ogni comando implementa execute(). Un invocatore li conserva e li esegue, senza dipendere da ciò che fanno. Aggiungendo undo() si ottiene uno stack di annullamento completo.

<?php
interface Command { public function execute(): string; }

final class Light { public bool $on = false; }
final class TurnOn implements Command {
    public function __construct(private Light $light) {}
    public function execute(): string { $this->light->on = true; return 'light on'; }
}
final class TurnOff implements Command {
    public function __construct(private Light $light) {}
    public function execute(): string { $this->light->on = false; return 'light off'; }
}

final class Invoker {
    private array $queue = [];
    public function add(Command $c): void { $this->queue[] = $c; }
    public function run(): void {
        foreach ($this->queue as $c) { echo $c->execute(), PHP_EOL; }
    }
}

$light = new Light();
$inv = new Invoker();
$inv->add(new TurnOn($light));
$inv->add(new TurnOff($light));
$inv->run();

Bus di comandi

I framework costruiscono un command bus basato su questo pattern: un DTO di comando viene inviato a un solo handler. Il middleware che circonda il bus può aggiungere in modo uniforme transazioni, validazione e logging. Poiché i comandi sono semplici oggetti serializzabili, lo stesso handler può essere eseguito in modo sincrono oppure inserito in una coda gestita da un worker.

Scegliere tra questi pattern

  • Strategy: un'operazione, molti algoritmi intercambiabili, scelti dal chiamante.
  • Observer: un evento, molte reazioni indipendenti; la sorgente non conosce gli handler.
  • Command: concretizzare una richiesta affinché possa essere accodata, registrata, ritentata o annullata.

Si combinano bene: un command handler può scegliere una strategy ed emettere eventi Observer.

Verifica rapida

Abbini il requisito al pattern.

Riepilogo

Ha modellato il comportamento con tre pattern: Strategy per sostituire gli algoritmi a runtime, tramite classi o closure; Observer per trasmettere i cambiamenti di stato a listener disaccoppiati, alla base dei dispatcher PSR-14; e Command per trasformare le richieste in oggetti che è possibile accodare, registrare e annullare, alla base dei command bus. Insieme mantengono flessibile la collaborazione e chiare le responsabilità.

Domande Frequenti

La lezione «Pattern comportamentali: Strategy, Observer, Command» è gratuita?

Sì — il testo completo di «Pattern comportamentali: Strategy, Observer, Command» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso PHP Academy, passa a CoddyKit PRO. Il corso PHP Academy include 4 lezioni in totale.

Cosa imparerò in «Pattern comportamentali: Strategy, Observer, Command»?

Modellate comportamento e comunicazione con i pattern comportamentali. Eserciti PHP Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare PHP Academy?

Non è richiesta alcuna esperienza precedente. PHP Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Pattern comportamentali: Strategy, Observer, Command»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione PHP Academy?

Sì. Ogni lezione PHP Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. I principi SOLID nella pratica
  2. Pattern creazionali: Factory, Builder, Singleton
  3. Pattern strutturali: Adapter, Decorator, Facade
  4. Pattern comportamentali: Strategy, Observer, Command
← Torna a PHP Academy