Hello and welcome back! In this unit, we’re going to explore another pivotal creational design pattern: the Factory Method Pattern. Just like the Singleton Pattern we discussed earlier, the Factory Method Pattern helps manage object creation in a way that enhances flexibility and scalability in your programs.
The Factory Method Pattern is particularly useful when your code needs to instantiate objects from a superclass but leaves the decision of which subclass to instantiate to the child classes. Confused? Don't worry; we’ll break it down with clear examples and practical code snippets.
By the end of this unit, you will be able to effectively:
Go
to create instances of different types based on runtime information.We'll start with a real-world example to illustrate the concept. Consider a scenario where you need to create different types of documents such as Word documents and Excel documents. Using the Factory Method Pattern, you can define an interface for creating an object but let the subclasses decide which class to instantiate.
Here’s a quick preview of the code you’ll be comfortable writing by the end of this unit:
Go1package main 2 3import "fmt" 4 5// Document is an interface that all concrete documents will implement 6type Document interface { 7 PrintDocument() 8} 9 10// WordDocument is a concrete type implementing Document interface 11type WordDocument struct{} 12 13func (w WordDocument) PrintDocument() { 14 fmt.Println("This is a Word document.") 15} 16 17// ExcelDocument is a concrete type implementing Document interface 18type ExcelDocument struct{} 19 20func (e ExcelDocument) PrintDocument() { 21 fmt.Println("This is an Excel document.") 22} 23 24// DocumentFactory is an interface defining the factory method 25type DocumentFactory interface { 26 CreateDocument() Document 27} 28 29// WordDocumentFactory is a factory for creating Word documents 30type WordDocumentFactory struct{} 31 32func (w WordDocumentFactory) CreateDocument() Document { 33 return WordDocument{} 34} 35 36// ExcelDocumentFactory is a factory for creating Excel documents 37type ExcelDocumentFactory struct{} 38 39func (e ExcelDocumentFactory) CreateDocument() Document { 40 return ExcelDocument{} 41} 42 43func main() { 44 var docFactory DocumentFactory 45 46 // Use WordDocumentFactory to create a Word document 47 docFactory = WordDocumentFactory{} 48 wordDoc := docFactory.CreateDocument() 49 wordDoc.PrintDocument() // Output: This is a Word document. 50 51 // Use ExcelDocumentFactory to create an Excel document 52 docFactory = ExcelDocumentFactory{} 53 excelDoc := docFactory.CreateDocument() 54 excelDoc.PrintDocument() // Output: This is an Excel document. 55}
Let's break down the code step by step to understand the Factory Method Pattern in Go
.
We have defined an interface Document
that all concrete document types will implement. The PrintDocument
method is used to print the type of document.
Next, we have two concrete document types: WordDocument
and ExcelDocument
. These types implement the Document
interface and define the PrintDocument
method to print the type of document.
We then define an interface DocumentFactory
that declares the factory method CreateDocument
. This method returns an instance of the Document
interface.
Two concrete factories, WordDocumentFactory
and ExcelDocumentFactory
, implement the DocumentFactory
interface. These factories create instances of WordDocument
and ExcelDocument
, respectively.
In the main
function, we demonstrate how to use the factory method to create different types of documents. We first create a WordDocument
using the WordDocumentFactory
and then an ExcelDocument
using the ExcelDocumentFactory
.
With this let's now understand the key components of the Factory Method Pattern:
Document
is the product interface.Product
interface. In our example, WordDocument
and ExcelDocument
are concrete products.DocumentFactory
is the creator interface.Creator
interface and define the factory method to create objects. In our example, WordDocumentFactory
and ExcelDocumentFactory
are concrete creators.main
function acts as the client.The Factory Method Pattern is widely used in software development to manage object creation in a flexible and scalable manner. This pattern is particualrly useful when you have a superclass with multiple subclasses and you want to delegate the instantiation of objects to the subclasses.
The Factory Method Pattern is highly versatile and can be applied in various scenarios:
Advantages
Disadvantages
Alignment with Go’s Design Philosophy
Go’s design philosophy emphasizes simplicity, maintainability, and clarity. The Factory Method Pattern aligns well with these principles:
By understanding these use cases, advantages, disadvantages, and how the pattern aligns with Go’s design philosophy, you’ll be better equipped to implement the Factory Method Pattern effectively in your projects.
Understanding and implementing the Factory Method Pattern is crucial for a few key reasons:
Imagine you’re working on a large-scale application that needs to support various types of documents. By using the Factory Method Pattern, you can add support for new document types without altering existing code, making your application more robust and scalable.
Exciting, right? Let’s dive into the practice section and solidify your understanding of the Factory Method Pattern.