Blog Datasheets Home About me Clients My work Services Contact

G2Labs Grzegorz Grzęda

Factory Method design pattern

May 12, 2023

The Factory Method is just an implementation of the Template Method but for building objects.

Let us consider an IRL example, I’ve recently coded. Here’s the story: I was building and HD44780 LCD driver. I needed some hardware abstraction, so that I could test the rest of the software without any running hardware. Also, I didn’t know if I would bit-bang my way through, or use some funky I2C IO expander as a proxy.

Depending on my project configuration, I needed an LCD driver:

1
2
3
4
5
struct ILcdDriver{
	//...
	virtual void sendCmd(char cmd) = 0;
	virtual void sendData(char data) = 0;
};

The actual drivers in question would be:

1
2
3
4
5
struct MockLcdDriver: ILcdDriver {};

struct GpoLcdDriver: ILcdDriver{};

struct ProxyLcdDriver: ILcdDriver{};

Each one behaving totally differently but giving the same end result: controlling the HD44780 (or pretending) in a proper way.

Now I needed an entity that would deliver me a proper driver, depending on the given project configuration.

1
2
3
4
struct IDeliverLcdDriver{
	// ...
	virtual ILcdDriver* deliver() = 0;
};

Now defining classes:

1
2
3
4
5
struct DeliverMockLcdDriver:IDeliverLcdDriver{};

struct DeliverGpoLcdDriver:IDeliverLcdDriver{};

struct DeliverProxyLcdDriver:IDeliverLcdDriver{};

I could easily generate drivers based even on #ifdef’s"

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// somewhere in the init part of the project
ILcdDriver *drv = nullptr;

IDeliverLcdDriver *deliver = nullptr;

#if defined(LCD_GPO)
	deliver = new DeliverGpoLcdDriver;
#elif defined(LCD_PROXY)
	deliver = new DeliverProxyLcdDriver;
#else
	deliver = new DeliverMockLcdDriver;
#endif

drv = deliver->deliver();

// ...


➡️ Clean code guidelines for intermediate developers: A roadmap


⬅️ Composite design pattern


Go back to Posts.