core
工厂模式(Factory Pattern)是一种创建型设计模式,用于创建对象而不暴露对象创建的逻辑。它将对象的实例化过程封装在一个工厂类中,客户端通过调用工厂类的方法来创建对象,从而实现了解耦和灵活性。
工厂模式的核心思想是将对象的创建与使用分离。客户端不直接实例化对象,而是通过调用工厂类的方法来获取对象实例。工厂类根据客户端的需求,决定实例化哪个具体对象,并将其返回给客户端。
三种工厂模式的识别
简单工厂模式
、工厂方法模式
和抽象工厂模式
都属于创建型设计模式,用于封装对象的创建过程(相同点),但它们之间有明显的区别。
不同点:
简单工厂模式(Simple Factory Pattern):
简单工厂模式通过一个工厂类来创建产品对象,客户端通过调用工厂类的静态方法或实例方法来获取对象实例。
工厂类负责根据客户端的需求,决定实例化哪个具体产品类。
简单工厂模式的主要特点是工厂类集中了对象的创建逻辑,客户端通过工厂类来创建产品对象,而无需直接实例化具体产品类。但是,当需求变化时,需要修改工厂类的代码。工厂方法模式(Factory Method Pattern):
工厂方法模式将对象的创建延迟到子类中,每个具体产品类都有对应的工厂类。
抽象工厂类定义了创建产品对象的抽象方法,每个具体工厂类实现了抽象工厂类,负责创建具体产品的实例。
客户端通过调用具体工厂类的方法来创建产品对象。客户端可以通过扩展抽象工厂类和具体工厂类来创建新的产品。抽象工厂模式(Abstract Factory Pattern):
抽象工厂模式提供了一种创建一系列相关或相互依赖对象的接口,而无需指定具体类。
抽象工厂模式包括抽象工厂类、具体工厂类、抽象产品类和具体产品类。
抽象工厂类定义了一组创建产品对象的抽象方法,每个具体工厂类实现了抽象工厂类,负责创建一组相关的具体产品。
客户端通过调用具体工厂类的方法来创建一组相关的产品对象。
总结:
简单工厂模式适用于创建单一类型的产品,通过一个工厂类来创建产品对象。
工厂方法模式适用于创建一类产品,每个具体产品都有对应的工厂类,通过扩展工厂类来创建新的产品。
抽象工厂模式适用于创建一组相关的产品,每个具体工厂类负责创建一组相关的产品对象。
选择使用哪种模式取决于具体需求和设计目标:
- 简单工厂模式简单易用,但对于复杂的产品结构不够灵活;
- 工厂方法模式适用于需要灵活扩展产品类的情况;
- 抽象工厂模式适用于需要创建一组相关产品 并保持一致性的情况。(抽象工厂模式适用于一组相关的产品对象的创建,如果产品对象之间没有相关性或依赖关系,请考虑使用工厂方法模式。)
Simple Factory Pattern
下面是一个简单的示例代码,说明了简单工厂模式的基本结构:
// 产品接口interface Product { void operation();}// 具体产品Aclass ConcreteProductA implements Product { public void operation() { System.out.println("ConcreteProductA operation"); }}// 具体产品Bclass ConcreteProductB implements Product { public void operation() { System.out.println("ConcreteProductB operation"); }}// 工厂类class Factory { public Product createProduct(String type) { if (type.equals("A")) { return new ConcreteProductA(); } else if (type.equals("B")) { return new ConcreteProductB(); } return null; }}// 客户端代码public class Client { public static void main(String[] args) { Factory factory = new Factory(); // 创建具体产品A Product productA = factory.createProduct("A"); productA.operation(); // 创建具体产品B Product productB = factory.createProduct("B"); productB.operation(); }}
在上面的示例中,Product 是产品接口,定义了产品的操作方法。ConcreteProductA 和 ConcreteProductB 是具体产品类,实现了产品接口,并定义了各自的操作方法。Factory 是工厂类,负责创建产品对象的方法。客户端通过调用工厂类的方法来创建具体产品的实例,并调用其操作方法。
通过使用工厂模式,客户端可以通过工厂类来创建具体产品的实例,而无需直接依赖具体产品类。这样可以实现代码的解耦和灵活性,使得系统更易于扩展和维护。
Factory Method Pattern
下面是一个简单的示例代码,说明了工厂方法模式的基本结构:
// 抽象产品interface Product { void operation();}// 具体产品Aclass ConcreteProductA implements Product { public void operation() { System.out.println("ConcreteProductA operation"); }}// 具体产品Bclass ConcreteProductB implements Product { public void operation() { System.out.println("ConcreteProductB operation"); }}// 抽象工厂interface Factory { Product createProduct();}// 具体工厂Aclass ConcreteFactoryA implements Factory { public Product createProduct() { return new ConcreteProductA(); }}// 具体工厂Bclass ConcreteFactoryB implements Factory { public Product createProduct() { return new ConcreteProductB(); }}// 客户端代码public class Client { public static void main(String[] args) { Factory factoryA = new ConcreteFactoryA(); Product productA = factoryA.createProduct(); productA.operation(); Factory factoryB = new ConcreteFactoryB(); Product productB = factoryB.createProduct(); productB.operation(); }}
在上面的示例中,Product 是抽象产品接口,定义了产品的操作方法。ConcreteProductA 和 ConcreteProductB 是具体产品类,实现了产品接口,并定义了各自的操作方法。Factory 是抽象工厂接口,定义了创建产品对象的抽象方法。ConcreteFactoryA 和 ConcreteFactoryB 是具体工厂类,实现了抽象工厂接口,负责创建具体产品的实例。
客户端通过调用具体工厂类的方法来创建具体产品的实例,并调用其操作方法。通过使用工厂方法模式,客户端可以通过工厂类来创建产品对象,而无需直接依赖具体产品类。这样可以实现代码的解耦和灵活性,使得系统更易于扩展和维护。
Abstract Factory Pattern
一个常见的实际应用抽象工厂模式的例子是图形用户界面(GUI)库。假设我们正在开发一个跨平台的GUI库,需要支持不同操作系统(如Windows、macOS和Linux)下的窗口和按钮。
在这种情况下,可以使用抽象工厂模式来创建一组相关的产品对象,包括窗口和按钮。首先,定义抽象产品接口:
// 抽象窗口产品interface Window { void render();}// 抽象按钮产品interface Button { void click();}
然后,实现具体的窗口和按钮产品类,每个操作系统对应一个具体产品类:
// Windows窗口产品class WindowsWindow implements Window { public void render() { System.out.println("Render Windows window"); }}// Windows按钮产品class WindowsButton implements Button { public void click() { System.out.println("Click Windows button"); }}//----------------------------------------------------------// macOS窗口产品class MacOSWindow implements Window { public void render() { System.out.println("Render macOS window"); }}// macOS按钮产品class MacOSButton implements Button { public void click() { System.out.println("Click macOS button"); }}//----------------------------------------------------------// Linux窗口产品class LinuxWindow implements Window { public void render() { System.out.println("Render Linux window"); }}// Linux按钮产品class LinuxButton implements Button { public void click() { System.out.println("Click Linux button"); }}
接下来,定义抽象工厂接口来创建窗口和按钮:
// 抽象GUI工厂interface GUIFactory { Window createWindow(); Button createButton();}
然后,实现具体的GUI工厂类,每个操作系统对应一个具体工厂类:
// Windows GUI工厂class WindowsGUIFactory implements GUIFactory { public Window createWindow() { return new WindowsWindow(); } public Button createButton() { return new WindowsButton(); }}// macOS GUI工厂class MacOSGUIFactory implements GUIFactory { public Window createWindow() { return new MacOSWindow(); } public Button createButton() { return new MacOSButton(); }}// Linux GUI工厂class LinuxGUIFactory implements GUIFactory { public Window createWindow() { return new LinuxWindow(); } public Button createButton() { return new LinuxButton(); }}
现在,客户端可以通过抽象工厂来创建特定操作系统下的窗口和按钮,并使用它们:
public class Client { public static void main(String[] args) { // 创建Windows风格的GUI GUIFactory windowsFactory = new WindowsGUIFactory(); Window windowsWindow = windowsFactory.createWindow(); Button windowsButton = windowsFactory.createButton(); windowsWindow.render(); windowsButton.click(); // 创建macOS风格的GUI GUIFactory macosFactory = new MacOSGUIFactory(); Window macosWindow = macosFactory.createWindow(); Button macosButton = macosFactory.createButton(); macosWindow.render(); macosButton.click(); // 创建Linux风格的GUI GUIFactory linuxFactory = new LinuxGUIFactory(); Window linuxWindow = linuxFactory.createWindow(); Button linuxButton = linuxFactory.createButton(); linuxWindow.render(); linuxButton.click(); }}
通过使用抽象工厂模式,我们可以轻松地扩展GUI库以支持新的操作系统,只需实现新的具体产品和具体工厂类即可,而不需要修改现有的客户端代码。这样,不同操作系统下的窗口和按钮将保持一致性,并且客户端无需关心具体产品的创建过程,只需使用抽象工厂接口来创建产品对象。