设计模式之工厂模式

文章目录

简单工厂模式

没有工厂模式时,客户端要自己 new 对象:

java 复制代码
Vehicle car = new Car();
Vehicle bike = new Bike();

这带来两个问题:

复制代码
1. 客户端需要知道所有产品的具体类名
2. 创建逻辑散落在各处,想改就得到处找

核心思想

把创建对象的逻辑集中到一个工厂类里,客户端不直接 new 对象。

实现

java 复制代码
interface Vehicle {
      void drive();
  }

class Car implements Vehicle {
      @Override
      public void drive() { System.out.println("开车"); }
  }

class Bike implements Vehicle {
      @Override
      public void drive() { System.out.println("骑自行车"); }
  }

class Truck implements Vehicle {
      @Override
      public void drive() { System.out.println("开卡车"); }
  }

  // 简单工厂
class SimpleVehicleFactory {
      public static Vehicle create(String type) {
          if ("car".equals(type))   return new Car();
          if ("bike".equals(type))  return new Bike();
          if ("truck".equals(type)) return new Truck();
          throw new IllegalArgumentException("Unknown type: " + type);
      }
  }

使用

java 复制代码
Vehicle car = SimpleVehicleFactory.create("car");
car.drive(); // 开车

Vehicle bike = SimpleVehicleFactory.create("bike");
bike.drive(); // 骑自行车

缺点

每次新增产品(比如 ElectricCar),都必须修改 SimpleVehicleFactory 的 if-else,违背开闭原则。

工厂方法模式

简单工厂的核心矛盾在于:所有创建逻辑都压在一个类里,新增产品必然要动这个类。

工厂方法的解决思路很直接------把那个大 if-else 拆开,每个分支变成一个独立的工厂子类。

核心思想

定义一个创建对象的接口,但把实例化哪个类的决定权延迟到子类。

实现

第一步:产品接口不变

java 复制代码
interface Vehicle {
      void drive();
  }

class Car implements Vehicle {
      @Override
      public void drive() { System.out.println("开车"); }
  }

class Bike implements Vehicle {
      @Override
      public void drive() { System.out.println("骑自行车"); }
  }

第二步:定义抽象工厂

java 复制代码
interface VehicleFactory {
      Vehicle createVehicle(); // 工厂方法,创建什么由子类决定
  }

第三步:每种产品对应一个具体工厂

java 复制代码
class CarFactory implements VehicleFactory {
      @Override
      public Vehicle createVehicle() { return new Car(); }
  }

class BikeFactory implements VehicleFactory {
      @Override
      public Vehicle createVehicle() { return new Bike(); }
  }

使用

java 复制代码
VehicleFactory factory = new CarFactory();
Vehicle car = factory.createVehicle();
car.drive(); // 开车

factory = new BikeFactory();
Vehicle bike = factory.createVehicle();
bike.drive(); // 骑自行车

验证

新增电动车,零修改旧代码

java 复制代码
 // 新增产品
class ElectricCar implements Vehicle {
      @Override
      public void drive() { System.out.println("开电动车"); }
  }

  // 新增工厂,完全不动任何现有类
class ElectricCarFactory implements VehicleFactory {
      @Override
      public Vehicle createVehicle() { return new ElectricCar(); }
  }

缺点

  • 类数量膨胀:产品每增加一种,就要同步新增一个工厂类
  • 只能生产单一产品:一个工厂只对应一种产品,无法保证产品之间的关联性

抽象工厂模式

工厂方法解决了扩展性问题,但有个新场景它处理不好:

假设现在有 A 品牌和 B 品牌,每个品牌都生产汽车和自行车。客户端想要一套 A品牌的产品,用工厂方法需要分别调用 ACarFactory 和 ABikeFactory,无法保证拿到的产品是同一品牌的(代码层面没有约束机制,靠的是开发者自觉,一旦粗心就会混用)。

核心思想

一个工厂不再生产单一产品,而是生产一套相关联的产品族,保证客户端只拿到一套配套的产品。

实现

java 复制代码
  // 产品接口
interface Car  { void drive(); }
interface Bike { void ride();  }

  // A 品牌产品
class ACar implements Car {
      @Override public void drive() { System.out.println("A 品牌轿车"); }
  }
class ABike implements Bike {
      @Override public void ride()  { System.out.println("A 品牌自行车"); }
  }

  // B 品牌产品
class BCar implements Car {
      @Override public void drive() { System.out.println("B 品牌轿车"); }
  }
class BBike implements Bike {
      @Override public void ride()  { System.out.println("B 品牌自行车"); }
  }

  // 抽象工厂:生产一套产品
interface Factory {
      Car  createCar();
      Bike createBike();
  }

  // A 品牌工厂,只生产 A 品牌的一套产品
class AFactory implements Factory {
      @Override public Car  createCar()  { return new ACar();  }
      @Override public Bike createBike() { return new ABike(); }
  }

  // B 品牌工厂,只生产 B 品牌的一套产品
class BFactory implements Factory {
      @Override public Car  createCar()  { return new BCar();  }
      @Override public Bike createBike() { return new BBike(); }
  }

使用

java 复制代码
  // 切换品牌只需换一行
Factory factory = new AFactory();
Car  car  = factory.createCar();   // A 品牌轿车
Bike bike = factory.createBike();  // A 品牌自行车,品牌一致 ✅

  // 换成 B 品牌
factory = new BFactory();
car  = factory.createCar();        // B 品牌轿车
bike = factory.createBike();       // B 品牌自行车,品牌一致 ✅
相关推荐
名字还没想好☜7 小时前
Python f-string 进阶:数字格式化、对齐填充、调试 = 号与嵌套表达式
开发语言·数据库·python·字符串格式化·f-string
·薯条大王7 小时前
经济实惠玩云服务器|一台云服务器多人共用,子账号配置教程
java·linux·运维·服务器·汇编·c++·python
用户938515635077 小时前
从零在浏览器里跑 DeepSeek-R1:WebGPU + Transformer.js 全链路实战
前端·设计模式·typescript
一壶浊酒..10 小时前
Scrape Webpack练习
开发语言·javascript·webpack
ZJH__GO10 小时前
网络编程v4pro--实现聊天室文件传输功能
java·服务器·网络·计算机网络
程序员黑豆10 小时前
Windows 系统 Java 环境变量配置全攻略:解决“不是内部或外部命令”
java·前端·ai编程
命运之光10 小时前
【C语言完整代码】就诊信息管理系统
java·c语言·开发语言
凤山老林11 小时前
Spring Boot @Async 线上实战:从默认配置到生产级线程池治理
java·spring boot·后端
命运之光11 小时前
【C语言完整代码】图书管理系统:图书馆场景下的增删改查实战
c语言·开发语言
猿长大人11 小时前
C# | Serilog 新手入门
开发语言·c#·.net·log