Abstract Factory
- Provides an interface for creating a families of related objects
- Factory method is a method
- Abstract Factory is an abstraction (interface)
Classical Structure
Scenario
- Build a GUI framework. In framework we have controls like button, textbox, dropdown. Support themes like Material, Ant.
- Based on theme selected, the controls should have consistent look and feel.
Problem
- Violates Open Closed Principle. If you need support another theme, you need to add another if condition
public interface IWidget
{
void Render();
}
public interface IButton: IWidget {}
public interface ITextbox: IWidget {}
public class MaterialButton: IButton
{
public void Render()
{
Console.WriteLine("Material Button");
}
}
public class MaterialTextbox : ITextbox
{
public void Render()
{
Console.WriteLine("Material Textbox");
}
}
public class AntButton : IButton
{
public void Render()
{
Console.WriteLine("Ant Button");
}
}
public class AntTextbox: ITextbox
{
public void Render()
{
Console.WriteLine("Ant Textbox");
}
}
public enum Theme
{
Material,
Ant
}
public class ContactForm
{
public void Render(Theme theme)
{
if (theme == Theme.Material)
{
new MaterialTextbox().Render();
new MaterialButton().Render();
}
else if (theme == Theme.Ant)
{
new AntTextbox().Render();
new AntButton().Render();
}
}
}
Solution
public interface IWidgetFactory
{
IButton CreateButton();
ITextbox CreateTextbox();
}
public class MaterialWidgetFactory : IWidgetFactory
{
public IButton CreateButton()
{
return new MaterialButton();
}
public ITextbox CreateTextbox()
{
return new MaterialTextbox();
}
}
public class AntWidgetFactory : IWidgetFactory
{
public IButton CreateButton()
{
return new AntButton();
}
public ITextbox CreateTextbox()
{
return new AntTextbox();
}
}
public class ContactForm
{
public void Render(IWidgetFactory widgetFactory)
{
widgetFactory.CreateTextbox().Render();
widgetFactory.CreateButton().Render();
}
}
new ContactForm().Render(new MaterialWidgetFactory());
Example Structure
Example Code