Factory Method
The Factory Method pattern is a creational design pattern that provides an interface for creating objects, but lets subclasses decide which class to instantiate. It defines a factory method, an operation that returns an object of a product class. Rather than directly instantiating concrete products, the client code calls this factory method within a creator class, and the creator’s subclasses override the factory method to return different types of products. This promotes loose coupling between the creator and the concrete products.
Usage
The Factory Method pattern is commonly used when:
- A class can’t anticipate the class of objects it must create.
- A class wants its subclasses to specify the objects it creates.
- The creation of objects requires complex logic or relies on configuration data that is only available at runtime.
- You want to centralize object creation logic to ensure consistency and maintainability.
Examples
-
Java’s JDBC Framework: The
java.sql.Connectioninterface’snewConnection()method (within its subclasses likeDriverManager) serves as a factory method. It allows different database drivers (MySQL, PostgreSQL, Oracle) to provide their own specific connection implementations without the client code needing to know the concrete class. -
Django’s Model Managers: In Django, model managers provide a way to encapsulate database query logic. The
create()method on a manager acts as a factory method. Different managers can be defined for a model, each creating instances with different default values or applying different validation rules, but clients always callcreate()on the manager without knowing the specifics of how the object is constructed. -
Configuration Parsing Libraries: Many configuration parsing libraries (e.g., for XML, YAML, JSON) use a factory method approach. A generic parser might have a method to create configuration objects, while specific parsers for different configuration formats implement that method to create the appropriate object type.
Specimens
15 implementationsThe Factory Method pattern is a creational pattern that lets a class defer instantiation to subclasses. It defines an interface for creating an object, but lets subclasses alter the type of objects that will be created. This promotes loose coupling and extensibility, allowing you to add new product types without modifying the core creating class.
This Dart example showcases a Document abstract class and concrete implementations MarkdownDocument and HtmlDocument. The DocumentFactory class uses a factory method, createDocument(), to determine which concrete document type to instantiate based on a provided type string. This design is idiomatic Dart as it leverages abstract classes and factory constructors to manage object creation and maintain flexibility, a common approach in Dart’s object-oriented structure.
abstract class Document {
String getContent();
}
class MarkdownDocument implements Document {
final String content;
MarkdownDocument(this.content);
@override
String getContent() => 'Markdown: $content';
}
class HtmlDocument implements Document {
final String content;
HtmlDocument(this.content);
@override
String getContent() => 'HTML: $content';
}
class DocumentFactory {
Document createDocument(String type, String content) {
switch (type) {
case 'markdown':
return MarkdownDocument(content);
case 'html':
return HtmlDocument(content);
default:
throw ArgumentError('Unsupported document type: $type');
}
}
}
void main() {
final factory = DocumentFactory();
final markdownDoc = factory.createDocument('markdown', 'This is markdown content.');
print(markdownDoc.getContent());
final htmlDoc = factory.createDocument('html', '<h1>This is HTML content.</h1>');
print(htmlDoc.getContent());
// Should throw an error
// factory.createDocument('pdf', 'Some PDF content');
}
The Factory Method pattern is a creational pattern that defines an interface for creating an object, but lets subclasses decide which class to instantiate. It promotes loose coupling by letting the client work with objects through an interface, without knowing their concrete classes. This allows for flexibility and extensibility.
The Scala code defines a Product trait and concrete implementations ProductA and ProductB. A Creator abstract class declares a factoryMethod which returns a Product. Concrete creators, ConcreteCreatorA and ConcreteCreatorB, override factoryMethod to return specific product types. The client code interacts with the Creator abstract class, delegating the object creation to subclasses, achieving decoupling. Using traits and abstract classes common in Scala allows for a clean and type-safe implementation.
// Product interface
trait Product {
def operation(): String
}
// Concrete Products
case class ProductA() extends Product {
override def operation(): String = "Product A operation"
}
case class ProductB() extends Product {
override def operation(): String = "Product B operation"
}
// Creator interface
abstract class Creator {
def factoryMethod(): Product
def someOperation(): String
}
// Concrete Creators
class ConcreteCreatorA() extends Creator {
override def factoryMethod(): Product = ProductA()
override def someOperation(): String = "Creator A operation with " + factoryMethod().operation()
}
class ConcreteCreatorB() extends Creator {
override def factoryMethod(): Product = ProductB()
override def someOperation(): String = "Creator B operation with " + factoryMethod().operation()
}
// Client
object Client {
def main(args: Array[String]): Unit = {
val creatorA = new ConcreteCreatorA()
println(creatorA.someOperation())
val creatorB = new ConcreteCreatorB()
println(creatorB.someOperation())
}
}
The Factory Method is a creational pattern that defines an interface for creating an object, but lets subclasses decide which class to instantiate. It enables a class to defer instantiation to subclasses. This promotes loose coupling, as the client doesn’t need to know concrete classes, and facilitates extending the system with new product types without modifying the existing client code.
The example uses an abstract Product class and concrete ConcreteProductA and ConcreteProductB. The Creator abstract class declares the factoryMethod which subclasses override to return specific Product instances. The Client code interacts with the Creator and its factoryMethod without needing to know the concrete product classes, adhering to the Dependency Inversion Principle. This structure is typical of PHP’s object-oriented approach, leveraging inheritance and abstract classes for flexible object creation.
<?php
/**
* Product interface.
*/
abstract class Product
{
public abstract function operation(): string;
}
/**
* Concrete Product A.
*/
class ConcreteProductA extends Product
{
public function operation(): string
{
return "ConcreteProductA operation.";
}
}
/**
* Concrete Product B.
*/
class ConcreteProductB extends Product
{
public function operation(): string
{
return "ConcreteProductB operation.";
}
}
/**
* Creator abstract class.
*/
abstract class Creator
{
public abstract function factoryMethod(): Product;
public function someOperation(): string
{
$product = $this->factoryMethod();
return "Creator: The product is " . $product->operation();
}
}
/**
* Concrete Creator A.
*/
class ConcreteCreatorA extends Creator
{
public function factoryMethod(): Product
{
return new ConcreteProductA();
}
}
/**
* Concrete Creator B.
*/
class ConcreteCreatorB extends Creator
{
public function factoryMethod(): Product
{
return new ConcreteProductB();
}
}
/**
* Client code.
*/
class Client
{
public static function main(): void
{
$creatorA = new ConcreteCreatorA();
echo $creatorA->someOperation() . PHP_EOL;
$creatorB = new ConcreteCreatorB();
echo $creatorB->someOperation() . PHP_EOL;
}
}
Client::main();
?>
The Factory Method pattern is a creational design pattern that defines an interface for creating an object, but lets subclasses decide which class to instantiate. This promotes loose coupling between the object creator and the concrete objects created. The code demonstrates this with a Document class and concrete MarkdownDocument and HTMLDocument subclasses. A DocumentFactory class provides a create_document method. Subclasses like MarkdownDocumentFactory and HTMLDocumentFactory override this method to return instances of their respective document types. This aligns with Ruby’s dynamic nature and utilizes inheritance effectively for customization.
# document.rb
class Document
def open
raise NotImplementedError, "Subclasses must implement the 'open' method"
end
end
class MarkdownDocument < Document
def open
puts "Opening Markdown document..."
end
end
class HTMLDocument < Document
def open
puts "Opening HTML document..."
end
end
# document_factory.rb
class DocumentFactory
def create_document(type)
raise NotImplementedError, "Subclasses must implement the 'create_document' method"
end
end
class MarkdownDocumentFactory < DocumentFactory
def create_document
MarkdownDocument.new
end
end
class HTMLDocumentFactory < DocumentFactory
def create_document
HTMLDocument.new
end
end
# client.rb
class Client
def initialize(factory)
@factory = factory
end
def create_and_open
document = @factory.create_document
document.open
end
end
# Usage:
markdown_factory = MarkdownDocumentFactory.new
client1 = Client.new(markdown_factory)
client1.create_and_open
html_factory = HTMLDocumentFactory.new
client2 = Client.new(html_factory)
client2.create_and_open
The Factory Method is a creational design pattern that provides an interface for creating objects, but lets subclasses decide which class to instantiate. It promotes loose coupling by decoupling concrete classes from their creation logic. This example implements a VehicleFactory that defines a method createVehicle(). CarFactory and MotorbikeFactory subclass VehicleFactory to return Car or Motorbike instances respectively. This is idiomatic Swift by utilizing inheritance and protocol-oriented programming to achieve polymorphism and encapsulation. The createVehicle() method is a concrete implementation within each factory, adhering to the pattern’s principle of deferred instantiation.
// Vehicle Protocol
protocol Vehicle {
var name: String { get }
func startEngine()
}
// Concrete Vehicle Classes
class Car: Vehicle {
let name = "Car"
func startEngine() {
print("Car engine started.")
}
}
class Motorbike: Vehicle {
let name = "Motorbike"
func startEngine() {
print("Motorbike engine started.")
}
}
// Factory Protocol
protocol VehicleFactory {
func createVehicle() -> Vehicle
}
// Concrete Factories
class CarFactory: VehicleFactory {
func createVehicle() -> Vehicle {
return Car()
}
}
class MotorbikeFactory: VehicleFactory {
func createVehicle() -> Vehicle {
return Motorbike()
}
}
// Client Code
func driveVehicle(factory: VehicleFactory) {
let vehicle = factory.createVehicle()
print("Driving a: \(vehicle.name)")
vehicle.startEngine()
}
// Usage Example
let carFactory = CarFactory()
driveVehicle(factory: carFactory)
let motorbikeFactory = MotorbikeFactory()
driveVehicle(factory: motorbikeFactory)
The Factory Method pattern is a creational design pattern that provides an interface for creating objects, but lets subclasses decide which class to instantiate. It promotes loose coupling by abstracting the object creation logic away from the client code.
The Kotlin code defines an abstract Product class representing the objects to be created. An abstract Creator class declares the factoryMethod which returns a Product. Concrete ConcreteProductA and ConcreteProductB inherit from Product. ConcreteCreatorA and ConcreteCreatorB implement the Creator and override the factoryMethod to return instances of their respective concrete products. The client code interacts with the Creator interface, enabling it to create different types of Product objects without knowing their concrete classes. Using Kotlin’s concise syntax and class hierarchy promotes readability and adherence to the pattern’s principles.
// Product
abstract class Product {
abstract fun operation(): String
}
// Concrete Products
class ConcreteProductA : Product() {
override fun operation(): String = "ConcreteProductA operation"
}
class ConcreteProductB : Product() {
override fun operation(): String = "ConcreteProductB operation"
}
// Creator
abstract class Creator {
abstract fun factoryMethod(): Product
fun someOperation(): String {
val product = factoryMethod()
return "Creator: The Product does something: ${product.operation()}"
}
}
// Concrete Creators
class ConcreteCreatorA : Creator() {
override fun factoryMethod(): Product = ConcreteProductA()
}
class ConcreteCreatorB : Creator() {
override fun factoryMethod(): Product = ConcreteProductB()
}
// Client
fun clientCode(creator: Creator) {
println(creator.someOperation())
}
fun main() {
clientCode(ConcreteCreatorA())
clientCode(ConcreteCreatorB())
}
The Factory Method is a creational design pattern that provides an interface for creating objects, but lets subclasses decide which class to instantiate. It promotes loose coupling by allowing the client to work with an abstract type, deferring the concrete class selection to factory subclasses.
This Rust implementation uses a trait Vehicle to define the common interface for different vehicle types. The VehicleFactory trait declares the create_vehicle method, which is the factory method. Concrete factories, like CarFactory and MotorcycleFactory, implement this trait to return specific vehicle types. The client code interacts with the factory interface, not the concrete vehicle classes, achieving decoupling. Rust’s traits and the Box<dyn Trait> type are used to achieve polymorphism and abstract the concrete types, fitting the language’s ownership and borrowing principles.
// Define the product interface
trait Vehicle {
fn drive(&self);
}
// Concrete products
struct Car {
model: String,
}
impl Car {
fn new(model: String) -> Self {
Car { model }
}
}
impl Vehicle for Car {
fn drive(&self) {
println!("Driving a {}!", self.model);
}
}
struct Motorcycle {
engine_size: u32,
}
impl Motorcycle {
fn new(engine_size: u32) -> Self {
Motorcycle { engine_size }
}
}
impl Vehicle for Motorcycle {
fn drive(&self) {
println!("Riding a motorcycle with {}cc engine!", self.engine_size);
}
}
// The Creator (abstract factory)
trait VehicleFactory {
fn create_vehicle(&self) -> Box<dyn Vehicle>;
}
// Concrete Creators
struct CarFactory {
model: String,
}
impl CarFactory {
fn new(model: String) -> Self {
CarFactory { model }
}
}
impl VehicleFactory for CarFactory {
fn create_vehicle(&self) -> Box<dyn Vehicle> {
Box::new(Car::new(self.model.clone()))
}
}
struct MotorcycleFactory {
engine_size: u32,
}
impl MotorcycleFactory {
fn new(engine_size: u32) -> Self {
MotorcycleFactory { engine_size }
}
}
impl VehicleFactory for MotorcycleFactory {
fn create_vehicle(&self) -> Box<dyn Vehicle> {
Box::new(Motorcycle::new(self.engine_size))
}
}
fn main() {
let car_factory = CarFactory::new("Sedan".to_string());
let motorcycle_factory = MotorcycleFactory::new(1000);
let car = car_factory.create_vehicle();
let motorcycle = motorcycle_factory.create_vehicle();
car.drive();
motorcycle.drive();
}
The Factory Method pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. It promotes loose coupling by decoupling specific classes from the code that uses them. This Go implementation uses an interface Product and concrete types ConcreteProductA and ConcreteProductB. The Creator interface defines the Operation which uses a Product created by the FactoryMethod. Concrete creators ConcreteCreatorA and ConcreteCreatorB override the FactoryMethod to return different concrete products. This is idiomatic Go as it leverages interfaces for abstraction and composition over inheritance, fitting well with Go’s design principles.
// Product interface defines the common interface for all products.
type Product interface {
Operation() string
}
// ConcreteProductA is a concrete product.
type ConcreteProductA struct{}
func (c *ConcreteProductA) Operation() string {
return "ConcreteProductA operation"
}
// ConcreteProductB is a concrete product.
type ConcreteProductB struct{}
func (c *ConcreteProductB) Operation() string {
return "ConcreteProductB operation"
}
// Creator interface declares the factory method.
type Creator interface {
FactoryMethod() Product
Operation() string
}
// ConcreteCreatorA creates ConcreteProductA.
type ConcreteCreatorA struct{}
func (c *ConcreteCreatorA) FactoryMethod() Product {
return &ConcreteProductA{}
}
func (c *ConcreteCreatorA) Operation() string {
product := c.FactoryMethod()
return "ConcreteCreatorA: " + product.Operation()
}
// ConcreteCreatorB creates ConcreteProductB.
type ConcreteCreatorB struct{}
func (c *ConcreteCreatorB) FactoryMethod() Product {
return &ConcreteProductB{}
}
func (c *ConcreteCreatorB) Operation() string {
product := c.FactoryMethod()
return "ConcreteCreatorB: " + product.Operation()
}
func main() {
creatorA := &ConcreteCreatorA{}
creatorB := &ConcreteCreatorB{}
println(creatorA.Operation())
println(creatorB.Operation())
}
The Factory Method pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. It promotes loose coupling by relieving the client of direct object creation responsibilities. This implementation uses function pointers to achieve the factory method effect in C, as C doesn’t natively support method overriding like OOP languages. A Product struct represents the objects created, and a Creator struct holds a function pointer (create_product) that acts as the factory method. Different concrete creators assign different functions to this pointer, effectively changing the object creation logic. This approach is common in C for achieving polymorphism and flexibility without full-blown OOP.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Product
typedef struct {
char* type;
} Product;
// Creator
typedef struct {
Product (*create_product)(void);
} Creator;
// Concrete Products
Product create_product_a() {
Product product;
product.type = strdup("Product A");
return product;
}
Product create_product_b() {
Product product;
product.type = strdup("Product B");
return product;
}
// Concrete Creators
typedef struct {
Creator base;
} ConcreteCreatorA, ConcreteCreatorB;
void init_creator_a(ConcreteCreatorA* creator) {
creator->base.create_product = create_product_a;
}
void init_creator_b(ConcreteCreatorB* creator) {
creator->base.create_product = create_product_b;
}
// Client
int main() {
ConcreteCreatorA creator_a;
init_creator_a(&creator_a);
ConcreteCreatorB creator_b;
init_creator_b(&creator_b);
Product product_a = creator_a.base.create_product();
Product product_b = creator_b.base.create_product();
printf("Created: %s\n", product_a.type);
printf("Created: %s\n", product_b.type);
free(product_a.type);
free(product_b.type);
return 0;
}
The Factory Method is a creational design pattern that provides an interface for creating objects but lets subclasses decide which class to instantiate. It promotes loose coupling by abstracting the object creation process. This example demonstrates a Document base class and concrete document types like PDFDocument and WordDocument. The DocumentFactory provides a method to create documents, and subclasses like PDFDocumentFactory and WordDocumentFactory override this method to return specific document types. This adheres to C++’s principles of polymorphism and abstraction through virtual functions and inheritance.
#include <iostream>
#include <string>
// Product
class Document {
public:
virtual void open() = 0;
virtual void save() = 0;
virtual ~Document() = default;
};
// Concrete Products
class PDFDocument : public Document {
public:
void open() override {
std::cout << "Opening PDF document." << std::endl;
}
void save() override {
std::cout << "Saving PDF document." << std::endl;
}
};
class WordDocument : public Document {
public:
void open() override {
std::cout << "Opening Word document." << std::endl;
}
void save() override {
std::cout << "Saving Word document." << std::endl;
}
};
// Creator
class DocumentFactory {
public:
virtual Document* createDocument() = 0;
virtual ~DocumentFactory() = default;
};
// Concrete Creators
class PDFDocumentFactory : public DocumentFactory {
public:
Document* createDocument() override {
return new PDFDocument();
}
};
class WordDocumentFactory : public DocumentFactory {
public:
Document* createDocument() override {
return new WordDocument();
}
};
// Client
int main() {
DocumentFactory* pdfFactory = new PDFDocumentFactory();
Document* pdfDoc = pdfFactory->createDocument();
pdfDoc->open();
pdfDoc->save();
delete pdfDoc;
delete pdfFactory;
DocumentFactory* wordFactory = new WordDocumentFactory();
Document* wordDoc = wordFactory->createDocument();
wordDoc->open();
wordDoc->save();
delete wordDoc;
delete wordFactory;
return 0;
}
The Factory Method pattern is a creational pattern that lets a class defer instantiation to subclasses. It defines an interface for creating an object, but lets subclasses decide which class to instantiate. This promotes loose coupling between the creator and the concrete products, allowing for flexibility and extensibility.
The C# example defines an IProduct interface and concrete product classes (ConcreteProductA, ConcreteProductB). The Creator class declares the FactoryMethod which returns an IProduct. Subclasses like ConcreteCreatorA and ConcreteCreatorB override FactoryMethod to return specific product types. This adheres to C#’s OOP principles, utilizing interfaces and inheritance to achieve polymorphism and decoupling. The use of abstract classes and methods is a common C# practice for defining contracts and enabling customization.
// IProduct interface
public interface IProduct
{
string Operation();
}
// Concrete Products
public class ConcreteProductA : IProduct
{
public string Operation()
{
return "ConcreteProductA operation";
}
}
public class ConcreteProductB : IProduct
{
public string Operation()
{
return "ConcreteProductB operation";
}
}
// Creator class
public abstract class Creator
{
public abstract IProduct FactoryMethod();
public void SomeCommonOperation()
{
IProduct product = FactoryMethod();
Console.WriteLine(product.Operation());
}
}
// Concrete Creators
public class ConcreteCreatorA : Creator
{
public override IProduct FactoryMethod()
{
return new ConcreteProductA();
}
}
public class ConcreteCreatorB : Creator
{
public override IProduct FactoryMethod()
{
return new ConcreteProductB();
}
}
// Usage
public class Program
{
public static void Main(string[] args)
{
Creator creatorA = new ConcreteCreatorA();
creatorA.SomeCommonOperation();
Creator creatorB = new ConcreteCreatorB();
creatorB.SomeCommonOperation();
}
}
The Factory Method pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. It promotes loose coupling by abstracting the object creation process. This allows for flexibility – new types can be added without modifying the existing code that uses the factory.
The code defines a Product interface and concrete products ConcreteProductA and ConcreteProductB. The Creator class declares the factoryMethod which returns a Product. ConcreteCreatorA and ConcreteCreatorB override factoryMethod to return their specific product types. The client code calls the factoryMethod through the creator, without knowing the exact product being created. This is idiomatic TypeScript due to its use of interfaces, classes, and inheritance to achieve abstraction and polymorphism, leveraging TypeScript’s type system for strong contracts.
// Product interface
interface Product {
operation(): string;
}
// Concrete Products
class ConcreteProductA implements Product {
operation(): string {
return "ConcreteProductA operation";
}
}
class ConcreteProductB implements Product {
operation(): string {
return "ConcreteProductB operation";
}
}
// Creator class
abstract class Creator {
abstract factoryMethod(): Product;
public someOperation(): string {
// Call the factory method to create the product.
const product = this.factoryMethod();
// Use the product.
return "Creator: The product is " + product.operation();
}
}
// Concrete Creators
class ConcreteCreatorA extends Creator {
factoryMethod(): Product {
return new ConcreteProductA();
}
}
class ConcreteCreatorB extends Creator {
factoryMethod(): Product {
return new ConcreteProductB();
}
}
// Client code
function clientCode(creator: Creator) {
console.log(creator.someOperation());
}
// Example usage
const creatorA = new ConcreteCreatorA();
clientCode(creatorA);
const creatorB = new ConcreteCreatorB();
clientCode(creatorB);
The Factory Method is a creational design pattern that provides an interface for creating objects but lets subclasses decide which class to instantiate. This promotes loose coupling between the creator and the concrete objects created. Here, we define a VehicleFactory with a createVehicle method. Subclasses like CarFactory and MotorcycleFactory override this method to return specific vehicle types. This allows adding new vehicle types without modifying the core VehicleFactory class. The implementation uses JavaScript’s prototypal inheritance and class syntax (ES6+) for a clean and maintainable structure, aligning with modern JavaScript best practices.
// Vehicle interface
class Vehicle {
constructor(type) {
this.type = type;
}
getType() {
return this.type;
}
}
// Concrete Vehicle classes
class Car extends Vehicle {
constructor() {
super("Car");
}
}
class Motorcycle extends Vehicle {
constructor() {
super("Motorcycle");
}
}
// Creator class (VehicleFactory)
class VehicleFactory {
createVehicle(type) {
if (type === "car") {
return new Car();
} else if (type === "motorcycle") {
return new Motorcycle();
} else {
throw new Error("Invalid vehicle type");
}
}
}
// Concrete Creator classes (CarFactory, MotorcycleFactory) - demonstrating extension
class CarFactory extends VehicleFactory {
createVehicle() {
return new Car();
}
}
class MotorcycleFactory extends VehicleFactory {
createVehicle() {
return new Motorcycle();
}
}
// Usage
const factory = new VehicleFactory();
const car = factory.createVehicle("car");
const motorcycle = factory.createVehicle("motorcycle");
console.log(car.getType()); // Output: Car
console.log(motorcycle.getType()); // Output: Motorcycle
const carFactory = new CarFactory();
const anotherCar = carFactory.createVehicle();
console.log(anotherCar.getType()); // Output: Car
The Factory Method is a creational design pattern that provides an interface for creating objects but lets subclasses decide which class to instantiate. It promotes loose coupling by allowing the client to work with abstractions rather than concrete implementations.
This Python example defines an abstract Document class and concrete MarkdownDocument and HTMLDocument classes. The DocumentFactory abstract class has a create_document method that subclasses must implement to return a specific Document type. MarkdownFactory and HTMLFactory provide these implementations. The client code requests a document through the factory interface without knowing the concrete document type being created. This aligns with Python’s dynamic typing and emphasis on interfaces/abstract base classes for flexibility.
from abc import ABC, abstractmethod
class Document(ABC):
@abstractmethod
def render(self):
pass
class MarkdownDocument(Document):
def render(self):
return "Rendering as Markdown..."
class HTMLDocument(Document):
def render(self):
return "Rendering as HTML..."
class DocumentFactory(ABC):
@abstractmethod
def create_document(self):
pass
class MarkdownFactory(DocumentFactory):
def create_document(self):
return MarkdownDocument()
class HTMLFactory(DocumentFactory):
def create_document(self):
return HTMLDocument()
def client_code(factory: DocumentFactory):
document = factory.create_document()
print(document.render())
if __name__ == "__main__":
markdown_factory = MarkdownFactory()
client_code(markdown_factory)
html_factory = HTMLFactory()
client_code(html_factory)
The Factory Method pattern is a creational design pattern that provides an interface for creating objects but lets subclasses decide which class to instantiate. This promotes loose coupling between the creator and the concrete products. Here, we define a Product interface and concrete product classes (ConcreteProductA, ConcreteProductB). The Creator class declares the factoryMethod which returns a Product. The ConcreteCreator overrides factoryMethod to return specific product types. This implementation is idiomatic Java due to its use of interfaces and abstract classes, leveraging polymorphism to achieve flexibility and maintainability.
// Product interface
interface Product {
String operation();
}
// Concrete Products
class ConcreteProductA implements Product {
@Override
public String operation() {
return "ConcreteProductA operation";
}
}
class ConcreteProductB implements Product {
@Override
public String operation() {
return "ConcreteProductB operation";
}
}
// Creator class
abstract class Creator {
abstract Product factoryMethod();
public final void someOperation() {
Product product = factoryMethod();
System.out.println(product.operation());
}
}
// Concrete Creator
class ConcreteCreator extends Creator {
@Override
public Product factoryMethod() {
return new ConcreteProductA();
}
}
class ConcreteCreatorB extends Creator {
@Override
public Product factoryMethod() {
return new ConcreteProductB();
}
}
// Usage
public class FactoryMethodDemo {
public static void main(String[] args) {
Creator creatorA = new ConcreteCreator();
creatorA.someOperation(); // Output: ConcreteProductA operation
Creator creatorB = new ConcreteCreatorB();
creatorB.someOperation(); // Output: ConcreteProductB operation
}
}