Tipologia: Creazionale
Obiettivo: Fornire un’interfaccia per creare famiglie di oggetti correlati o dipendenti senza specificare le loro classi concrete
Frequenza di utilizzo: Alta
Componenti:
- Abstract Factory: dichiara un’interfaccia per operazioni che creano prodotti astratti
- ConcreteFactory: implementa le operazioni per creare gli oggetti “prodotto” concreti
- AbstractProduct: dichiara un’interfaccia per il tipo di dato “prodotto”
- Product: è l’oggetto “prodotto” creato con la corrispondente classe factory astratta. Implementa l’interfaccia AbstractProduct
- Client: utilizza le interfacce dichiarate dalle classi AbstractFactory e AbstractProduct
Implementazione in C#
La prima classe implementata è la Abstract Factory:
abstract class ContinentFactory
{
public abstract Herbivore CreateHerbivore();
public abstract Carnivore CreateCarnivore();
}
si tratta di una classe astratta (tutti i metodi sono astratti). Al suo interno sono definiti due metodi astratti (che dovranno essere implementati dalle classi che la andranno ad implementare).
La seconda classe da implementare è la Concrete Factory, la classe che implementa l’Abstract Factory precedentemente definita.
class AfricaFactory : ContinentFactory
{
public override Herbivore CreateHerbivore()
{
return new Wildebeest();
}
public override Carnivore CreateCarnivore()
{
return new Lion();
}
}
Questa classe implementa al suo interno i metodi astratti della classe da cui deriva. Ovviamente all’interno del progetto possono essere definite più classi che implementano la Abstract Factory.
E’ il momento di definire la AbstratProduct (la classe che gli oggetti concreti dovranno implementare):
abstract class Carnivore
{
public abstract void Eat(Herbivore h);
}
con la relativa classe concreta:
class Lion : Carnivore
{
public override void Eat(Herbivore h)
{
Console.WriteLine(this.GetType().Name + " eats " + h.GetType().Name);
}
}
Una volta definiti tutti gli attori, manca soltanto la definizione della classe Client:
class AnimalWorld
{
private Carnivore _carnivore;
public AnimalWorld(ContinentFactory factory)
{
_carnivore = factory.CreateCarnivore();
}
public void RunFoodChain()
{
_carnivore.Eat(_herbivore);
}
}
Si può notare come il costruttore abbia come parametro un oggetto che implementa la classe astratta ContinentFactory. Anche il tipo ritornato dalla factory è generico (Carnivore).
