I lettori come te aiutano a sostenere MUO. Quando effettui un acquisto utilizzando i link sul nostro sito, potremmo guadagnare una commissione di affiliazione. Per saperne di più.

Il modello di progettazione factory (o metodo factory) è specializzato nella delega e nell'incapsulamento. Questo modello consente a una superclasse di rinviare l'istanza alle sottoclassi. Questo perché la classe che contiene il pattern del metodo factory primario è astratta.

La versione originale del metodo factory assume la forma di un metodo non implementato perché non conosce il prodotto che creerà. Il metodo di fabbrica potrebbe sapere che sta creando un prodotto, ma non conosce le caratteristiche specifiche del prodotto che creerà. Questa conoscenza è disponibile solo per le rispettive sottoclassi. Pertanto, la responsabilità di implementare il metodo factory e creare oggetti appropriati è esclusivamente quella di una sottoclasse.

Implementazione del Factory Design Pattern in Java

Questo articolo utilizza un'applicazione di generazione di report di feedback di esempio. Questa applicazione utilizza i diversi tipi di feedback ricevuti da un'azienda (per una nuova merenda) per creare report specifici (utilizzando il metodo factory). Pertanto, il modello di fabbrica creerà un feedback specifico (o rapporto di feedback), utilizzando come base la seguente classe di prodotto principale:

instagram viewer

pubblicoastrattoclasseFeedback{

privato Corda revisoreNome;
privato Corda reviewMessage;
privatoint recensioneValutazioni;

pubblicoFeedback(String reviewerName, String reviewMessage, int recensioneValutazioni){
Questo.reviewerName = reviewerName;
Questo.reviewMessage = reviewMessage;
Questo.reviewRatings = reviewRatings;
}

pubblico Corda getRevisoreNome(){
ritorno revisoreNome;
}
pubblicovuotosetRevisoreNome(String reviewerName){
Questo.reviewerName = reviewerName;
}
pubblico Corda getReviewMessage(){
ritorno reviewMessage;
}
pubblicovuotosetReviewMessage(String reviewMessage){
Questo.reviewMessage = reviewMessage;
}
pubblicointgetReviewRatings(){
ritorno recensioneValutazioni;
}
pubblicovuotosetReviewRatings(int recensioneValutazioni){
Questo.reviewRatings = reviewRatings;
}
}

Ogni feedback avrà tre proprietà obbligatorie, un nome del recensore, un messaggio di recensione e un punteggio numerico (da uno a cinque) per il nuovo spuntino. I diversi tipi di feedback che l'azienda riceverà proverranno da uno dei tre canali:

Classe di feedback via e-mail

pubblicoclasseE-mailRispostaestendeFeedback{

privato Corda revisoreE-mail;

E-mail pubblicaRisposta(Corda recensoreNome, Corda reviewMessage, int reviewRatings, Corda recensoreEmail) {
super(reviewerName, reviewMessage, reviewRatings);
Questo.reviewerEmail = reviewerEmail;
}
pubblico Corda getReviewerEmail(){
ritorno revisoreE-mail;
}
pubblicovuotosetReviewerEmail(String reviewerEmail){
Questo.reviewerEmail = reviewerEmail;
}
}

Classe di feedback sulla posta

pubblicoclasseMailFeedbackestendeFeedback{

privato Corda indirizzo di ritorno;

feedback di posta pubblico (Corda recensoreNome, Corda reviewMessage, int reviewRatings, Corda indirizzo di ritorno) {
super(reviewerName, reviewMessage, reviewRatings);
Questo.returnAddress = returnAddress;
}

pubblico Corda getReturnAddress(){
ritorno indirizzo di ritorno;
}

pubblicovuotosetReturnAddress(Stringa returnAddress){
Questo.returnAddress = returnAddress;
}
}

Classe di feedback sui social media

pubblicoclasseFeedback sui social mediaestendeFeedback{

privato Corda revisoreHandle;

feedback sui social media pubblici (Corda recensoreNome, Corda reviewMessage, int reviewRatings, Corda reviewerHandle) {
super(reviewerName, reviewMessage, reviewRatings);
Questo.reviewerHandle = reviewerHandle;
}

pubblico Corda getReviewerHandle(){
ritorno revisoreHandle;
}

pubblicovuotosetReviewerHandle(String reviewerHandle){
Questo.reviewerHandle = reviewerHandle;
}
}

Noterai che ogni sottoclasse di feedback ha una proprietà unica. Ciò significa che dovrai creare il report per ogni tipo di feedback utilizzando almeno una proprietà univoca per quel tipo.

La fabbrica semplice

Una fabbrica semplice è un approccio popolare all'utilizzo del modello di progettazione della fabbrica. Questo approccio comporta il raggruppamento di tutti i diversi feedback (o prodotti) in un metodo (la fabbrica semplice) e la selezione del feedback appropriato in base a un parametro.

pubblicoclasseFeedbackReportFabbrica{

pubblico Feedback makeFeedback(String feedbackType){
Feedback feedback = nullo;

Se(feedbackType.uguale("e-mail")) {
riscontro = nuovo Feedback e-mail();
}altroSe (feedbackType.uguale("posta")) {
riscontro = nuovo Feedback posta();
}altroSe (feedbackType.uguale("sociale")) {
riscontro = nuovo Feedback sui social media ();
}
ritorno feedback;
}
}

