Abstract Factory Pattern

[tr] Türkçe Oku

2023-06-11

Once upon a time, there was a kingdom, and the name of this kingdom was “Abstract Factory”. Although it seemed abstract, everything in this kingdom had a purpose, a certain order, and a specific design. There were certain rules on how everything was made, and these rules were based on design patterns that regulated the creation of objects.

In the kingdom of Abstract Factory, the King, known as AbstractFactory, would manage the factories of different types of products. The King thought that a factory should be able to produce various products at the same time. The King would give each of these factories the task of creating products from the same family. For example, one factory could create a Button and a TextField, while another could create a Slider and a Dropdown.

This concept is implemented in the C# language as follows:

public abstract class AbstractFactory
{
    public abstract IButton CreateButton();
    public abstract ITextField CreateTextField();
}

public class FactoryA : AbstractFactory
{
    public override IButton CreateButton()
    {
        return new ButtonA();
    }

    public override ITextField CreateTextField()
    {
        return new TextFieldA();
    }
}

public class FactoryB : AbstractFactory
{
    public override IButton CreateButton()
    {
        return new ButtonB();
    }

    public override ITextField CreateTextField()
    {
        return new TextFieldB();
    }
}

The same concept in Java:

public interface AbstractFactory {
    Button createButton();
    TextField createTextField();
}

public class FactoryA implements AbstractFactory {
    public Button createButton() {
        return new ButtonA();
    }
    public TextField createTextField() {
        return new TextFieldA();
    }
}

public class FactoryB implements AbstractFactory {
    public Button createButton() {
        return new ButtonB();
    }
    public TextField createTextField() {
        return new TextFieldB();
    }
}

Let’s see this example in Python:

from abc import ABC, abstractmethod

class AbstractFactory(ABC):
    @abstractmethod
    def create_button(self):
        pass

    @abstractmethod
    def create_text_field(self):
        pass

class FactoryA(AbstractFactory):
    def create_button(self):
        return ButtonA()

    def create_text_field(self):
        return TextFieldA()

class FactoryB(AbstractFactory):
    def create_button(self):
        return ButtonB()

    def create_text_field(self):
        return TextFieldB()

We can also apply this example in Go:

type AbstractFactory interface {
	CreateButton() Button
	CreateTextField() TextField
}

type FactoryA struct{}

func (f FactoryA) CreateButton() Button {
	return ButtonA{}
}

func (f FactoryA) CreateTextField() TextField {
	return TextFieldA{}
}

type FactoryB struct{}

func (f FactoryB) CreateButton() Button {
	return ButtonB{}
}

func (f FactoryB) CreateTextField() TextField {
	return TextFieldB{}
}

The situation in Rust is as follows:

pub trait AbstractFactory {
    fn create_button(&self) -> Box<dyn Button>;
    fn create_text_field(&self) -> Box<dyn TextField>;
}

pub struct FactoryA;
pub struct FactoryB;

impl AbstractFactory for FactoryA {
    fn create_button(&self) -> Box<dyn Button> {
        Box::new(ButtonA)
    }

    fn create_text_field(&self) -> Box<dyn TextField> {
        Box::new(TextFieldA)
    }
}

impl AbstractFactory for FactoryB {
    fn create_button(&self) -> Box<dyn Button> {
        Box::new(ButtonB)
    }

    fn create_text_field(&self) -> Box<dyn TextField> {
        Box::new(TextFieldB)
    }
}


That is the story of the Abstract Factory kingdom. We understood how different varieties of products could be produced by a single factory. Each factory creates a certain product family, providing us with consistency among products. This is very useful especially when there is a specific relationship between the products or when a specific factory needs to create only certain types of products. This way, one factory can only create one type of button, while another factory can create a different type of button.

This story shows what the abstract factory design pattern is and how it can be used. In each language, there are specific ways to apply this pattern, but the basic concept is always the same: a factory creates a series of products belonging to a certain family, and there is a specific relationship between these products. This makes the code more orderly and understandable, and most importantly, it makes the code easier to maintain and extend.



More posts like this

The Dance of Components: The Composite Design Pattern

2023-06-22 | #composite-pattern #design-patterns #structural-patterns

Once upon a time, there was a tree in a forest. This tree was a complex structure with leaves and branches. Each branch could have smaller branches and leaves on it. The tree worked as a whole, holding its branches and leaves together. This tree is an example of the Composite design pattern. The tree (Composite) contains two types of components: branches (also Composite) and leaves (Leaf). Both branches and leaves implement the same interface (Component) recognized by the tree.

Continue reading 


Gaining Flexibility by Building Bridges: Analysis and Implementations in Four Different Languages with the Bridge Design Pattern

2023-06-22 | #bridge-pattern #design-patterns #structural-patterns

Once upon a time, there were two kingdoms. Despite being very close to each other, a wide and deep river was located between them. This river made it difficult for the kingdoms to interact with each other. To solve this situation, both kingdoms decided to build a bridge. This bridge became an interface that facilitated communication between the two kingdoms. However, the bridge had different structures and features on each side.

Continue reading 


Decorator Design Pattern: The Adornments of Software

2023-06-15 | #decorator-pattern #design-patterns #structural-patterns

Once upon a time, there was an object named “Component”. This object was used to perform a specific function. However, sometimes it was necessary to extend or modify this function. That’s where “Decorators” came into play. Decorators are objects that “decorate” or extend the Component. A Decorator comes on top of a Component and extends or modifies its function. This is used to extend the functionality of the Component without changing it itself.

Continue reading 