Abstract Factory Pattern
Summary: When the object construction is complicated, needing multiple arguments, we should create a separate function (Factory Method) or class (Factory), which is responsible for the creation of the all object.
Problem examples
Suport of multiple databases
Multiple data sources: Serial port, ethernet port, device driver
Diferent report types
Multiple data sources: Serial port, ethernet port, device driver
Diferent report types
Solution
Abstract class
Generalized interface
A Factory creates instances of the concrete classes
Generalized interface
A Factory creates instances of the concrete classes
Sample Code
The abstract factory
public interface IPhotoFactory
{
IAnaloguePhoto CreateAnaloguePhoto();
IDigitalPhoto CreateDigitalPhoto();
}
The abstract products
public interface IAnaloguePhoto
{
string GetName();
}
public interface IDigitalPhoto
{
string GetName();
}
The concrete factories
public class CanonFactory : IPhotoFactory
{
public IAnaloguePhoto CreateAnaloguePhoto()
{
return new CanonAnaloguePhoto();
}
public IDigitalPhoto CreateDigitalPhoto()
{
return new CanonDigitalPhoto();
}
}
public class NikonFactory : IPhotoFactory
{
public IAnaloguePhoto CreateAnaloguePhoto()
{
return new NikonAnaloguePhoto();
}
public IDigitalPhoto CreateDigitalPhoto()
{
return new NikonDigitalPhoto();
}
}
The concrete products
public class CanonAnaloguePhoto : IAnaloguePhoto
{
public string GetName()
{
return "Canon Analogue Photo";
}
}
public class CanonDigitalPhoto : IDigitalPhoto
{
public string GetName()
{
return "Canon Digital Photo";
}
}
public class NikonAnaloguePhoto : IAnaloguePhoto
{
public string GetName()
{
return "Nikon Analogue Photo";
}
}
public class NikonDigitalPhoto : IDigitalPhoto
{
public string GetName()
{
return "Nikon Digital Photo";
}
}
The client
public class PhotoClient
{
public enum Brand { Canon, Nikon};
private IPhotoFactory photoFactory;
public PhotoClient(Brand brand)
{
switch (brand)
{
case Brand.Canon:
photoFactory = new CanonFactory();
break;
case Brand.Nikon:
photoFactory = new NikonFactory();
break;
}
}
public string GetAnaloguePhoto() => photoFactory.CreateAnaloguePhoto().GetName();
public string GetDigitalPhoto() => photoFactory.CreateDigitalPhoto().GetName();
}
Usage
var photoClient = new PhotoClient(PhotoClient.Brand.Canon);
WriteLine(photoClient.GetAnaloguePhoto());
WriteLine(photoClient.GetDigitalPhoto());
photoClient = new PhotoClient(PhotoClient.Brand.Nikon);
WriteLine(photoClient.GetAnaloguePhoto());
WriteLine(photoClient.GetDigitalPhoto());
Comments
Post a Comment