Deep Dive into Creational Patterns - The Factory Method Pattern.
Hey software designers! Today, we’re exploring the Factory Method pattern. This pattern provides an interface for creating objects in a superclass but allows subclasses to alter the type of objects that will be created. Let’s dive into its workings, benefits, and real-world applications with detailed examples.
What is the Factory Method Pattern?
The Factory Method pattern is a creational design pattern that defines an interface for creating an object but allows subclasses to alter the type of objects that will be created. The Factory Method pattern promotes loose coupling by eliminating the need to bind application-specific classes into the code, allowing the code to refer to the newly created objects through their common interface.
Real-World Scenario
Imagine you’re developing a document editor that supports different types of documents (Word, PDF, Excel). Each type of document requires a different way of opening, editing, and saving. Without a systematic approach, you might end up with tightly coupled code that is hard to maintain and extend.
The Problem
When an application needs to create instances of multiple derived classes, hardcoding the object creation logic can lead to a tightly coupled and inflexible codebase. This approach makes it difficult to introduce new types or change existing types without modifying the existing code.
Without Factory Method Pattern
class DocumentEditor
def open_document(type)
case type
when 'Word'
WordDocument.new.open
when 'PDF'
PDFDocument.new.open
when 'Excel'
ExcelDocument.new.open
else
raise 'Unknown document type'
end
end
end
class WordDocument
def open
puts 'Opening Word document...'
end
end
class PDFDocument
def open
puts 'Opening PDF document...'
end
end
class ExcelDocument
def open
puts 'Opening Excel document...'
end
end
editor = DocumentEditor.new
editor.open_document('Word')
editor.open_document('PDF')
Drawbacks: The code is tightly coupled to specific implementations and hard to extend.
The Solution: Factory Method Pattern
Using the Factory Method pattern, we can delegate the responsibility of creating objects to subclasses, promoting flexibility and extensibility.
With Factory Method Pattern
Step 1: Define the Product Interface
class Document
def open
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
end
Step 2: Create Concrete Products
class WordDocument < Document
def open
puts 'Opening Word document...'
end
end
class PDFDocument < Document
def open
puts 'Opening PDF document...'
end
end
class ExcelDocument < Document
def open
puts 'Opening Excel document...'
end
end
Step 3: Define the Creator Interface
class DocumentCreator
def create_document
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
def open_document
document = create_document
document.open
end
end
Step 4: Implement Concrete Creators
class WordDocumentCreator < DocumentCreator
def create_document
WordDocument.new
end
end
class PDFDocumentCreator < DocumentCreator
def create_document
PDFDocument.new
end
end
class ExcelDocumentCreator < DocumentCreator
def create_document
ExcelDocument.new
end
end
Step 5: Implement Client Code
word_creator = WordDocumentCreator.new
word_creator.open_document
pdf_creator = PDFDocumentCreator.new
pdf_creator.open_document
excel_creator = ExcelDocumentCreator.new
excel_creator.open_document
Benefits: Promotes loose coupling, making the code more flexible and easier to extend.
Real-World Benefits
Scenario: Adding New Document Types
Imagine you need to add a new type of document (e.g., TextDocument). Using the Factory Method pattern, you can easily introduce new document types without modifying the existing code.
Without Factory Method Pattern:
class DocumentEditor
def open_document(type)
case type
when 'Word'
WordDocument.new.open
when 'PDF'
PDFDocument.new.open
when 'Excel'
ExcelDocument.new.open
when 'Text'
TextDocument.new.open
else
raise 'Unknown document type'
end
end
end
class TextDocument
def open
puts 'Opening Text document...'
end
end
Drawbacks: Tightly coupled code that is difficult to maintain and extend.
With Factory Method Pattern:
class TextDocument < Document
def open
puts 'Opening Text document...'
end
end
class TextDocumentCreator < DocumentCreator
def create_document
TextDocument.new
end
end
text_creator = TextDocumentCreator.new
text_creator.open_document
Benefits: Clean, maintainable code with high flexibility and extensibility.
Conclusion
The Factory Method pattern is a powerful tool for creating objects in a flexible and extensible manner. It promotes loose coupling and enhances the maintainability of your code. By using the Factory Method pattern, you can easily introduce new types and alter existing ones without modifying the existing code. Incorporate the Factory Method pattern into your design strategies to build more robust and adaptable software systems.
Stay tuned for more insights into software design principles and patterns.
Thôi Lo Code Đi Kẻo Sếp nạt!