~/app/articles/NORMAL

cat article/42.md

工厂模式 (Factory Method)全面讲解

学习笔记
设计模式
工厂方法模式
软件开发
面向对象编程
Java
代码设计

本文详细介绍了工厂方法模式的概念、优势、结构以及示例代码,适合软件开发者学习面向对象设计原则和代码设计模式。

工厂方法模式 (Factory Method) 全面讲解

1. 什么是工厂方法模式?

工厂方法模式定义了一个创建对象的接口,但由子类决定实例化哪个类。

  • 核心思想:将对象的创建延迟到子类,解决直接new带来的耦合问题。
  • 类比:餐厅点餐,菜单是接口,具体菜品由后厨(子类)决定。

2. 为什么需要工厂方法模式?

直接new的问题:

// 硬编码创建对象,紧耦合!
Car car = new Tesla();
// 如果想换成比亚迪,需要修改代码:
Car car = new BYD();
  • 缺点:违反开闭原则(对扩展开放,对修改关闭)。

工厂方法的优势:

// 通过工厂创建,客户端代码无需修改
Car car = CarFactory.createCar();
  • 解耦:客户端代码和具体类分离。
  • 扩展性:新增车型只需扩展工厂子类。

3. 工厂方法模式的结构

角色:

  1. Product(抽象产品):定义对象的接口(如Car)。
  2. ConcreteProduct(具体产品):实现抽象产品(如Tesla、BYD)。
  3. Creator(抽象工厂):声明工厂方法(如CarFactory)。
  4. ConcreteCreator(具体工厂):实现工厂方法(如TeslaFactory)。

3.1 示例代码(汽车工厂)

步骤1:定义抽象产品
public interface Car {
    void drive();
}
步骤2:定义具体产品
public class Tesla implements Car {
    @Override
    public void drive() {
        System.out.println("驾驶特斯拉");
    }
}

public class BYD implements Car {
    @Override
    public void drive() {
        System.out.println("驾驶比亚迪");
    }
}
步骤3:定义抽象工厂
public interface CarFactory {
    Car createCar();  // 工厂方法
}
步骤4:定义具体工厂
public class TeslaFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new Tesla();
    }
}

public class BYDFactory implements CarFactory {
    @Override
    public Car createCar() {
        return new BYD();
    }
}
步骤5:客户端调用
public class Client {
    public static void main(String[] args) {
        CarFactory factory = new TeslaFactory();  // 切换工厂即可换产品
        Car car = factory.createCar();
        car.drive();  // 输出:驾驶特斯拉
    }
}

4. 工厂方法 vs 简单工厂

简单工厂(非标准模式)

public class SimpleCarFactory {
    public static Car createCar(String type) {
        if ("Tesla".equals(type)) {
            return new Tesla();
        } else if ("BYD".equals(type)) {
            return new BYD();
        }
        throw new IllegalArgumentException("未知车型");
    }
}
  • 缺点:违反开闭原则(新增车型需修改工厂类)。

工厂方法(标准模式)

  • 优点:新增车型只需新增工厂子类(如AudiFactory),无需修改原有代码。

5. 应用场景

  • 经典用途:
    • 日志框架(如Log4j的LoggerFactory)。
    • JDBC的Connection(不同数据库驱动)。
  • 面试考点:
    • 工厂方法与抽象工厂的区别(前者生产一种产品,后者生产产品族)。

6. 互动实践

问题1:以下代码违反了什么原则?如何改进?

public class CarFactory {
    public Car createCar(String brand) {
        if ("Tesla".equals(brand)) {
            return new Tesla();
        } else if ("BYD".equals(brand)) {
            return new BYD();
        }
        return null;
    }
}
  • 答案:违反开闭原则。改进方式:使用工厂方法模式,为每个品牌创建独立工厂类。

问题2:用工厂方法实现一个PizzaStore

// 你的任务:补全Pizza工厂方法模式
public interface Pizza {
    void bake();
}

public class MargheritaPizza implements Pizza { /*...*/ }
public class PepperoniPizza implements Pizza { /*...*/ }

public interface PizzaFactory {
    Pizza createPizza();
}

public class MargheritaFactory implements PizzaFactory { /*...*/ }
// 补全PepperoniFactory和客户端调用代码

7. 考试练习题

题目1(概念题)

工厂方法模式的目的是什么?
A. 封装对象的创建过程
B. 强制使用继承
C. 减少类的数量
D. 替代多态

答案:A


题目2(代码填空)

补全以下工厂方法模式的代码:

public interface Document {
    void open();
}

public class WordDocument implements Document {
    @Override
    public void open() { System.out.println("打开Word"); }
}

public interface DocumentFactory {
    ____ createDocument();  // 填空1
}

public class WordFactory implements DocumentFactory {
    @Override
    public ____ createDocument() {  // 填空2
        return ____;  // 填空3
    }
}

答案:

  1. Document
  2. Document
  3. new WordDocument()

题目3(设计题)

如何用工厂方法模式设计一个跨平台UI组件(如Button)?画出类图并说明。
答案:

  • 抽象产品:Button接口(含render()方法)。
  • 具体产品:WindowsButton、MacButton。
  • 抽象工厂:ButtonFactory接口。
  • 具体工厂:WindowsButtonFactory、MacButtonFactory。
$ comments --list (0)

// not signed in


// no comments yet