Costruttori factory
Fa parte della sezione Programmazione orientata agli oggetti del percorso Dart di Coddy. Lezione 14 di 110.
Un costruttore factory è un costruttore speciale che non crea sempre una nuova istanza. A differenza dei costruttori normali, un costruttore factory può restituire un'istanza esistente, un sottotipo o persino null (se nullable). Lo dichiari usando la parola chiave factory.
class Logger {
static final Logger _instance = Logger._internal();
// Costruttore con nome privato
Logger._internal();
// Costruttore factory
factory Logger() {
return _instance;
}
}
Logger log1 = Logger();
Logger log2 = Logger();
print(identical(log1, log2)); // trueIn questo esempio, il costruttore factory restituisce sempre la stessa istanza. Indipendentemente da quante volte chiami Logger(), ottieni lo stesso oggetto. Questo schema viene comunemente usato per implementare i singleton.
I costruttori factory differiscono dai costruttori normali per un aspetto fondamentale: non hanno accesso a this perché potrebbero non creare affatto una nuova istanza. Devono invece restituire esplicitamente un oggetto:
class Shape {
factory Shape(String type) {
if (type == 'circle') return Circle();
if (type == 'square') return Square();
return Rectangle();
}
}
class Circle extends Shape { Circle() : super._(); }
class Square extends Shape { Square() : super._(); }
class Rectangle extends Shape { Rectangle() : super._(); }I costruttori factory sono utili quando hai bisogno di controllare la creazione delle istanze, ad esempio per restituire oggetti memorizzati nella cache, implementare pool di oggetti o decidere quale sottotipo istanziare in base ai parametri di input.
Sfida
FacileCreiamo un sistema di notifiche che utilizza costruttori factory per creare diversi tipi di notifiche in base a una semplice stringa in input.
Creerai due file per organizzare il codice:
notification.dart: definisci una classeNotificationche funge da base per tutti i tipi di notifica. La classe deve avere:- Un campo
String message - Un costruttore con nome privato
Notification._internalche inizializza il messaggio - Un costruttore factory
Notification(String type, String message)che restituisce diversi sottotipi di notifica in base al parametrotype:- Se type è
'email', restituisci unEmailNotification - Se type è
'sms', restituisci unSMSNotification - Altrimenti, restituisci un
PushNotification
- Se type è
- Un metodo
send()che stampaSending: [message]
- Un campo
Nello stesso file, crea tre sottoclassi che estendono Notification:
EmailNotification: esegui l’override disend()per stampareEmail: [message]SMSNotification: esegui l’override disend()per stampareSMS: [message]PushNotification: esegui l’override disend()per stamparePush: [message]
Ogni sottoclasse deve avere un costruttore che riceve un message e lo passa alla classe genitore usando super._internal(message).
main.dart: importa la classe di notifica e crea tre notifiche usando il costruttore factory:- Una notifica email con il messaggio
'Welcome!' - Una notifica SMS con il messaggio
'Your code is 1234' - Una notifica push con il messaggio
'New update available'
send()su ogni notifica nell’ordine indicato sopra.- Una notifica email con il messaggio
Output previsto:
Email: Welcome!
SMS: Your code is 1234
Push: New update availableProvalo tu
import 'notification.dart';
void main() {
// TODO: Crea una notifica email con il messaggio 'Welcome!'
// TODO: Crea una notifica SMS con il messaggio 'Your code is 1234'
// TODO: Crea una notifica push con il messaggio 'New update available'
// TODO: Chiama send() su ogni notifica nell'ordine previsto
}
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