文章目录
简单工厂模式
没有工厂模式时,客户端要自己 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 品牌自行车,品牌一致 ✅