Menu
Coddy logo textTech

Factory

Fa parte della sezione Programmazione orientata agli oggetti del percorso Dart di Coddy. Lezione 91 di 110.

Il pattern Factory delega la creazione degli oggetti a un metodo o a una classe separati, permettendoti di creare oggetti senza specificarne la classe esatta. È diverso dal costruttore factory che hai imparato in precedenza: il pattern Factory è un approccio di progettazione in cui la logica di creazione è centralizzata e può restituire tipi diversi in base all'input.

Considera uno scenario in cui devi creare diversi tipi di notifiche. Invece di lasciare che sia il client a decidere quale classe istanziare, se ne occupa una factory:

abstract class Notification {
  void send(String message);
}

class EmailNotification implements Notification {
  @override
  void send(String message) => print('Email: $message');
}

class SMSNotification implements Notification {
  @override
  void send(String message) => print('SMS: $message');
}

class NotificationFactory {
  static Notification create(String type) {
    switch (type) {
      case 'email':
        return EmailNotification();
      case 'sms':
        return SMSNotification();
      default:
        return EmailNotification();
    }
  }
}

void main() {
  var notification = NotificationFactory.create('sms');
  notification.send('Hello!');  // SMS: Hello!
}

Il codice client non deve conoscere EmailNotification o SMSNotification: chiede semplicemente alla factory una notifica di un certo tipo. Questo rende facile aggiungere nuovi tipi di notifica: devi modificare solo la factory, non tutti i punti in cui vengono create le notifiche.

Usa il pattern Factory quando la creazione di oggetti comporta una logica complessa, quando vuoi nascondere le classi di implementazione ai client o quando il tipo esatto da creare dipende dalle condizioni di runtime.

challenge icon

Sfida

Facile

Costruiamo un generatore di documenti usando il pattern Factory! Creerai un sistema che produce diversi tipi di documenti (report, fatture e lettere) tramite una factory centralizzata, così il codice client non deve conoscere le classi specifiche dei documenti.

Organizzerai il codice in due file:

  • document_factory.dart: crea qui il sistema di documenti:
    • Una classe astratta Document con un metodo generate(String content) che restituisce una String
    • Tre classi concrete che implementano Document:
      • Report - il suo metodo generate restituisce === REPORT ===\n[content]\n=============
      • Invoice - il suo metodo generate restituisce INVOICE\n--------\n[content]\nTotal Due
      • Letter - il suo metodo generate restituisce Dear Reader,\n[content]\nSincerely
    • Una classe DocumentFactory con un metodo statico create(String type) che restituisce il Document appropriato in base alla stringa del tipo: "report", "invoice" oppure "letter". Per qualsiasi tipo sconosciuto, restituisci un Letter come valore predefinito
  • main.dart: importa la tua factory di documenti e mostra come la factory crea diversi tipi di documenti senza che il client debba conoscere le classi concrete:
    • Usa la factory per creare un report e stampa il risultato della sua generazione con il contenuto Sales increased by 25%
    • Stampa una riga vuota
    • Usa la factory per creare una fattura e stampa il risultato della sua generazione con il contenuto Widget x3 - $150
    • Stampa una riga vuota
    • Usa la factory per creare una lettera e stampa il risultato della sua generazione con il contenuto Thank you for your order

Nota che il tuo file principale interagisce solo con la factory e con il tipo astratto Document: non crea mai direttamente oggetti Report, Invoice o Letter!

Output previsto:

=== REPORT ===
Sales increased by 25%
=============

INVOICE
--------
Widget x3 - $150
Total Due

Dear Reader,
Thank you for your order
Sincerely

Provalo tu

import 'document_factory.dart';

void main() {
  // TODO: usa DocumentFactory.create() per creare un rapporto
  // Poi stampa il risultato della sua generazione con il contenuto: "Sales increased by 25%"
  
  // TODO: stampa una riga vuota
  
  // TODO: usa DocumentFactory.create() per creare una fattura
  // Poi stampa il risultato della sua generazione con il contenuto: "Widget x3 - \$150"
  
  // TODO: stampa una riga vuota
  
  // TODO: usa DocumentFactory.create() per creare una lettera
  // Poi stampa il risultato della sua generazione con il contenuto: "Thank you for your order"
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Dart online