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.
Sfida
FacileCostruiamo 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
Documentcon un metodogenerate(String content)che restituisce unaString - Tre classi concrete che implementano
Document:Report- il suo metodogeneraterestituisce=== REPORT ===\n[content]\n=============Invoice- il suo metodogeneraterestituisceINVOICE\n--------\n[content]\nTotal DueLetter- il suo metodogeneraterestituisceDear Reader,\n[content]\nSincerely
- Una classe
DocumentFactorycon un metodo staticocreate(String type)che restituisce ilDocumentappropriato in base alla stringa del tipo:"report","invoice"oppure"letter". Per qualsiasi tipo sconosciuto, restituisci unLettercome valore predefinito
- Una classe astratta
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
- Usa la factory per creare un report e stampa il risultato della sua generazione con il contenuto
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
SincerelyProvalo 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"
}
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
1Fondamenti della programmazione orientata agli oggetti
File esterniLibrerie e importazioniIntroduzione alla programmazione orientata agli oggettiClassi e oggettiLa parola chiave thisMetodiVariabili di istanzaFondamenti dei costruttoriRiepilogo - Calcolatrice semplice4Sicurezza dei valori null
Introduzione alla sicurezza dei valori nullNullable e non nullableGli operatori ? e !La keyword late e la sicurezza dei valori nullOperatori null-awareSicurezza dei valori null nelle classiRiepilogo - Sistema di profili utente7Classi astratte e interfacce
Classi astratteMetodi astrattiInterfacce in DartInterfacce impliciteImplementare vs estendereInterfacce multipleRiepilogo - Calcolatore di forme10Collezioni e generici
Panoramica di List, Set e MapCollezioni sicure rispetto ai tipiClassi genericheMetodi genericiVincoli sui genericiIterable e IteratorRiepilogo - Archiviazione generica13Concetti avanzati di OOP
Composizione vs ereditarietàMetodi di estensioneClassi chiamabiliClassi sealed (Dart 3)Record (Dart 3)Pattern e matching (3.0)Enum con metodi16Progetto: Gestione della biblioteca
Panoramica del progettoClassi Libro e Utente2I costruttori in Dart
Costruttore predefinitoCostruttori con nomeListe di inizializzazioneCostruttori costantiCostruttori factoryCostruttori di reindirizzamentoRiepilogo - Crea forme5Incapsulamento
Membri pubblici e privatiConvenzione del prefisso _Visibilità a livello di libreriaApprofondimento su getter e setterNascondimento delle informazioniRiepilogo - Registri degli studenti8Mixin
Introduzione ai MixinCreare MixinUsare più MixinParola chiave on nei MixinMixin vs ereditarietàMixin vs interfacciaRiepilogo - Sistema animale11Metodi speciali
Sovrascrittura di toString()Sovrascrittura di hashCode e ==Interfaccia ComparableMetodo call()Sovrascrittura di noSuchMethodRiepilogo - Collezione personalizzata14Modelli di progettazione Parte 1
Introduzione ai modelli di progettazioneSingletonFactoryObserverStrategy3Proprietà delle classi
Membri di istanza e staticiCampi final e constVariabili lateMetodi e campi staticiGetter e setterRiepilogo - Gestore di conti bancari6Ereditarietà
Ereditarietà di baseLa parola chiave superOverride dei metodiL’annotazione @overrideLa parola chiave final per le classiCostruttori ed ereditarietàRiepilogo - Gerarchia dei dipendenti9Polimorfismo
Fondamenti di polimorfismoPolimorfismo tramite interfacceControllo del tipo a runtimeGli operatori is e asParola chiave covariantRiepilogo - Elaboratore di pagamenti12OOP asincrona
Future e async/awaitNozioni di base sugli streamController degli streamCostruttori asincroniAsync nei metodi di classeRiepilogo - Recupero dei dati15Pattern di progettazione Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositePattern RepositoryEsercitati da solo: Compilatore Dart online