- It provides a class that creates other objects that are related by a common interface.
- This class creates families of related or dependent objects without specifying their concrete classes.
- Over time, its meaning has evolved relative to the original GoF definition.
- Today, this pattern aims to create individual object instances.
- Constructors are limited in their control over the overall creation process.
- They don’t communicate their intention very well because they must be named after their class.
- Having numerous overloaded constructors may make it hard for the client developer to decide which constructor to use.
- Replacing constructors with intention-revealing creation methods is frequently preferred.
- If your application needs more control, consider using a Factory.
- Some possible scenarios where this may be the case are when the creation process involves object caching, sharing or re-using of objects, and maintaining object and type counts.
- There are times when the client does not know exactly what type to construct.
- It is easier to code against a base type or an interface and then let a factory make this decision for the client.
Participants
AbstractProduct
(IVehicle)
- Declares an interface for a type of
Product
object.
Product
(KiaPride, HyundaiAccent)
- The implementation of the
AbstractProduct
interface.
AbstractFactory
(IVehicleFactory)
- Declares an interface for operations that create
AbstractProduct
.
ConcreteFactory
(KiaFactory, HyundaiFactory)
- Implements the operations to create concrete product objects.
var kiaFactory = new KiaFactory();
var kiaEconomy = kiaFactory.GetEconomyCar();
var kiaLuxury = kiaFactory.GetLuxuryCar();
var hyundaiFactory = new HyundaiFactory();
var hyundaiEconomy = hyundaiFactory.GetEconomyCar();
var hyundaiLuxury = hyundaiFactory.GetLuxuryCar();
public interface IVehicle
{
string GetName();
}
public class KiaPride : IVehicle
{
public string GetName() => "Kia - Pride";
}
public class KiaRegal : IVehicle
{
public string GetName() => "Kia - Regal";
}
public class HyundaiAccent : IVehicle
{
public string GetName() => "Hyundai - Accent";
}
public class HyundaiSantaFe : IVehicle
{
public string GetName() => "Hyundai - SantaFe";
}
public interface IVehicleFactory
{
IVehicle GetLuxuryCar();
IVehicle GetEconomyCar();
}
public class KiaFactory : IVehicleFactory
{
public IVehicle GetLuxuryCar() => new KiaPride();
public IVehicle GetEconomyCar() => new KiaRegal();
}
public class HyundaiFactory : IVehicleFactory
{
public IVehicle GetLuxuryCar() => new HyundaiAccent();
public IVehicle GetEconomyCar() => new HyundaiSantaFe();
}
Rules of Thumb
- Abstract Factory, Builder, and Prototype define a factory object that's responsible for knowing and creating the class of product objects.
- Abstract Factory has the factory object producing objects of several classes.
- Builder has the factory object building a complex product incrementally using a correspondingly complex protocol.
- Prototype has the factory object (aka prototype) building a product by copying a prototype object.
- Abstract Factory classes are often implemented with Factory Methods, but they can also be implemented using Prototype.
- Abstract Factory can be used as an alternative to Facade to hide platform-specific classes.
- Builder focuses on constructing a complex object step by step.
- Abstract Factory emphasizes a family of product objects (either simple or complex).
- Builder returns the product as a final step, but as far as the Abstract Factory is concerned, the product gets returned immediately.