当我们谈论工厂模式时,我们实际上是在讨论一种创建对象的设计模式。工厂模式的目的是封装对象的创建过程,并将其交给一个单独的工厂类来处理。这种方式有助于解耦对象的创建和使用,使得系统更加灵活、可维护。
有三种主要的工厂模式:简单工厂模式、工厂方法模式和抽象工厂模式。
简单工厂模式:
简单工厂模式是一种创建型设计模式,它提供了一个简单的工厂类,该工厂类负责根据给定的条件创建对象。这个模式通常包括以下几个角色:
- 产品接口(Product Interface): 定义了产品的接口或抽象类。
- 具体产品(Concrete Product): 实现了产品接口的具体类。
- 工厂类(Factory Class): 包含一个方法,根据输入条件创建并返回具体产品的实例。
下面是一个简单的例子,假设我们有一个形状接口 Shape
和两个具体的形状类 Circle
和 Square
:
// 1. 产品接口 interface Shape { void draw(); } // 2. 具体产品类 class Circle implements Shape { @Override public void draw() { System.out.println("绘制圆形"); } } class Square implements Shape { @Override public void draw() { System.out.println("绘制正方形"); } } // 3. 工厂类 class ShapeFactory { // 工厂方法,根据输入条件创建并返回具体产品的实例 public Shape createShape(String shapeType) { if ("Circle".equalsIgnoreCase(shapeType)) { return new Circle(); } else if ("Square".equalsIgnoreCase(shapeType)) { return new Square(); } else { throw new IllegalArgumentException("无法创建该形状类型"); } } }
使用简单工厂模式的客户端代码如下:
public class Client { public static void main(String[] args) { // 创建工厂实例 ShapeFactory shapeFactory = new ShapeFactory(); // 通过工厂创建具体产品实例 Shape circle = shapeFactory.createShape("Circle"); Shape square = shapeFactory.createShape("Square"); // 调用产品的方法 circle.draw(); square.draw(); } }
在这个例子中,ShapeFactory
是工厂类,负责根据输入的字符串条件创建相应的形状对象。这样,客户端代码不需要直接实例化具体的形状类,而是通过工厂类来获取所需的对象,从而达到解耦的效果。
工厂方法模式(Factory Method Pattern):
工厂方法模式是一种创建型设计模式,它定义了一个创建对象的接口,但由子类决定要实例化的类。换句话说,工厂方法模式将对象的实例化推迟到子类中进行。
角色:
- 抽象产品接口(Product Interface): 定义了产品的接口或抽象类。
- 具体产品类(Concrete Product): 实现了产品接口的具体类。
- 抽象工厂类(Creator): 声明了创建产品的工厂方法,可以包含一些默认的实现。
- 具体工厂类(Concrete Creator): 实现了抽象工厂类,负责实际创建具体产品的实例。
下面是一个简单的例子,假设我们有一个抽象的日志接口 Logger
和两个具体的日志类 FileLogger
和 ConsoleLogger
:
// 1. 抽象产品接口 interface Logger { void logMessage(String message); } // 2. 具体产品类 class FileLogger implements Logger { @Override public void logMessage(String message) { System.out.println("写入日志到文件: " + message); } } class ConsoleLogger implements Logger { @Override public void logMessage(String message) { System.out.println("在控制台打印日志: " + message); } } // 3. 抽象工厂类 abstract class LoggerFactory { // 工厂方法,由子类实现,用于创建具体产品实例 public abstract Logger createLogger(); } // 4. 具体工厂类 class FileLoggerFactory extends LoggerFactory { @Override public Logger createLogger() { return new FileLogger(); } } class ConsoleLoggerFactory extends LoggerFactory { @Override public Logger createLogger() { return new ConsoleLogger(); } }
使用工厂方法模式的客户端代码如下:
public class Client { public static void main(String[] args) { // 创建具体工厂实例 LoggerFactory fileLoggerFactory = new FileLoggerFactory(); LoggerFactory consoleLoggerFactory = new ConsoleLoggerFactory(); // 使用具体工厂创建具体产品实例 Logger fileLogger = fileLoggerFactory.createLogger(); Logger consoleLogger = consoleLoggerFactory.createLogger(); // 调用产品的方法 fileLogger.logMessage("这是一个文件日志"); consoleLogger.logMessage("这是一个控制台日志"); } }
在工厂方法模式中,具体产品的创建由具体工厂类决定,这样就可以轻松地扩展和变化产品系列,同时保持客户端代码的稳定性。
抽象工厂模式(Abstract Factory Pattern):
抽象工厂模式是一种创建型设计模式,它提供一个接口,用于创建相关或依赖对象的家族,而不需要指定它们的具体类。抽象工厂模式是工厂方法模式的升级版,它引入了多个工厂方法,每个工厂方法负责创建一组相关的产品。
角色:
- 抽象产品接口(Abstract Product Interface): 定义了一组产品的接口或抽象类。
- 具体产品类(Concrete Product): 实现了产品接口的具体类。
- 抽象工厂接口(Abstract Factory): 声明了一组创建产品的抽象方法,每个方法对应一个产品。
- 具体工厂类(Concrete Factory): 实现了抽象工厂接口,负责创建一组相关的产品。
下面是一个简单的Java抽象工厂模式的实例,假设我们有两个产品家族:电脑和手机,每个家族有两个具体产品:台式电脑、笔记本电脑、智能手机和功能手机。
// 抽象产品接口 interface Computer { void show(); } interface Phone { void display(); } // 具体产品实现 class DesktopComputer implements Computer { @Override public void show() { System.out.println("Desktop Computer"); } } class LaptopComputer implements Computer { @Override public void show() { System.out.println("Laptop Computer"); } } class Smartphone implements Phone { @Override public void display() { System.out.println("Smartphone"); } } class FeaturePhone implements Phone { @Override public void display() { System.out.println("Feature Phone"); } } // 抽象工厂接口 interface ElectronicsFactory { Computer createComputer(); Phone createPhone(); } // 具体工厂实现 class DellFactory implements ElectronicsFactory { @Override public Computer createComputer() { return new DesktopComputer(); } @Override public Phone createPhone() { return new Smartphone(); } } class LenovoFactory implements ElectronicsFactory { @Override public Computer createComputer() { return new LaptopComputer(); } @Override public Phone createPhone() { return new FeaturePhone(); } } // 客户端 public class Client { public static void main(String[] args) { // 使用Dell工厂创建产品 ElectronicsFactory dellFactory = new DellFactory(); Computer dellComputer = dellFactory.createComputer(); Phone dellPhone = dellFactory.createPhone(); dellComputer.show(); dellPhone.display(); // 使用Lenovo工厂创建产品 ElectronicsFactory lenovoFactory = new LenovoFactory(); Computer lenovoComputer = lenovoFactory.createComputer(); Phone lenovoPhone = lenovoFactory.createPhone(); lenovoComputer.show(); lenovoPhone.display(); } }
在这个例子中,Computer
和 Phone
是抽象产品接口,DesktopComputer
、LaptopComputer
、Smartphone
和 FeaturePhone
是具体产品的实现。ElectronicsFactory
是抽象工厂接口,DellFactory
和 LenovoFactory
是具体工厂的实现。
客户端通过具体工厂来创建产品,而无需关心产品的具体实现。这样,如果需要更改产品的实现,只需更改具体工厂的实现,而客户端代码保持不变,实现了对象的创建和使用之间的解耦。