当我们谈论工厂模式时,我们实际上是在讨论一种创建对象的设计模式。工厂模式的目的是封装对象的创建过程,并将其交给一个单独的工厂类来处理。这种方式有助于解耦对象的创建和使用,使得系统更加灵活、可维护。
有三种主要的工厂模式:简单工厂模式、工厂方法模式和抽象工厂模式。
简单工厂模式是一种创建型设计模式,它提供了一个简单的工厂类,该工厂类负责根据给定的条件创建对象。这个模式通常包括以下几个角色:
产品接口(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
是工厂类,负责根据输入的字符串条件创建相应的形状对象。这样,客户端代码不需要直接实例化具体的形状类,而是通过工厂类来获取所需的对象,从而达到解耦的效果。
工厂方法模式是一种创建型设计模式,它定义了一个创建对象的接口,但由子类决定要实例化的类。换句话说,工厂方法模式将对象的实例化推迟到子类中进行。
角色:
抽象产品接口(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 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
是具体工厂的实现。
客户端通过具体工厂来创建产品,而无需关心产品的具体实现。这样,如果需要更改产品的实现,只需更改具体工厂的实现,而客户端代码保持不变,实现了对象的创建和使用之间的解耦。