说明:
实现调用者和消费者的分离。满足OOP七大原则(开闭原则、依赖倒转原则、迪米特法则。)
分类:
- 简单工厂
- 工厂方法
- 抽象工厂
1、简单工厂
说明:
一个工厂决定创建那种具体产品类的实例。
UML类图:
示例:
Car接口
package cn.aalo.factory.simple;
/**
* @author JuRan
* @date 18/2/2025 上午 10:21
* @description:
*/
public interface Car {
void name();
}
Car实现类
package cn.aalo.factory.simple;
/**
* @author JuRan
* @date 18/2/2025 上午 10:23
* @description: 车的实现类
*/
public class WuLing implements Car {
@Override
public void name() {
System.out.println("五菱");
}
}
package cn.aalo.factory.simple;
/**
* @author JuRan
* @date 18/2/2025 上午 10:24
* @description: Car的实现类
*/
public class AoDi implements Car{
@Override
public void name() {
System.out.println("奥迪");
}
}
简单工厂
package cn.aalo.factory.simple;
/**
* @author JuRan
* @date 18/2/2025 上午 10:26
* @description: 车的工厂类
*/
public class CarFactory {
public static Car getCar(String car){
if (car.equals("wl")){
return new WuLing();
} else if (car.equals("ad")) {
return new AoDi();
}else {
return null;
}
}
}
消费者
package cn.aalo.factory.simple;
/**
* @author JuRan
* @date 18/2/2025 上午 10:24
* @description: 消费者
*/
public class Consumer {
public static void main(String[] args) {
Car wl = CarFactory.getCar("wl");
wl.name();
Car ad = CarFactory.getCar("ad");
ad.name();
}
}
优点:
- 客户端不需要知道具体类的创建方式,降低耦合度。
- 结构简单,适用于对象创建较少的情况。
缺点:
- 违反开闭原则,新增车的实现类时需要修改工厂类。
2、工厂方法
说明:
定义一个创建对象接口,让子类决定实例化哪种产品。
UML类图:
示例:
Car接口
package cn.aalo.factory.method;
/**
* @author JuRan
* @date 18/2/2025 上午 10:21
* @description:
*/
public interface Car {
void name();
}
Car 实现类
package cn.aalo.factory.method;
/**
* @author JuRan
* @date 18/2/2025 上午 10:23
* @description: 车的实现类
*/
public class WuLing implements Car {
@Override
public void name() {
System.out.println("五菱");
}
}
package cn.aalo.factory.method;
/**
* @author JuRan
* @date 18/2/2025 上午 10:24
* @description: Car的实现类
*/
public class AoDi implements Car {
@Override
public void name() {
System.out.println("奥迪");
}
}
定义一个创建对象接口,让子类决定实现哪个产品
创建对象接口Factory
package cn.aalo.factory.method;
/**
* @author JuRan
* @date 18/2/2025 上午 10:56
* @description: 奥迪工厂类
*/
public interface CarFactory {
Car createFactory();
}
子类实现类(WuLing,AoDi)
package cn.aalo.factory.method;
/**
* @author JuRan
* @date 18/2/2025 上午 10:57
* @description: 五菱工厂实现类
*/
public class WuLingFactory implements CarFactory{
@Override
public Car createFactory() {
return new WuLing();
}
}
package cn.aalo.factory.method;
/**
* @author JuRan
* @date 18/2/2025 上午 10:57
* @description: 奥迪工厂实现类
*/
public class AoDiFactory implements CarFactory{
@Override
public Car createFactory() {
return new AoDi();
}
}
消费者类利用工厂方法,得到产品。
Consumer
package cn.aalo.factory.method;
import cn.aalo.factory.simple.AoDi;
import cn.aalo.factory.simple.CarFactory;
/**
* @author JuRan
* @date 18/2/2025 上午 10:24
* @description: 消费者
*/
public class Consumer {
public static void main(String[] args) {
Car AoDi = new AoDiFactory().createFactory();
AoDi.name();
Car wuLing = new WuLingFactory().createFactory();
wuLing.name();
}
}
优点:
- 遵循开放封闭原则,新增产品时只需增加新的工厂类,不需要修改已有代码。
- 代码结构清晰,符合单一职责原则。
缺点:
- 需要为每个产品类创建工厂,增加类的数量越大,代码量越大。
注:
从结构复杂度、代码复杂度、编程复杂度、管理复杂度等方面来说,简单工厂都是具有其中的佼佼者,但是从设计原则上来说;工厂方法更胜一筹,实际业务中简单方法可能更胜一筹。
3、抽象工厂
说明:
抽象工厂
提供了一个创建一系列相关
或者相互依赖的对象接口
,无需指定它们具体的类。
UML类图:
示例:
产品类接口
package cn.aalo.factory.abstractFactory;
/**
* @author JuRan
* @date 21/2/2025 上午 11:01
* @description: 笔记本接口
*/
public interface BookProduct {
void start();
void call();
void sendMessage();
}
package cn.aalo.factory.abstractFactory;
/**
* @author JuRan
* @date 21/2/2025 上午 11:01
* @description: 手机接口
*/
public interface PhoneProduct {
void start();
void call();
void sendMessage();
}
产品类接口实现类(笔记本)
package cn.aalo.factory.abstractFactory;
/**
* @author JuRan
* @date 21/2/2025 上午 11:02
* @description: 华为笔记本
*/
public class HuaWeiBook implements BookProduct {
@Override
public void start() {
System.out.println("华为BookStart");
}
@Override
public void call() {
System.out.println("华为BookCall");
}
@Override
public void sendMessage() {
System.out.println("sendMessage");
}
}
package cn.aalo.factory.abstractFactory;
/**
* @author JuRan
* @date 21/2/2025 上午 11:02
* @description: 小米笔记本
*/
public class XiaoMiBook implements BookProduct {
@Override
public void start() {
System.out.println("小米BookStart");
}
@Override
public void call() {
System.out.println("小米BookCall");
}
@Override
public void sendMessage() {
System.out.println("sendMessage");
}
}
产品类接口实现类(手机)
package cn.aalo.factory.abstractFactory;
/**
* @author JuRan
* @date 21/2/2025 上午 11:02
* @description: 华为手机
*/
public class HuaWeiPhone implements PhoneProduct{
@Override
public void start() {
System.out.println("华为Start");
}
@Override
public void call() {
System.out.println("华为call");
}
@Override
public void sendMessage() {
System.out.println("sendMessage");
}
}
package cn.aalo.factory.abstractFactory;
/**
* @author JuRan
* @date 21/2/2025 上午 11:02
* @description: 小米手机
*/
public class XiaoMiPhone implements PhoneProduct{
@Override
public void start() {
System.out.println("小米Start");
}
@Override
public void call() {
System.out.println("小米call");
}
@Override
public void sendMessage() {
System.out.println("sendMessage");
}
}
产品制造工厂抽象类
package cn.aalo.factory.abstractFactory;
/**
* @author JuRan
* @date 21/2/2025 上午 11:19
* @description: 创建产品类
*/
public interface CreateProduct {
BookProduct createBookProduct();
PhoneProduct createPhoneProject();
}
小米创建工厂
package cn.aalo.factory.abstractFactory;
/**
* @author JuRan
* @date 21/2/2025 上午 11:22
* @description: 小米创建产品工厂
*/
public class XiaoMiProductFactory implements CreateProduct{
@Override
public BookProduct createBookProduct() {
return new XiaoMiBook();
}
@Override
public PhoneProduct createPhoneProject() {
return new XiaoMiPhone();
}
}
华为创建产品工厂
package cn.aalo.factory.abstractFactory;
/**
* @author JuRan
* @date 21/2/2025 上午 11:22
* @description: 华为创建产品工厂
*/
public class HuaWeiProductFactory implements CreateProduct{
@Override
public BookProduct createBookProduct() {
return new HuaWeiBook();
}
@Override
public PhoneProduct createPhoneProject() {
return new HuaWeiPhone();
}
}
消费者
package cn.aalo.factory.abstractFactory;
/**
* @author JuRan
* @date 21/2/2025 上午 11:24
* @description: 消费者
*/
public class Consumer {
public static void main(String[] args){
//小米Factory
XiaoMiProductFactory xiaoMiProductFactory = new XiaoMiProductFactory();
xiaoMiProductFactory.createBookProduct().start();
xiaoMiProductFactory.createPhoneProject().start();
//HuaWeiFactory
HuaWeiProductFactory HuaWeiProductFactory = new HuaWeiProductFactory();
HuaWeiProductFactory.createBookProduct().start();
HuaWeiProductFactory.createPhoneProject().start();
}
}
优点:
保证一组产品的创建逻辑统一,防止产品之间的不兼容问题, 遵循 开放封闭原则(OCP),新增产品族时不需要修改已有代码。
缺点:
每增加一个产品族,就需要修改抽象工厂和所有具体工厂,扩展不够灵活、 工厂类变多,代码复杂度较高。
4、总结
模式 | 特点 | 适用场景 | 优点 | 缺点 |
---|---|---|---|---|
简单工厂模式 | 通过一个工厂类创建不同的产品 | 适用于产品较少的情况 | 简单易用,减少代码重复 | 违反 OCP,不利于扩展 |
工厂方法模式 | 让子类决定具体产品的实例化 | 适用于产品较多且经常扩展 | 符合 OCP,扩展性好 | 增加了类的数量 |
抽象工厂模式 | 创建一组相关的产品 | 适用于多个产品族 | 维护产品族的统一性 | 代码复杂,扩展新产品族麻烦 |
工厂模式是面向对象编程中常见的设计模式,选择适合的模式可以提高代码的可维护性和可扩展性。