La scala Pattern Factory astratta?

8

Sto ancora cercando di capire i modelli di design qui, dopo aver appreso il pattern Abstract factory, ho capito che questo pattern non si adatta bene. Dai un'occhiata al diagramma uml del modello astratto di fabbrica

Se devo creare un nuovo 'AbstractProductC', dovrò aggiungere un metodo astratto 'CreateProductC' in 'AbstractFactory' che influenza l'implementazione di entrambi ConcreateFactory1, ConcreateFactory2.

La mia domanda qui è, la scala del modello di Factory astratta (o) Sto pensando nella direzione sbagliata qui?

grazie in anticipo

    
posta Jitendar 10.12.2013 - 19:48
fonte

4 risposte

5

Abstract Factory si adatta perfettamente.

C'è un principio di base che afferma che una classe dovrebbe fare bene una cosa. Il tuo problema qui è che stai cercando di fare molte classi fare molte cose.

Non è necessario attenersi a una fabbrica astratta. Puoi (e dovresti avere) più:

AbstractProductAFactory definisce l'interfaccia per la produzione di ProdottoA. Le tue implementazioni concrete (ConcreteProductAFactory1, ConcreteProductAFactory2) lo estenderebbero.

AbstractProductBFactory definisce l'interfaccia per la produzione di ProdottoB. Le tue implementazioni concrete ( ConcreteProductBFactory1 , ConcreteProductBFactory2 ) lo estenderebbero.

Se hai bisogno di un ProductC, crea un nuovo AbstractProductCFactory . Non c'è bisogno di cambiare nessuna delle tue altre fabbriche in questo modo.

Aggiorna Idealmente, ProductA dovrebbe rappresentare una classe di prodotto, ovvero tutti i prodotti che condividono un'interfaccia che si chiama ProductA. Nei commenti suggerisco che si tratti di una pizza:

interface AbstractPizzaFactory {
    public Pizza buildPizza(List<Topping> toppings);
}


class ThinCrustPizzaFactory implements AbstractPizzaFactory {
    public Pizza buildPizza(List<Topping> toppings){

        ...

    }
}

class DeepDishPizzaFactory implements AbstractPizzaFactory {
    public Pizza buildPizza(List<Topping> toppings){

        ...

    }
}

E così via. L'aggiunta di PanPizzaFactory non influisce su nessuna delle altre classi: è solo una nuova implementazione concreta di PizzaFactory. Se hai prodotti che non sono pizze - sandwich, ad esempio, è lì che crei un'altra fabbrica astratta (ad esempio AbstractSandwichFactory ).

Il vero punto è che non vorrai avere una fabbrica astratta che costruisca due tipi di prodotti molto diversi con due diversi metodi di "costruzione". Raggruppale nel modo più logico possibile in modo che condividano un'interfaccia e quindi creare una fabbrica astratta che definisca in che modo le fabbriche concrete dovrebbero implementare le implementazioni di tale interfaccia.

    
risposta data 10.12.2013 - 20:01
fonte
4

Il problema con il ridimensionamento è che il codice può ridimensionarsi in molti modi diversi. Il problema che stai avendo è semplicemente causato dalla necessità di ridimensionare in una direzione, per cui non è previsto che il modello di progettazione. In caso di pattern Abstract Factory, è pensato per scalare in modo da aggiungere nuove fabbriche concrete, ma l'aggiunta di un nuovo prodotto causa grossi cambiamenti strutturali.

Uno dei punti di progettazione e architettura del software consiste nell'individuare le direzioni più probabili in cui il codice si ridimensionerà e selezionerà i modelli in base a tali direzioni. Se ti identifichi, aggiungere nuovi prodotti è più probabile che aggiungere una nuova fabbrica di cemento, quindi usare Abstract Factory non è una buona idea e potrebbe essere meglio ripensare completamente il design.

    
risposta data 10.12.2013 - 23:19
fonte
3

Sì, hai ragione, "fabbrica astratta" non si adatta bene quando hai bisogno di prodotti astratti aggiuntivi.

Ma in molti scenari del mondo reale si ha un numero variabile di prodotti, ma solo un piccolo numero fisso di prodotti astratti da supportare. Ad esempio, prendi l'esempio dei widget GUI dall'articolo wikipedia sulle fabbriche astratte . La factory GUI astratta potrebbe avere un metodo createWidget (invece di createButton ), dove Widget è il "prodotto astratto", essendo la classe base più alta per una famiglia di decine di elementi della GUI. L'aggiunta di nuovi widget GUI non implica in alcun modo una modifica all'interfaccia della fabbrica astratta, quindi nessuna delle interfacce della fabbrica di calcestruzzo deve essere modificata.

Avere molti prodotti astratti significa che avrai molte diverse gerarchie di classi nel tuo codice. E se questo è il caso, puoi prendere in considerazione la creazione di una singola fabbrica (o fabbrica astratta) per ciascuna delle gerarchie.

    
risposta data 24.12.2013 - 12:27
fonte
0

Il fattore di ridimensionamento è una questione semplice di gestione delle dipendenze. Più dipendenze ha una classe - più stabile e premurosa dovrebbe essere la sua API.

Non c'è alcun problema nella creazione di una fabbrica definita dalla responsabilità di creare tipi di natura simile o coesiva. Ma più classi dipendono da questa fabbrica, più rigorosa dovrebbe essere questa coesione.

(Nota: questo può essere fatto in modo graduale, non necessariamente da un BDUF)

    
risposta data 10.12.2013 - 20:13
fonte

Leggi altre domande sui tag