Tuttavia, il semplice approccio di fabbrica non è il modello di progettazione della fabbrica, né è un modello di progettazione. È più come un concetto di design.

Il metodo di fabbrica

Il metodo factory è la vera rappresentazione del design pattern. Usando il metodo di fabbrica, il riformato FeedbackReportFabbricaClasse Java ora conterrà il seguente codice:

pubblicoastrattoclasseFeedbackReportFabbrica{
pubblicoastrattovuotomakeFeedbackReport(Feedback feedback);
}

È possibile definire la struttura del modello di progettazione di fabbrica con il seguente diagramma di classe:

Dal diagramma sopra vedrai che una classe astratta (o interfaccia) conterrà una versione astratta del metodo factory. Quindi, le classi factory concrete che estendono la classe astratta implementeranno il metodo factory, utilizzando proprietà univoche per il prodotto che si desidera creare. Dovresti anche notare che qualsiasi classe di fabbrica concreta dovrebbe creare uno o più prodotti.

L'applicazione di esempio ha tre prodotti correlati ma univoci. Ogni tipo di feedback ha almeno una proprietà univoca. Quindi, l'applicazione dovrà avere tre fabbriche di cemento per costruire ogni prodotto.

Fabbrica di feedback via e-mail

pubblicoclasseEmailFeedbackReportestendeFeedbackReportFabbrica{

E-mailFeedback feedback;

@Oltrepassare
pubblicovuotomakeFeedbackReport(Feedback feedback){

Questo.feedback = (EmailFeedback) feedback;

Sistema.fuori.println("\nSegnalaPerFeedbackattraversoE-mail" +
"\nNome revisore: " +Questo.feedback.getReviewerName() +
"\nRisposta: " + Questo.feedback.getReviewMessage() +
"\nValutazioni: " + Questo.feedback.getReviewRatings() +
"\nIndirizzo email: " + Questo.feedback.getReviewerEmail());
}
}

Fabbrica di feedback per posta

pubblicoclasseMailFeedbackReportestendeFeedbackReportFabbrica{
PostaFeedback feedback;

@Oltrepassare
pubblicovuotomakeFeedbackReport(Feedback feedback){
Questo.feedback = feedback (MailFeedback);

Sistema.fuori.println("\nSegnalaPerFeedbackattraversoPosta" +
"\nNome revisore: " +Questo.feedback.getReviewerName() +
"\nRisposta: " + Questo.feedback.getReviewMessage() +
"\nValutazioni: " + Questo.feedback.getReviewRatings() +
"\nIndirizzo postale: " + Questo.feedback.getReturnAddress());
}
}

Fabbrica di feedback sui social media

pubblicoclasseRapporto di feedback sui social mediaestendeFeedbackReportFabbrica{
Feedback sui social media;

@Oltrepassare
pubblicovuotomakeFeedbackReport(Feedback feedback){
Questo.feedback = feedback (SocialMediaFeedback);

Sistema.fuori.println("\nSegnalaPerFeedbackattraversoSocialeMedia" +
"\nNome revisore: " + Questo.feedback.getReviewerName() +
"\nRisposta: " + Questo.feedback.getReviewMessage() +
"\nValutazioni: " + Questo.feedback.getReviewRatings() +
"\nGestione dei social media del revisore: " + Questo.feedback.getReviewerHandle());
}
}

Test dell'applicazione di esempio

Ora puoi utilizzare i rispettivi metodi di fabbrica per creare report in miniatura sui feedback ricevuti dai diversi canali. Puoi testare l'applicazione utilizzando JUnit, oppure puoi creare una classe driver:

pubblicoclassePrincipale{

pubblicostaticovuotoprincipale(Stringa[] argomenti){
Feedback feedback = nuovo E-mailRisposta("Nick", "Fantastico prodotto!", 5, "[email protected]");
Feedback feedback2 = nuovo PostaRisposta("John", "Il prodotto è buono ma non è qualcosa che comprerei regolarmente", 4, "prima strada");
Feedback feedback3 = nuovo Feedback sui social media ("Jane", "Non è per me", 2, "@janey");

FeedbackReportFactory fabbrica = nuovo EmailFeedbackReport();
FeedbackReportFactory factory2 = nuovo MailFeedbackReport();
FeedbackReportFactory factory3 = nuovo SocialMediaFeedbackReport();

fabbrica.makeFeedbackReport(feedback);
fabbrica2.makeFeedbackReport(feedback2);
fabbrica3.makeFeedbackReport(feedback3);
}

La classe Main sopra utilizza le rispettive factory per creare tre report, producendo il seguente output nella console:

Vantaggi dell'utilizzo del modello di progettazione di fabbrica

Il modello di progettazione di fabbrica promuove la flessibilità di progettazione, in cui si utilizzano interfacce (o classi astratte) per creare classi concrete. Promuove inoltre la scalabilità attraverso il polimorfismo, consentendo a nuove classi di implementare l'interfaccia esistente man mano che l'applicazione si espande.

Quando utilizzi il modello di progettazione di fabbrica, stai utilizzando due importanti principi di progettazione: aperto-chiuso e inversione del controllo (IoC).