Comprensione delle fabbriche

4

So che ci sono centinaia di domande su questo qui. Probabilmente ho letto cinquanta diverse domande, post di blog e libri di testo. Il problema è che ho ottenuto circa 75 risposte diverse. Ho visto tutto quanto segue descritto come un tipo di fabbrica, e non posso seguire la terminologia confusa, e confondermi con i pro ei contro.

public class PizzaFactory {
  public static Pizza(String city) {
    switch(city) {
      case "Chicago": return new DeepDishPizza();
      case "New York": return new ThinCrustPizza();
    }
  }
}

vs

  public abstract class PizzaFactory {
    public Pizza getPizza();
  }

  public class ChicagoPizzaShop extends PizzaFactory {
    public Pizza getPizza() {
      return new DeepDishPizza();
    }
  }

  public class NewYorkPizzaShop extends PizzaFactory {
    public Pizza getPizza() {
      return new ThinCrustPizza();
    }
  }

public class SomeOtherClass {
  public Pizza getPizza(String city) {
    PizzaFactory pizzaShop;
    switch(city) {
      case "Chicago": pizzaShop = new ChicagoPizzaShop();
        break;
      case "New York" : pizzaShop = new NewYorkPizzaShop();
        break;
    return pizzaShop.getPizza();
    }
  }
}

vs

public class PizzaFactoryFactory {
  public abstract class PizzaFactory {
    public Pizza getPizza();
  }

  public class ChicagoPizzaShop extends PizzaFactory {
    public Pizza getPizza() {
      return new DeepDishPizza();
    }
  }

  public class NewYorkPizzaShop extends PizzaFactory {
    public Pizza getPizza() {
      return new ThinCrustPizza();
    }
  }

  public Pizza getPizza(String city) {
    switch (city) {
      case "Chicago": return new ChicagoPizzaShop().getPizza();
      case "New York": return new NewYorkPizzaShop().getPizza();
    }
  }
}

vs

public abstract class PizzaFactory {
    public Pizza getPizza();
  }

  public class ChicagoPizzaShop extends PizzaFactory {
    public Pizza getPizza() {
      return new DeepDishPizza();
    }
  }

  public class NewYorkPizzaShop extends PizzaFactory {
    public Pizza getPizza() {
      return new ThinCrustPizza();
    }
  }
}

public abstract Customer {
  public Pizza orderPizza();
}

public ChicagoCustomer extends Customer {
  public Pizza orderPizza() {
    return new ChicagoPizzaShop.getPizza();
  }
}

public NewYorkCustomer extends Customer {
  public Pizza orderPizza() {
    return new NewYorkPizzaShop.getPizza();
  }
}
// How does one choose which Customer to use? *Another* factory?

Ci sono probabilmente altri a cui non sto pensando in questo momento. Quale di questi è uno schema di fabbrica astratta? Il modello del metodo di fabbrica? Qualche altra cosa? Più concretamente, ho otto sottoclassi diverse di una classe astratta, e ho bisogno di restituire una di quelle basate su una selezione utente che posso rappresentare sia come stringa, sia come int o enum. Come fare meglio?

    
posta TBridges42 31.07.2015 - 06:05
fonte

1 risposta

8

La fabbrica astratta ha senso solo quando il codice che crea la fabbrica si trova in una parte completamente diversa dalla tua applicazione rispetto al codice che effettivamente utilizza la tua fabbrica. Nessuno dei tuoi esempi in realtà lo rappresenta. Molto spesso, la fabbrica è a valle della dipendenza tra i moduli. Quindi il codice che consuma l'astrazione creata non può avere dipendenza dalle implementazioni concrete.

L'illustrazione seguente mostra dove la fabbrica astratta ha senso.

Questodesignhapochebuoneproprietà.Quandoimoduliperleimplementazioniconcrete(imoduliChicagoStoreseNewYorkStores)cambiano,nonrichiedelaricompilazionedialtrimodulioquellocheeffettivamenteutilizzaleimplementazioni(Persone).Insecondoluogo,consentediaggiungereunanuovaimplementazioneconcreta(forseWashingtonStores),dopolaqualeèsufficientemodificareilmodulo"application", che lega tutto insieme. L'oggetto "compositore" è quello che lega tutto insieme. Questo sarebbe spesso una sorta di struttura di Inversion of Control. Si noti inoltre che quello che utilizza la factory per creare un'istanza ha bisogno di più di queste istanze. Se voleva solo una singola istanza, il compositore può semplicemente passare in quelle istanze. Non ci sarebbe bisogno di complicare il design con le fabbriche astratte.

Ma potreste dire: "Non è troppo complesso?" Si, è corretto. Ma se hai requisiti che imporrebbero questo tipo di struttura di dipendenza, questo tipo di design è inevitabile. Devi ponderare i vantaggi che ottieni separando le dipendenze dalla progettazione complicata.

Una nota per la fine: se stai solo imparando schemi di progettazione, la mia opinione personale sarebbe semplicemente ignorare il modello (astratto) di fabbrica. Il suo uso è altamente situazionale ed è più spesso abusato, quindi usato correttamente. Poiché molti sembrano essere d'accordo con me e altro .

Si noti inoltre che ciò che ho descritto sopra è un modello di progettazione chiamato "Fabbrica astratta". C'è anche un pattern chiamato "Factory" che IMO è solo un metodo che crea oggetti. La tua confusione deriva probabilmente dal fatto che questi due sono spesso mescolati insieme.

    
risposta data 31.07.2015 - 06:25
fonte

Leggi altre domande sui tag