设计模式
- 1.工厂模式
- 1.1 简单工厂模式
- 1.2 工厂方法模式
- 1.3 抽象工厂模式
- 1.3.1 扩展一个产品族
- 1.3.2 扩展一个产品等级
- 1.4 工厂方法模式和抽象工厂模式的区别
1.工厂模式
背景: 我们需要生产两款车: BMW320和BMW523

public class BMW320 {
}
public class BMW523 {
}
在没有工厂模式之前, 我们只能自己手动创建(new)这几款车
public static void main(String[] args) {BMW320 bmw320 = new BMW320();BMW523 bmw523 = new BMW523();
}
之后就出现了工厂, 使用工厂可以封装对象的创建逻辑,提高代码的灵活性、可维护性和可扩展性,同时降低客户端代码与具体产品类的耦合度。
1.1 简单工厂模式

代码改造:
- 产品类: 继承同一个共性类(抽象类)
// 抽象类
abstract class BMW {
}
// 实现类
public class BMW320 extends BMW {
}
// 实现类
public class BMW523 extends BMW {
}
- 工厂类: 提供创建产品的通用方法
public class Factory {public BMW createBMW(int type) {switch (type) {case 320:return new BMW320();case 523:return new BMW523();default:break;}return null;}
}
- 生产者: 通过工厂获取对象
public static void main(String[] args) {Factory factory = new Factory();BMW bmw320 = factory.createBMW(320);BMW bmw523 = factory.createBMW(523);
}
简易工厂模式的优缺点:
- 优点
- 封装对象创建逻辑: 工厂封装了对象的创建逻辑, 生产者无需了解具体的对象创建逻辑.这提高了代码的
可读性、可维护性、复用性 - 松耦合: 生产者直接通过工厂来获取对象, 只需要知道产品类所需的具体参数即可
- 封装对象创建逻辑: 工厂封装了对象的创建逻辑, 生产者无需了解具体的对象创建逻辑.这提高了代码的
- 缺点
- 不符合开放-封闭原则: 当需要添加新的产品类时, 需要改动工厂类的代码, 违反了开发-封闭原则
- 违背单一职责原则: 简单工厂模式通常将多个产品的创建逻辑都集中在一个工厂类中, 这可能导致该工厂类的职责过于庞大, 不符合单一职责原则
1.2 工厂方法模式
工厂方法模式将工厂抽象化,并定义一个创建对象的接口。每增加新产品,只需增加该产品以及对应的具体实现工厂类,由具体工厂类决定要实例化的产品是哪个,将对象的创建与实例化延迟到子类,这样工厂的设计就符合“开闭原则”了,扩展时不必去修改原来的代码。

代码改造:
- 产品类不改动
- 工厂类: 工厂抽象化, 每新增一个产品, 只需要增加该产品的具体实现工厂类
interface FactoryBMW {BMW createBMW();
}
public class FactoryBMW320 implements FactoryBMW {@Overridepublic BMW320 createBMW() {return new BMW320();}
}
public class FactoryBMW523 implements FactoryBMW {@Overridepublic BMW523 createBMW() {return new BMW523();}
}
- 生产者: 由具体工厂类决定要实例化的产品是哪个
public static void main(String[] args) {FactoryBMW320 factoryBMW320 = new FactoryBMW320();BMW320 bmw320 = factoryBMW320.createBMW();FactoryBMW523 factoryBMW523 = new FactoryBMW523();BMW523 bmw523 = factoryBMW523.createBMW();
}
工厂方法模式的优缺点:
- 优点
- 符合开发-封闭原则: 新增产品时只需要添加新的具体工厂类和产品类, 无需修改现有代码, 符合开放-封闭原则。
- 遵循单一职责原则: 每个具体工厂类负责创建特定类型的产品, 符合单一职责原则, 使得系统更加模块化、清晰。
- 缺点
- 类的个数增加: 使用工厂方法模式会导致类的数量增加, 每个具体产品都需要对应一个具体工厂,这可能使得类的数量相对较多。
- 不同的工厂类之间代码重复: 如果多个具体工厂类之间有相似的实现,可能导致代码的重复。在这种情况下,可以考虑使用抽象工厂模式来减少重复代码。
1.3 抽象工厂模式
在介绍抽象工厂模式前,我们先厘清两个概念:
- 产品等级结构: 同一类型的产品
- 产品族: 同一品牌的不同产品就构成了一个产品族

横构图

竖构图

- 产品类: 现在生产发动机A、B和空调A、B这四类产品
//发动机产品接口
public interface Engine {void create();
}
public class EngineA implements Engine{ public void create() { System.out.println("制造-->EngineA"); }
}
public class EngineB implements Engine{ public void create() { System.out.println("制造-->EngineB"); }
}//空调产品接口
public interface Aircondition {void create();
}
public class AirconditionA implements Aircondition{ public void create() { System.out.println("制造-->AirconditionA"); }
}
public class AirconditionB implements Aircondition{ public void create() { System.out.println("制造-->AirconditionB"); }
}
- 工厂类: 工厂接口类、工厂实现类
public interface Factory { //制造发动机public Engine createEngine();//制造空调 public Aircondition createAircondition();
}
//为宝马320系列生产配件
public class FactoryBMW320 implements Factory { @Override public Engine createEngine() { return new EngineA(); } @Override public Aircondition createAircondition() { return new AirconditionA(); }
}
//宝马523系列
public class FactoryBMW523 implements Factory { @Override public Engine createEngine() { return new EngineB(); } @Override public Aircondition createAircondition() { return new AirconditionB(); }
}
- 生产者
public class Customer { public static void main(String[] args){ //生产宝马320系列配件FactoryBMW320 factoryBMW320 = new FactoryBMW320(); factoryBMW320.createEngine();factoryBMW320.createAircondition();//生产宝马523系列配件 FactoryBMW523 factoryBMW523 = new FactoryBMW523(); factoryBMW523.createEngine();factoryBMW523.createAircondition();}
}
抽象工厂模式的缺点: 拓展一个产品等级很麻烦
1.3.1 扩展一个产品族

扩展一个产品族很简单, 例如新增一个BMW118的工厂, 只需再新增C类发动机和C类空调的实现类即可(新增一个产品族不需要修改原来的代码), 符合OCP原则
1.3.2 扩展一个产品等级

扩展一个产品等级结构是非常麻烦的, 除了新增产品接口、产品实现类以外, 你还需要修改原来的代码(工厂接口、每一个工厂实现类)
淡黄色为新增的接口、实现类红色对原代码的修改
1.4 工厂方法模式和抽象工厂模式的区别
- 适用场景不同
- 工厂方法模式适用于单一产品等级结构, 一个工厂只创建一个具体产品
- 抽象工厂模式 适用于多个产品等级结构, 一个工厂创建一整个产品族
- 开发封闭原则
- 工厂方法模式对工厂的扩展是开放的,对于产品等级结构的扩展是封闭的
- 抽象工厂模式的扩展既对产品等级结构开放,也对产品族的扩展开放。