Factory Method Pattern

Pattern Factory Method refers to creational design patterns.
This pattern describes the creation of an interface for creating an object of a particular class. Sounds simple yeah?

Theory

Suppose we are developing a framework for working with AR glasses, when you tilt your head to the side, a menu of available applications should appear in front of the user’s eyes. Applications will be developed by third-party companies, clients of our framework. Naturally, we don’t know which applications, icons, names should appear, so we must provide an interface for implementing the icon and related information about the application. Call it Product:

 
protocol Product {
 var name: String { get }
 var image: Image { get }
 var executablePath: String { get }
}
 

Next, we need to provide an interface so that our customers implement the application array of their Specific Product – an array of application icons with names that we will already draw in the framework.

We’ll write this interface – the Creator interface, containing the Factory Method, which returns an array of Products.

 
protocol Creator {
 func factoryMethod() -> [Product]
}
 

In practice

The first customer of our AR framework was 7B, a leading provider of coffee maker software in Honduras. They want to sell augmented reality glasses with the ability to brew coffee, check the fullness of the water / beans, point the way to their nearest coffee maker in indoor map mode.

They undertake the development of software, we only need to provide documentation on the interfaces of Creator and Product, for the correct listing of applications and their further launch.

After the documentation is transferred, 7B using the Creator interface implements the Concrete Creator – a class that returns an array of icon applications. Icon applications themselves are the Concrete Product classes implementing the Product interface.

Concrete Product code example:

 
class CoffeeMachineLocator: implements Product {
 let name = “7B Coffee Machine Locator v.3000”
 let image = Image.atPath(“images/locator.tga”)
 let executablePath = “CoffeeMachineLocator.wasm”
}

class iPuchinno: implements Product {
 let name = “iPuchinno 1.0.3”
 let image = Image.atPath(“images/puchino.pvrtc”)
 let executablePath = “neutron/ipuchBugFixFinalNoFreezeFixAlpha4.js”
}
 

Concrete Creator class, returning array with two applications:

 
class 7BAppsCreator: implements Creator {
 func factoryMethod() -> [Product] {
  return [CoffeeMachineLocator(), iPuchinno()]
 }
}
 

After that, 7B compiles the library of Concrete Products, Concrete Creator and combines it with our framework, starts selling AR glasses for its coffee makers, no source code modifications on our side is required.

References

https://refactoring.guru/design-patterns/command
https://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612