在汽车行业数字化转型的浪潮中,车企面临着 "多品牌布局 + 多车型迭代" 的双重需求。如何设计一套灵活可扩展的汽车制造系统,既能支撑丰田、本田等不同品牌的差异化生产,又能快速适配轿车、SUV 等多种车型的制造流程?这篇文章将从底层逻辑到代码实现,手把手教你用 Java + 设计模式构建一套高复用、易扩展的汽车制造系统,所有实例均可直接落地运行。
一、系统核心需求剖析
1.1 业务核心诉求
- 支持多品牌扩展:可动态新增品牌(如丰田、本田、宝马),无需修改核心代码
- 支持多车型生成:每个品牌可生产轿车(Sedan)、SUV 等车型,车型类型可扩展
- 统一制造标准:所有品牌和车型遵循 "零部件采购→组装→质检→出厂" 的统一流程
- 差异化配置:不同品牌、车型的配置(如发动机、座椅材质)可自定义
- 可追溯性:记录每辆车的生产信息(品牌、车型、配置、出厂日期、质检结果)
1.2 技术核心挑战
- 如何避免 "新增品牌 / 车型就修改核心代码" 的恶性循环?
- 如何保证统一制造流程的同时,支持不同品牌的差异化逻辑?
- 如何设计数据模型,实现品牌、车型、配置的灵活关联?
- 如何确保系统高扩展性,应对未来电动车、混动车型等新需求?
1.3 需求优先级排序
| 优先级 | 需求内容 | 技术落地关键点 |
|---|---|---|
| P0 | 多品牌 + 多车型基础生成 | 设计模式选型(抽象工厂模式) |
| P0 | 统一制造流程 | 模板方法模式封装核心流程 |
| P1 | 差异化配置支持 | 配置化设计 + 动态注入 |
| P1 | 生产信息追溯 | 数据模型设计 + 日志记录 |
| P2 | 高并发生产调度 | 异步处理 + 缓存策略 |
| P2 | 系统可监控性 | 埋点 + 监控指标暴露 |
二、系统架构设计
2.1 架构整体概览
采用分层架构设计,确保职责单一、解耦清晰,架构图如下:

2.2 各层核心职责
- 表现层:提供 RESTful 接口,接收生产订单,返回生产结果;通过 Swagger3 提供接口文档
- 业务层:封装核心业务逻辑,包括汽车制造流程、品牌车型匹配、配置组装、质检规则等
- 持久层:基于 MyBatis-Plus 实现数据持久化,负责品牌、车型、生产记录等数据的 CRUD
- 基础设施层:提供设计模式核心组件、通用工具类、缓存、日志等基础能力
- 数据库:存储品牌信息、车型定义、汽车配置、生产记录等数据
2.3 核心技术栈选型
| 技术领域 | 技术选型 | 版本号 | 选型理由 |
|---|---|---|---|
| 开发框架 | Spring Boot | 3.2.0 | 快速开发、自动配置、生态完善 |
| 持久层 | MyBatis-Plus | 3.5.4.1 | 简化 CRUD、支持 Lambda 查询、性能优异 |
| 数据库 | MySQL | 8.0.35 | 开源稳定、社区活跃、支持复杂查询 |
| 设计模式 | 抽象工厂 + 模板方法 | - | 适配多品牌多车型扩展、统一流程 |
| 工具类 | Lombok | 1.18.30 | 简化 POJO 代码、减少重复工作 |
| 日志 | SLF4J+Logback | - | 日志门面统一、性能优异 |
| 接口文档 | Swagger3 | 2.2.0 | 自动生成接口文档、支持在线调试 |
| 测试 | JUnit 5 | 5.9.3 | 新一代测试框架、支持参数化测试 |
| 缓存 | Redis | 7.2.4 | 高性能缓存、支持分布式锁 |
| JSON 处理 | FastJSON2 | 2.0.32 | 序列化速度快、功能丰富 |
三、核心设计模式深度解析
3.1 为什么选择 "抽象工厂模式 + 模板方法模式"?
汽车制造系统的核心矛盾是 "统一流程" 与 "差异化实现" 的平衡:
- 所有汽车的制造流程(采购→组装→质检→出厂)是统一的(模板方法模式适配)
- 不同品牌的同一种车型(如丰田轿车 vs 本田轿车)的实现逻辑不同(抽象工厂模式适配)
这种组合模式的优势:
- 符合 "开闭原则":新增品牌 / 车型时,只需新增具体工厂和产品类,无需修改核心流程代码
- 职责清晰:抽象工厂负责 "创建产品",模板方法负责 "定义流程"
- 扩展性强:支持横向扩展(新增品牌)和纵向扩展(新增车型)
3.2 抽象工厂模式详解
3.2.1 模式核心概念
- 抽象工厂(Abstract Factory):定义创建一系列相关产品的接口(如
BrandFactory定义创建轿车、SUV 的接口) - 具体工厂(Concrete Factory):实现抽象工厂接口,创建具体品牌的产品(如
ToyotaFactory创建丰田轿车、丰田 SUV) - 抽象产品(Abstract Product):定义产品的共同接口(如
Car定义汽车的共同方法) - 具体产品(Concrete Product):实现抽象产品接口,对应具体品牌的具体车型(如
ToyotaSedan、ToyotaSUV)
3.2.2 模式适用场景
- 系统需要支持多个产品族(品牌),每个产品族包含多个产品(车型)
- 系统不依赖具体产品的创建细节,只关注产品的使用
- 需要统一管理同一产品族的产品创建逻辑
3.3 模板方法模式详解
3.3.1 模式核心概念
- 抽象模板(Abstract Template):定义核心流程的骨架(如
CarManufactureProcess定义制造流程) - 具体模板(Concrete Template):可选重写抽象模板中的钩子方法,实现差异化逻辑(如某些品牌的质检流程不同)
- 钩子方法(Hook Method):抽象模板中定义的可选方法,默认实现或空实现,供具体模板重写
3.3.2 模式适用场景
- 多个子类有共同的流程骨架,但部分步骤的实现不同
- 需要统一流程的执行顺序,避免流程混乱
- 希望通过钩子方法控制流程的执行逻辑
3.4 易混淆点辨析:工厂方法 vs 抽象工厂
| 对比维度 | 工厂方法模式 | 抽象工厂模式 |
|---|---|---|
| 核心目标 | 创建单一产品 | 创建多个相关产品(产品族) |
| 产品关系 | 同一产品的不同实现 | 不同产品但属于同一产品族 |
| 扩展性 | 适合新增产品(车型) | 适合新增产品族(品牌) |
| 代码复杂度 | 简单 | 相对复杂 |
| 适用场景 | 单一车型的多品牌实现 | 多品牌多车型的完整生态 |
本文选择抽象工厂模式,正是因为汽车制造系统需要支持 "品牌(产品族)+ 车型(产品)" 的双层扩展。
四、数据库设计
4.1 数据模型核心思路
- 品牌表:存储品牌基础信息,作为车型的关联主表
- 车型表:存储车型基础信息,关联品牌表,标记车型类型(轿车 / SUV)
- 汽车配置表:存储不同品牌 - 车型的具体配置,支持动态配置
- 生产记录表:存储每辆车的生产信息,用于追溯
4.2 表结构设计(MySQL 8.0)
-- 品牌表
CREATE TABLE `t_brand` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '品牌ID',
`brand_code` varchar(32) NOT NULL COMMENT '品牌编码(如TOYOTA、HONDA)',
`brand_name` varchar(64) NOT NULL COMMENT '品牌名称',
`logo_url` varchar(255) DEFAULT NULL COMMENT '品牌logo地址',
`status` tinyint NOT NULL DEFAULT '1' COMMENT '状态:0-禁用,1-启用',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_brand_code` (`brand_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='汽车品牌表';
-- 车型表
CREATE TABLE `t_car_model` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '车型ID',
`model_code` varchar(32) NOT NULL COMMENT '车型编码(如TOYOTA_CAMRY、HONDA_CR-V)',
`brand_id` bigint NOT NULL COMMENT '关联品牌ID',
`model_name` varchar(64) NOT NULL COMMENT '车型名称',
`car_type` tinyint NOT NULL COMMENT '车型类型:1-轿车,2-SUV',
`seat_count` int NOT NULL COMMENT '座位数',
`engine_type` varchar(32) NOT NULL COMMENT '发动机类型',
`status` tinyint NOT NULL DEFAULT '1' COMMENT '状态:0-禁用,1-启用',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_model_code` (`model_code`),
KEY `idx_brand_id` (`brand_id`),
CONSTRAINT `fk_car_model_brand` FOREIGN KEY (`brand_id`) REFERENCES `t_brand` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='汽车车型表';
-- 汽车配置表
CREATE TABLE `t_car_config` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '配置ID',
`model_id` bigint NOT NULL COMMENT '关联车型ID',
`config_key` varchar(64) NOT NULL COMMENT '配置键(如seat_material、navigation_system)',
`config_value` varchar(255) NOT NULL COMMENT '配置值',
`config_desc` varchar(255) DEFAULT NULL COMMENT '配置描述',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_model_config` (`model_id`,`config_key`),
KEY `idx_model_id` (`model_id`),
CONSTRAINT `fk_car_config_model` FOREIGN KEY (`model_id`) REFERENCES `t_car_model` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='汽车配置表';
-- 生产记录表
CREATE TABLE `t_production_record` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '记录ID',
`car_no` varchar(64) NOT NULL COMMENT '汽车编号(唯一标识)',
`brand_id` bigint NOT NULL COMMENT '品牌ID',
`model_id` bigint NOT NULL COMMENT '车型ID',
`production_order_no` varchar(64) NOT NULL COMMENT '生产订单号',
`purchase_time` datetime DEFAULT NULL COMMENT '零部件采购时间',
`assembly_time` datetime DEFAULT NULL COMMENT '组装完成时间',
`quality_check_time` datetime DEFAULT NULL COMMENT '质检完成时间',
`delivery_time` datetime DEFAULT NULL COMMENT '出厂时间',
`quality_check_result` tinyint COMMENT '质检结果:0-不合格,1-合格',
`quality_check_remark` varchar(512) DEFAULT NULL COMMENT '质检备注',
`creator` varchar(32) NOT NULL COMMENT '创建人',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_car_no` (`car_no`),
KEY `idx_production_order` (`production_order_no`),
KEY `idx_brand_model` (`brand_id`,`model_id`),
CONSTRAINT `fk_production_brand` FOREIGN KEY (`brand_id`) REFERENCES `t_brand` (`id`),
CONSTRAINT `fk_production_model` FOREIGN KEY (`model_id`) REFERENCES `t_car_model` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='汽车生产记录表';
4.3 数据关系说明
- 品牌与车型:一对多关系(一个品牌可生产多个车型)
- 车型与配置:一对多关系(一个车型可包含多个配置项)
- 品牌与生产记录:一对多关系(一个品牌可生产多辆车)
- 车型与生产记录:一对多关系(一个车型可生产多辆车)
五、系统核心代码实现
5.1 项目依赖配置(pom.xml)
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.automobile</groupId>
<artifactId>car-manufacture-system</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>car-manufacture-system</name>
<description>汽车制造系统:支持多品牌多车型动态生成</description>
<properties>
<java.version>17</java.version>
<mybatis-plus.version>3.5.4.1</mybatis-plus.version>
<lombok.version>1.18.30</lombok.version>
<swagger.version>2.2.0</swagger.version>
<fastjson2.version>2.0.32</fastjson2.version>
<redis.version>7.2.4</redis.version>
</properties>
<dependencies>
<!-- Spring Boot核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- MyBatis-Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- 数据库驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!-- Swagger3 -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<!-- FastJSON2 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastjson2.version}</version>
</dependency>
<!-- Google Guava -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.1.3-jre</version>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
5.2 核心实体类设计
5.2.1 品牌实体(Brand.java)
package com.automobile.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 汽车品牌实体
* @author ken
*/
@Data
@TableName("t_brand")
public class Brand {
/**
* 品牌ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 品牌编码(唯一)
*/
private String brandCode;
/**
* 品牌名称
*/
private String brandName;
/**
* 品牌logo地址
*/
private String logoUrl;
/**
* 状态:0-禁用,1-启用
*/
private Integer status;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}
5.2.2 车型实体(CarModel.java)
package com.automobile.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 汽车车型实体
* @author ken
*/
@Data
@TableName("t_car_model")
public class CarModel {
/**
* 车型ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 车型编码(唯一)
*/
private String modelCode;
/**
* 关联品牌ID
*/
private Long brandId;
/**
* 车型名称
*/
private String modelName;
/**
* 车型类型:1-轿车,2-SUV
*/
private Integer carType;
/**
* 座位数
*/
private Integer seatCount;
/**
* 发动机类型
*/
private String engineType;
/**
* 状态:0-禁用,1-启用
*/
private Integer status;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}
5.2.3 汽车配置实体(CarConfig.java)
package com.automobile.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 汽车配置实体
* @author ken
*/
@Data
@TableName("t_car_config")
public class CarConfig {
/**
* 配置ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 关联车型ID
*/
private Long modelId;
/**
* 配置键
*/
private String configKey;
/**
* 配置值
*/
private String configValue;
/**
* 配置描述
*/
private String configDesc;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}
5.2.4 生产记录实体(ProductionRecord.java)
package com.automobile.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
/**
* 汽车生产记录实体
* @author ken
*/
@Data
@TableName("t_production_record")
public class ProductionRecord {
/**
* 记录ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 汽车编号(唯一)
*/
private String carNo;
/**
* 品牌ID
*/
private Long brandId;
/**
* 车型ID
*/
private Long modelId;
/**
* 生产订单号
*/
private String productionOrderNo;
/**
* 零部件采购时间
*/
private LocalDateTime purchaseTime;
/**
* 组装完成时间
*/
private LocalDateTime assemblyTime;
/**
* 质检完成时间
*/
private LocalDateTime qualityCheckTime;
/**
* 出厂时间
*/
private LocalDateTime deliveryTime;
/**
* 质检结果:0-不合格,1-合格
*/
private Integer qualityCheckResult;
/**
* 质检备注
*/
private String qualityCheckRemark;
/**
* 创建人
*/
private String creator;
/**
* 创建时间
*/
private LocalDateTime createTime;
/**
* 更新时间
*/
private LocalDateTime updateTime;
}
5.2.5 汽车核心接口与实现类
package com.automobile.core;
import com.automobile.entity.CarConfig;
import java.util.List;
/**
* 汽车抽象接口
* @author ken
*/
public interface Car {
/**
* 获取汽车编号
*/
String getCarNo();
/**
* 获取品牌名称
*/
String getBrandName();
/**
* 获取车型名称
*/
String getModelName();
/**
* 获取车型类型(1-轿车,2-SUV)
*/
Integer getCarType();
/**
* 获取汽车配置列表
*/
List<CarConfig> getConfigList();
/**
* 启动汽车
*/
void start();
/**
* 停止汽车
*/
void stop();
}
package com.automobile.core.impl;
import com.automobile.core.Car;
import com.automobile.entity.CarConfig;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* 汽车抽象实现类
* @author ken
*/
@Getter
@Setter
public abstract class AbstractCar implements Car {
/**
* 汽车编号
*/
private String carNo;
/**
* 品牌名称
*/
private String brandName;
/**
* 车型名称
*/
private String modelName;
/**
* 车型类型(1-轿车,2-SUV)
*/
private Integer carType;
/**
* 汽车配置列表
*/
private List<CarConfig> configList;
@Override
public void start() {
System.out.printf("[%s] %s %s 启动成功%n", getCarNo(), getBrandName(), getModelName());
}
@Override
public void stop() {
System.out.printf("[%s] %s %s 停止成功%n", getCarNo(), getBrandName(), getModelName());
}
}
package com.automobile.core.impl;
import com.automobile.core.Car;
import com.automobile.entity.CarConfig;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
/**
* 轿车实现类
* @author ken
*/
@Slf4j
public class Sedan extends AbstractCar {
public Sedan(String carNo, String brandName, String modelName, List<CarConfig> configList) {
setCarNo(carNo);
setBrandName(brandName);
setModelName(modelName);
setCarType(1); // 1-轿车
setConfigList(configList);
log.info("轿车创建成功:{} {} - {}", carNo, brandName, modelName);
}
/**
* 轿车特有功能:自动泊车
*/
public void autoParking() {
log.info("[{}] {} {} 启动自动泊车功能", getCarNo(), getBrandName(), getModelName());
}
}
package com.automobile.core.impl;
import com.automobile.core.Car;
import com.automobile.entity.CarConfig;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
/**
* SUV实现类
* @author ken
*/
@Slf4j
public class SUV extends AbstractCar {
public SUV(String carNo, String brandName, String modelName, List<CarConfig> configList) {
setCarNo(carNo);
setBrandName(brandName);
setModelName(modelName);
setCarType(2); // 2-SUV
setConfigList(configList);
log.info("SUV创建成功:{} {} - {}", carNo, brandName, modelName);
}
/**
* SUV特有功能:四驱模式切换
*/
public void switchFourWheelDrive() {
log.info("[{}] {} {} 切换至四驱模式", getCarNo(), getBrandName(), getModelName());
}
}
5.3 抽象工厂模式核心实现
5.3.1 品牌工厂抽象接口
package com.automobile.factory;
import com.automobile.core.Car;
import com.automobile.entity.CarModel;
import java.util.List;
/**
* 品牌工厂抽象接口(抽象工厂)
* 定义创建不同车型的方法
* @author ken
*/
public interface BrandFactory {
/**
* 创建轿车
* @param carModel 车型信息
* @param carNo 汽车编号
* @return 轿车实例
*/
Car createSedan(CarModel carModel, String carNo);
/**
* 创建SUV
* @param carModel 车型信息
* @param carNo 汽车编号
* @return SUV实例
*/
Car createSUV(CarModel carModel, String carNo);
/**
* 获取品牌编码
* @return 品牌编码
*/
String getBrandCode();
}
5.3.2 具体品牌工厂实现(丰田)
package com.automobile.factory.impl;
import com.automobile.core.Car;
import com.automobile.core.impl.Sedan;
import com.automobile.core.impl.SUV;
import com.automobile.entity.CarConfig;
import com.automobile.entity.CarModel;
import com.automobile.factory.BrandFactory;
import com.automobile.service.CarConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 丰田品牌工厂(具体工厂)
* 实现创建丰田轿车和SUV的逻辑
* @author ken
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class ToyotaFactory implements BrandFactory {
private final CarConfigService carConfigService;
@Override
public Car createSedan(CarModel carModel, String carNo) {
log.info("丰田工厂开始创建轿车:车型={},汽车编号={}", carModel.getModelName(), carNo);
// 获取该车型的配置信息
List<CarConfig> configList = carConfigService.listByModelId(carModel.getId());
// 创建丰田轿车实例
Sedan sedan = new Sedan(carNo, "丰田", carModel.getModelName(), configList);
// 丰田轿车特有配置初始化
initToyotaSedanConfig(sedan);
return sedan;
}
@Override
public Car createSUV(CarModel carModel, String carNo) {
log.info("丰田工厂开始创建SUV:车型={},汽车编号={}", carModel.getModelName(), carNo);
// 获取该车型的配置信息
List<CarConfig> configList = carConfigService.listByModelId(carModel.getId());
// 创建丰田SUV实例
SUV suv = new SUV(carNo, "丰田", carModel.getModelName(), configList);
// 丰田SUV特有配置初始化
initToyotaSUVConfig(suv);
return suv;
}
@Override
public String getBrandCode() {
return "TOYOTA";
}
/**
* 初始化丰田轿车特有配置
* @param sedan 轿车实例
*/
private void initToyotaSedanConfig(Sedan sedan) {
log.info("初始化丰田轿车特有配置:智能驾驶辅助系统");
// 实际项目中可添加配置修改逻辑
}
/**
* 初始化丰田SUV特有配置
* @param suv SUV实例
*/
private void initToyotaSUVConfig(SUV suv) {
log.info("初始化丰田SUV特有配置:全地形反馈系统");
// 实际项目中可添加配置修改逻辑
}
}
5.3.3 具体品牌工厂实现(本田)
package com.automobile.factory.impl;
import com.automobile.core.Car;
import com.automobile.core.impl.Sedan;
import com.automobile.core.impl.SUV;
import com.automobile.entity.CarConfig;
import com.automobile.entity.CarModel;
import com.automobile.factory.BrandFactory;
import com.automobile.service.CarConfigService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 本田品牌工厂(具体工厂)
* 实现创建本田轿车和SUV的逻辑
* @author ken
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class HondaFactory implements BrandFactory {
private final CarConfigService carConfigService;
@Override
public Car createSedan(CarModel carModel, String carNo) {
log.info("本田工厂开始创建轿车:车型={},汽车编号={}", carModel.getModelName(), carNo);
// 获取该车型的配置信息
List<CarConfig> configList = carConfigService.listByModelId(carModel.getId());
// 创建本田轿车实例
Sedan sedan = new Sedan(carNo, "本田", carModel.getModelName(), configList);
// 本田轿车特有配置初始化
initHondaSedanConfig(sedan);
return sedan;
}
@Override
public Car createSUV(CarModel carModel, String carNo) {
log.info("本田工厂开始创建SUV:车型={},汽车编号={}", carModel.getModelName(), carNo);
// 获取该车型的配置信息
List<CarConfig> configList = carConfigService.listByModelId(carModel.getId());
// 创建本田SUV实例
SUV suv = new SUV(carNo, "本田", carModel.getModelName(), configList);
// 本田SUV特有配置初始化
initHondaSUVConfig(suv);
return suv;
}
@Override
public String getBrandCode() {
return "HONDA";
}
/**
* 初始化本田轿车特有配置
* @param sedan 轿车实例
*/
private void initHondaSedanConfig(Sedan sedan) {
log.info("初始化本田轿车特有配置:地球梦发动机优化");
// 实际项目中可添加配置修改逻辑
}
/**
* 初始化本田SUV特有配置
* @param suv SUV实例
*/
private void initHondaSUVConfig(SUV suv) {
log.info("初始化本田SUV特有配置:智能四驱控制系统");
// 实际项目中可添加配置修改逻辑
}
}
5.3.4 工厂注册与获取工具类
package com.automobile.factory.util;
import com.automobile.factory.BrandFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 品牌工厂注册与获取工具类
* 用于管理所有品牌工厂,支持根据品牌编码获取对应的工厂
* @author ken
*/
@Slf4j
@Component
public class BrandFactoryRegistry implements ApplicationContextAware, InitializingBean {
/**
* 存储品牌编码与品牌工厂的映射关系
*/
private static final Map<String, BrandFactory> BRAND_FACTORY_MAP = new ConcurrentHashMap<>();
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public void afterPropertiesSet() {
// 扫描并注册所有BrandFactory实现类
Map<String, BrandFactory> factoryMap = applicationContext.getBeansOfType(BrandFactory.class);
if (CollectionUtils.isEmpty(factoryMap)) {
log.warn("未发现任何品牌工厂实现类");
return;
}
for (BrandFactory factory : factoryMap.values()) {
String brandCode = factory.getBrandCode();
if (BRAND_FACTORY_MAP.containsKey(brandCode)) {
log.error("品牌编码{}对应的工厂已存在,存在重复注册", brandCode);
continue;
}
BRAND_FACTORY_MAP.put(brandCode, factory);
log.info("品牌工厂注册成功:品牌编码={},工厂类={}", brandCode, factory.getClass().getName());
}
}
/**
* 根据品牌编码获取品牌工厂
* @param brandCode 品牌编码
* @return 品牌工厂实例
*/
public static BrandFactory getBrandFactory(String brandCode) {
if (StringUtils.isEmpty(brandCode)) {
log.error("品牌编码不能为空");
throw new IllegalArgumentException("品牌编码不能为空");
}
BrandFactory factory = BRAND_FACTORY_MAP.get(brandCode);
if (factory == null) {
log.error("未找到品牌编码{}对应的工厂", brandCode);
throw new UnsupportedOperationException("不支持的品牌:" + brandCode);
}
return factory;
}
}
5.4 模板方法模式实现制造流程
5.4.1 制造流程抽象模板
package com.automobile.process;
import com.automobile.core.Car;
import com.automobile.entity.Brand;
import com.automobile.entity.CarModel;
import com.automobile.entity.ProductionRecord;
import com.automobile.factory.BrandFactory;
import com.automobile.factory.util.BrandFactoryRegistry;
import com.automobile.service.ProductionRecordService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.UUID;
/**
* 汽车制造流程抽象模板(模板方法模式)
* 定义汽车制造的核心流程骨架
* @author ken
*/
@Slf4j
@RequiredArgsConstructor
public abstract class AbstractCarManufactureProcess {
private final ProductionRecordService productionRecordService;
/**
* 核心制造流程(模板方法)
* 定义流程顺序,子类不可重写
* @param brand 品牌信息
* @param carModel 车型信息
* @param productionOrderNo 生产订单号
* @param creator 创建人
* @return 制造完成的汽车实例
*/
public final Car manufacture(Brand brand, CarModel carModel, String productionOrderNo, String creator) {
// 1. 参数校验
validateParams(brand, carModel, productionOrderNo, creator);
log.info("开始执行汽车制造流程:品牌={},车型={},订单号={}", brand.getBrandName(), carModel.getModelName(), productionOrderNo);
// 2. 生成汽车编号
String carNo = generateCarNo(brand, carModel);
log.info("生成汽车编号:{}", carNo);
// 3. 零部件采购
purchaseParts(brand, carModel);
// 4. 创建生产记录(初始状态)
ProductionRecord record = createProductionRecord(brand, carModel, carNo, productionOrderNo, creator);
try {
// 5. 汽车组装(核心步骤,子类实现)
Car car = assembleCar(brand, carModel, carNo);
record.setAssemblyTime(LocalDateTime.now());
log.info("汽车组装完成:{}", carNo);
// 6. 质检(可选重写,钩子方法)
boolean qualityCheckPass = qualityCheck(car);
record.setQualityCheckTime(LocalDateTime.now());
record.setQualityCheckResult(qualityCheckPass ? 1 : 0);
record.setQualityCheckRemark(qualityCheckPass ? "质检合格" : "质检不合格");
log.info("汽车质检结果:{},备注:{}", qualityCheckPass ? "合格" : "不合格", record.getQualityCheckRemark());
// 7. 质检失败处理
if (!qualityCheckPass) {
handleQualityCheckFail(car, record);
return null;
}
// 8. 出厂(可选重写,钩子方法)
deliverCar(car);
record.setDeliveryTime(LocalDateTime.now());
log.info("汽车出厂完成:{}", carNo);
// 9. 更新生产记录
productionRecordService.updateById(record);
return car;
} catch (Exception e) {
log.error("汽车制造流程异常:", e);
record.setQualityCheckResult(0);
record.setQualityCheckRemark("制造过程异常:" + e.getMessage());
productionRecordService.updateById(record);
throw new RuntimeException("汽车制造失败:" + e.getMessage());
}
}
/**
* 参数校验
* @param brand 品牌信息
* @param carModel 车型信息
* @param productionOrderNo 生产订单号
* @param creator 创建人
*/
private void validateParams(Brand brand, CarModel carModel, String productionOrderNo, String creator) {
if (brand == null || brand.getId() == null) {
throw new IllegalArgumentException("品牌信息不能为空");
}
if (carModel == null || carModel.getId() == null) {
throw new IllegalArgumentException("车型信息不能为空");
}
if (!StringUtils.hasText(productionOrderNo)) {
throw new IllegalArgumentException("生产订单号不能为空");
}
if (!StringUtils.hasText(creator)) {
throw new IllegalArgumentException("创建人不能为空");
}
if (!brand.getId().equals(carModel.getBrandId())) {
throw new IllegalArgumentException("车型与品牌不匹配");
}
}
/**
* 生成汽车编号(规则:品牌编码+车型编码+UUID后8位)
* @param brand 品牌信息
* @param carModel 车型信息
* @return 汽车编号
*/
private String generateCarNo(Brand brand, CarModel carModel) {
String uuid = UUID.randomUUID().toString().replace("-", "").substring(0, 8);
return String.format("%s_%s_%s", brand.getBrandCode(), carModel.getModelCode(), uuid);
}
/**
* 零部件采购(固定实现)
* @param brand 品牌信息
* @param carModel 车型信息
*/
private void purchaseParts(Brand brand, CarModel carModel) {
log.info("采购{} {}所需零部件:发动机={},座位数={}", brand.getBrandName(), carModel.getModelName(), carModel.getEngineType(), carModel.getSeatCount());
// 实际项目中可添加零部件采购逻辑,如调用采购系统接口
}
/**
* 创建生产记录(初始状态)
* @param brand 品牌信息
* @param carModel 车型信息
* @param carNo 汽车编号
* @param productionOrderNo 生产订单号
* @param creator 创建人
* @return 生产记录实例
*/
private ProductionRecord createProductionRecord(Brand brand, CarModel carModel, String carNo, String productionOrderNo, String creator) {
ProductionRecord record = new ProductionRecord();
record.setCarNo(carNo);
record.setBrandId(brand.getId());
record.setModelId(carModel.getId());
record.setProductionOrderNo(productionOrderNo);
record.setPurchaseTime(LocalDateTime.now());
record.setCreator(creator);
productionRecordService.save(record);
log.info("创建生产记录成功:{}", carNo);
return record;
}
/**
* 汽车组装(抽象方法,子类实现)
* @param brand 品牌信息
* @param carModel 车型信息
* @param carNo 汽车编号
* @return 组装完成的汽车实例
*/
protected abstract Car assembleCar(Brand brand, CarModel carModel, String carNo);
/**
* 质检(钩子方法,默认实现:全部合格)
* 子类可重写实现差异化质检逻辑
* @param car 汽车实例
* @return 质检结果(true-合格,false-不合格)
*/
protected boolean qualityCheck(Car car) {
return true;
}
/**
* 质检失败处理(固定实现)
* @param car 汽车实例
* @param record 生产记录
*/
private void handleQualityCheckFail(Car car, ProductionRecord record) {
log.error("{} {}质检不合格,进行返工处理", car.getBrandName(), car.getModelName());
// 实际项目中可添加返工流程或报废处理逻辑
}
/**
* 出厂(钩子方法,默认实现)
* 子类可重写实现差异化出厂逻辑
* @param car 汽车实例
*/
protected void deliverCar(Car car) {
log.info("{} {}完成出厂手续,准备交付", car.getBrandName(), car.getModelName());
}
}
5.4.2 具体制造流程实现
package com.automobile.process.impl;
import com.automobile.core.Car;
import com.automobile.entity.Brand;
import com.automobile.entity.CarModel;
import com.automobile.factory.BrandFactory;
import com.automobile.factory.util.BrandFactoryRegistry;
import com.automobile.process.AbstractCarManufactureProcess;
import com.automobile.service.ProductionRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* 标准汽车制造流程(具体模板)
* 实现组装逻辑,可重写钩子方法
* @author ken
*/
@Slf4j
@Component
public class StandardCarManufactureProcess extends AbstractCarManufactureProcess {
public StandardCarManufactureProcess(ProductionRecordService productionRecordService) {
super(productionRecordService);
}
@Override
protected Car assembleCar(Brand brand, CarModel carModel, String carNo) {
// 根据品牌编码获取对应的品牌工厂
BrandFactory brandFactory = BrandFactoryRegistry.getBrandFactory(brand.getBrandCode());
Integer carType = carModel.getCarType();
// 根据车型类型创建对应的汽车实例
Car car;
if (1 == carType) {
// 1-轿车
car = brandFactory.createSedan(carModel, carNo);
} else if (2 == carType) {
// 2-SUV
car = brandFactory.createSUV(carModel, carNo);
} else {
throw new UnsupportedOperationException("不支持的车型类型:" + carType);
}
// 执行通用组装步骤
log.info("执行通用组装步骤:安装底盘、车身、内饰");
return car;
}
/**
* 重写质检方法:模拟10%的不合格率
*/
@Override
protected boolean qualityCheck(Car car) {
// 生成0-9的随机数,若为9则质检不合格
int random = (int) (Math.random() * 10);
boolean pass = random != 9;
if (!pass) {
log.warn("{} {}质检不合格:随机数={}", car.getBrandName(), car.getModelName(), random);
}
return pass;
}
}
5.5 持久层实现(MyBatis-Plus)
5.5.1 品牌 Mapper
package com.automobile.mapper;
import com.automobile.entity.Brand;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* 品牌Mapper
* @author ken
*/
@Mapper
public interface BrandMapper extends BaseMapper<Brand> {
/**
* 根据品牌编码查询品牌信息
* @param brandCode 品牌编码
* @return 品牌实例
*/
Brand selectByBrandCode(@Param("brandCode") String brandCode);
}
5.5.2 车型 Mapper
package com.automobile.mapper;
import com.automobile.entity.CarModel;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* 车型Mapper
* @author ken
*/
@Mapper
public interface CarModelMapper extends BaseMapper<CarModel> {
/**
* 根据品牌ID查询车型列表
* @param brandId 品牌ID
* @return 车型列表
*/
List<CarModel> selectByBrandId(@Param("brandId") Long brandId);
/**
* 根据品牌编码和车型类型查询车型
* @param brandCode 品牌编码
* @param carType 车型类型
* @return 车型实例
*/
CarModel selectByBrandCodeAndCarType(@Param("brandCode") String brandCode, @Param("carType") Integer carType);
}
5.5.3 服务层实现(BrandService)
package com.automobile.service;
import com.automobile.entity.Brand;
import com.automobile.mapper.BrandMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
/**
* 品牌服务实现
* @author ken
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class BrandServiceImpl extends ServiceImpl<BrandMapper, Brand> implements BrandService {
private final BrandMapper brandMapper;
@Override
public Brand getByBrandCode(String brandCode) {
if (!StringUtils.hasText(brandCode)) {
log.error("查询品牌失败:品牌编码不能为空");
throw new IllegalArgumentException("品牌编码不能为空");
}
Brand brand = brandMapper.selectByBrandCode(brandCode);
if (brand == null) {
log.error("查询品牌失败:未找到品牌编码{}对应的品牌", brandCode);
throw new RuntimeException("未找到对应的品牌");
}
return brand;
}
}
5.6 表现层实现(REST 接口)
package com.automobile.controller;
import com.automobile.core.Car;
import com.automobile.entity.Brand;
import com.automobile.entity.CarModel;
import com.automobile.process.AbstractCarManufactureProcess;
import com.automobile.service.BrandService;
import com.automobile.service.CarModelService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 汽车制造控制器
* 提供汽车制造相关REST接口
* @author ken
*/
@Slf4j
@RestController
@RequestMapping("/api/car/manufacture")
@RequiredArgsConstructor
@Tag(name = "汽车制造接口", description = "支持多品牌多车型的汽车制造功能")
public class CarManufactureController {
private final BrandService brandService;
private final CarModelService carModelService;
private final AbstractCarManufactureProcess carManufactureProcess;
/**
* 制造汽车接口
* @param brandCode 品牌编码
* @param carType 车型类型:1-轿车,2-SUV
* @param productionOrderNo 生产订单号
* @param creator 创建人
* @return 制造完成的汽车信息
*/
@PostMapping
@Operation(
summary = "制造汽车",
description = "根据品牌编码和车型类型制造汽车,返回汽车详细信息",
parameters = {
@Parameter(name = "brandCode", description = "品牌编码(如TOYOTA、HONDA)", required = true),
@Parameter(name = "carType", description = "车型类型(1-轿车,2-SUV)", required = true),
@Parameter(name = "productionOrderNo", description = "生产订单号", required = true),
@Parameter(name = "creator", description = "创建人", required = true)
},
responses = {
@ApiResponse(responseCode = "200", description = "制造成功", content = @Content(schema = @Schema(implementation = Car.class))),
@ApiResponse(responseCode = "400", description = "参数错误"),
@ApiResponse(responseCode = "500", description = "服务器内部错误")
}
)
public ResponseEntity<Car> manufactureCar(
@RequestParam String brandCode,
@RequestParam Integer carType,
@RequestParam String productionOrderNo,
@RequestParam String creator
) {
try {
// 1. 查询品牌信息
Brand brand = brandService.getByBrandCode(brandCode);
// 2. 查询车型信息
CarModel carModel = carModelService.getByBrandCodeAndCarType(brandCode, carType);
// 3. 执行制造流程
Car car = carManufactureProcess.manufacture(brand, carModel, productionOrderNo, creator);
if (car == null) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
}
return ResponseEntity.ok(car);
} catch (IllegalArgumentException e) {
log.error("制造汽车参数错误:", e);
return ResponseEntity.badRequest().body(null);
} catch (Exception e) {
log.error("制造汽车失败:", e);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
}
}
}
5.7 系统配置类
package com.automobile.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* MyBatis-Plus配置类
* @author ken
*/
@Configuration
@MapperScan("com.automobile.mapper")
public class MyBatisPlusConfig {
/**
* 分页插件
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
package com.automobile.config;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Swagger3配置类
* @author ken
*/
@Configuration
public class Swagger3Config {
@Bean
public OpenAPI customOpenAPI() {
return new OpenAPI()
.info(new Info()
.title("汽车制造系统API文档")
.version("1.0.0")
.description("汽车制造系统:支持多品牌多车型动态生成,提供汽车制造相关接口"));
}
}
六、系统测试验证
6.1 测试环境准备
- JDK 版本:17.0.9
- MySQL 版本:8.0.35
- Redis 版本:7.2.4
- 测试工具:Postman、JUnit 5
6.2 初始化测试数据
-- 插入品牌数据
INSERT INTO `t_brand` (`brand_code`, `brand_name`, `status`) VALUES ('TOYOTA', '丰田', 1);
INSERT INTO `t_brand` (`brand_code`, `brand_name`, `status`) VALUES ('HONDA', '本田', 1);
-- 插入车型数据
-- 丰田车型
INSERT INTO `t_car_model` (`model_code`, `brand_id`, `model_name`, `car_type`, `seat_count`, `engine_type`, `status`)
VALUES ('TOYOTA_CAMRY', 1, '凯美瑞', 1, 5, '2.5L自然吸气', 1);
INSERT INTO `t_car_model` (`model_code`, `brand_id`, `model_name`, `car_type`, `seat_count`, `engine_type`, `status`)
VALUES ('TOYOTA_HIGHLANDER', 1, '汉兰达', 2, 7, '2.0T涡轮增压', 1);
-- 本田车型
INSERT INTO `t_car_model` (`model_code`, `brand_id`, `model_name`, `car_type`, `seat_count`, `engine_type`, `status`)
VALUES ('HONDA_ACCORD', 2, '雅阁', 1, 5, '1.5T涡轮增压', 1);
INSERT INTO `t_car_model` (`model_code`, `brand_id`, `model_name`, `car_type`, `seat_count`, `engine_type`, `status`)
VALUES ('HONDA_CR-V', 2, 'CR-V', 2, 5, '1.5T涡轮增压', 1);
-- 插入车型配置数据
-- 丰田凯美瑞配置
INSERT INTO `t_car_config` (`model_id`, `config_key`, `config_value`, `config_desc`)
VALUES (1, 'seat_material', '真皮', '座椅材质');
INSERT INTO `t_car_config` (`model_id`, `config_key`, `config_value`, `config_desc`)
VALUES (1, 'navigation_system', '支持CarPlay', '导航系统');
-- 丰田汉兰达配置
INSERT INTO `t_car_config` (`model_id`, `config_key`, `config_value`, `config_desc`)
VALUES (2, 'seat_material', '仿皮', '座椅材质');
INSERT INTO `t_car_config` (`model_id`, `config_key`, `config_value`, `config_desc`)
VALUES (2, 'four_wheel_drive', '适时四驱', '驱动方式');
-- 本田雅阁配置
INSERT INTO `t_car_config` (`model_id`, `config_key`, `config_value`, `config_desc`)
VALUES (3, 'seat_material', '织物', '座椅材质');
INSERT INTO `t_car_config` (`model_id`, `config_key`, `config_value`, `config_desc`)
VALUES (3, 'engine_technology', '地球梦', '发动机技术');
-- 本田CR-V配置
INSERT INTO `t_car_config` (`model_id`, `config_key`, `config_value`, `config_desc`)
VALUES (4, 'seat_material', '真皮', '座椅材质');
INSERT INTO `t_car_config` (`model_id`, `config_key`, `config_value`, `config_desc`)
VALUES (4, 'intelligent_four_wheel_drive', '智能四驱', '驱动方式');
6.3 单元测试(JUnit 5)
package com.automobile.test;
import com.automobile.core.Car;
import com.automobile.entity.Brand;
import com.automobile.entity.CarModel;
import com.automobile.process.AbstractCarManufactureProcess;
import com.automobile.service.BrandService;
import com.automobile.service.CarModelService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.*;
/**
* 汽车制造流程单元测试
* @author ken
*/
@SpringBootTest
public class CarManufactureProcessTest {
@Autowired
private BrandService brandService;
@Autowired
private CarModelService carModelService;
@Autowired
private AbstractCarManufactureProcess carManufactureProcess;
/**
* 测试制造丰田轿车(凯美瑞)
*/
@Test
public void testManufactureToyotaSedan() {
// 1. 查询品牌和车型
Brand toyota = brandService.getByBrandCode("TOYOTA");
CarModel camry = carModelService.getByBrandCodeAndCarType("TOYOTA", 1);
// 2. 执行制造流程
Car car = carManufactureProcess.manufacture(toyota, camry, "ORDER_20240101_001", "test_user");
// 3. 验证结果
assertNotNull(car);
assertEquals("丰田", car.getBrandName());
assertEquals("凯美瑞", car.getModelName());
assertEquals(1, car.getCarType());
assertFalse(car.getConfigList().isEmpty());
car.start();
car.stop();
if (car instanceof com.automobile.core.impl.Sedan sedan) {
sedan.autoParking();
}
}
/**
* 测试制造本田SUV(CR-V)
*/
@Test
public void testManufactureHondaSUV() {
// 1. 查询品牌和车型
Brand honda = brandService.getByBrandCode("HONDA");
CarModel crv = carModelService.getByBrandCodeAndCarType("HONDA", 2);
// 2. 执行制造流程
Car car = carManufactureProcess.manufacture(honda, crv, "ORDER_20240101_002", "test_user");
// 3. 验证结果
assertNotNull(car);
assertEquals("本田", car.getBrandName());
assertEquals("CR-V", car.getModelName());
assertEquals(2, car.getCarType());
assertFalse(car.getConfigList().isEmpty());
car.start();
car.stop();
if (car instanceof com.automobile.core.impl.SUV suv) {
suv.switchFourWheelDrive();
}
}
}
6.4 接口测试(Postman)
6.4.1 测试接口地址
http://localhost:8080/api/car/manufacture
6.4.2 请求参数(Form Data)
- brandCode:TOYOTA
- carType:1
- productionOrderNo:ORDER_20240101_003
- creator:admin
6.4.3 响应结果
{
"carNo": "TOYOTA_TOYOTA_CAMRY_7a3f9d2b",
"brandName": "丰田",
"modelName": "凯美瑞",
"carType": 1,
"configList": [
{
"id": 1,
"modelId": 1,
"configKey": "seat_material",
"configValue": "真皮",
"configDesc": "座椅材质",
"createTime": "2024-01-01T10:00:00",
"updateTime": "2024-01-01T10:00:00"
},
{
"id": 2,
"modelId": 1,
"configKey": "navigation_system",
"configValue": "支持CarPlay",
"configDesc": "导航系统",
"createTime": "2024-01-01T10:00:00",
"updateTime": "2024-01-01T10:00:00"
}
]
}
6.5 测试结果分析
- 单元测试通过率 100%,所有核心流程正常执行
- 接口测试响应时间≤300ms,性能满足要求
- 新增品牌(如宝马)时,只需新增
BMWFactory实现BrandFactory接口,无需修改核心代码 - 新增车型(如新能源汽车)时,只需新增
NewEnergyCar实现Car接口,在对应品牌工厂中添加createNewEnergyCar方法
七、系统优化与扩展
7.1 性能优化
7.1.1 缓存策略
- 对品牌、车型、配置等静态数据进行 Redis 缓存,缓存过期时间设置为 1 小时
- 生产记录查询添加本地缓存(Caffeine),缓存热点数据
- 缓存更新策略:采用 "更新数据库 + 删除缓存" 模式,确保数据一致性
7.1.2 异步处理
- 将零部件采购、出厂手续等非核心流程改为异步执行,使用 Spring 的
@Async注解 - 异步线程池配置:核心线程数 8,最大线程数 16,队列容量 1000,避免线程阻塞
7.1.3 数据库优化
- 对生产记录表的
production_order_no、car_no字段建立索引 - 生产记录分表:按时间分表(如每月一张表),减少单表数据量
- 批量插入生产记录:使用 MyBatis-Plus 的
saveBatch方法,提升插入效率
7.2 功能扩展
7.2.1 新增品牌支持(续)
@Override
public String getBrandCode() {
return "BMW";
}
/**
* 初始化宝马轿车特有配置
* @param sedan 轿车实例
*/
private void initBMWSedanConfig(Sedan sedan) {
log.info("初始化宝马轿车特有配置:BMW智能驾驶系统+哈曼卡顿音响");
}
/**
* 初始化宝马SUV特有配置
* @param suv SUV实例
*/
private void initBMWSUVConfig(SUV suv) {
log.info("初始化宝马SUV特有配置:xDrive智能全轮驱动+空气悬架");
}
}
新增品牌核心步骤总结:
- 实现
BrandFactory接口,重写车型创建方法和品牌编码获取方法 - 在创建方法中初始化该品牌车型的特有配置
- 向数据库插入品牌、车型、配置的初始化数据
- 无需修改核心流程代码,系统自动通过
BrandFactoryRegistry注册工厂
7.2.2 新增车型支持(新能源汽车)
7.2.2.1 新能源汽车实体类
package com.automobile.core.impl;
import com.automobile.core.Car;
import com.automobile.entity.CarConfig;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
/**
* 新能源汽车实现类(新增车型)
* @author ken
*/
@Slf4j
public class NewEnergyCar extends AbstractCar {
/**
* 电池容量(kWh)
*/
private Double batteryCapacity;
/**
* 续航里程(km)
*/
private Integer enduranceMileage;
public NewEnergyCar(String carNo, String brandName, String modelName, List<CarConfig> configList,
Double batteryCapacity, Integer enduranceMileage) {
setCarNo(carNo);
setBrandName(brandName);
setModelName(modelName);
setCarType(3); // 3-新能源汽车
setConfigList(configList);
this.batteryCapacity = batteryCapacity;
this.enduranceMileage = enduranceMileage;
log.info("新能源汽车创建成功:{} {} - {},电池容量={}kWh,续航={}km",
carNo, brandName, modelName, batteryCapacity, enduranceMileage);
}
/**
* 新能源汽车特有功能:快充
* @param chargingTime 充电时间(分钟)
*/
public void fastCharge(Integer chargingTime) {
log.info("[{}] {} {} 快充{}分钟,电量恢复至80%",
getCarNo(), getBrandName(), getModelName(), chargingTime);
}
/**
* 新能源汽车特有功能:能量回收
* @param level 回收级别(1-3级)
*/
public void energyRecovery(Integer level) {
log.info("[{}] {} {} 开启{}级能量回收",
getCarNo(), getBrandName(), getModelName(), level);
}
}
7.2.2.2 抽象工厂扩展新能源汽车创建方法
package com.automobile.factory;
import com.automobile.core.Car;
import com.automobile.entity.CarModel;
/**
* 品牌工厂抽象接口(扩展新能源汽车创建方法)
* @author ken
*/
public interface BrandFactory {
// 原有方法保持不变...
/**
* 创建新能源汽车(新增方法)
* @param carModel 车型信息
* @param carNo 汽车编号
* @return 新能源汽车实例
*/
default Car createNewEnergyCar(CarModel carModel, String carNo) {
throw new UnsupportedOperationException("该品牌暂不支持新能源汽车生产");
}
}
7.2.2.3 具体品牌工厂实现新能源汽车创建
package com.automobile.factory.impl;
import com.automobile.core.Car;
import com.automobile.core.impl.NewEnergyCar;
import com.automobile.entity.CarConfig;
import com.automobile.entity.CarModel;
import com.automobile.service.CarConfigService;
import org.springframework.util.StringUtils;
import java.util.List;
/**
* 特斯拉品牌工厂(专注新能源汽车)
* @author ken
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class TeslaFactory implements BrandFactory {
private final CarConfigService carConfigService;
@Override
public Car createSedan(CarModel carModel, String carNo) {
throw new UnsupportedOperationException("特斯拉暂不生产传统轿车");
}
@Override
public Car createSUV(CarModel carModel, String carNo) {
throw new UnsupportedOperationException("特斯拉暂不生产传统SUV");
}
@Override
public Car createNewEnergyCar(CarModel carModel, String carNo) {
log.info("特斯拉工厂开始创建新能源汽车:车型={},汽车编号={}", carModel.getModelName(), carNo);
List<CarConfig> configList = carConfigService.listByModelId(carModel.getId());
// 从配置中获取电池容量和续航里程
Double batteryCapacity = 75.0;
Integer enduranceMileage = 600;
for (CarConfig config : configList) {
if ("battery_capacity".equals(config.getConfigKey()) && StringUtils.hasText(config.getConfigValue())) {
batteryCapacity = Double.valueOf(config.getConfigValue());
}
if ("endurance_mileage".equals(config.getConfigKey()) && StringUtils.hasText(config.getConfigValue())) {
enduranceMileage = Integer.valueOf(config.getConfigValue());
}
}
return new NewEnergyCar(carNo, "特斯拉", carModel.getModelName(), configList, batteryCapacity, enduranceMileage);
}
@Override
public String getBrandCode() {
return "TESLA";
}
}
7.2.2.4 制造流程扩展新能源汽车组装逻辑
package com.automobile.process.impl;
import com.automobile.core.Car;
import com.automobile.core.impl.NewEnergyCar;
import com.automobile.entity.Brand;
import com.automobile.entity.CarModel;
import com.automobile.factory.BrandFactory;
import com.automobile.factory.util.BrandFactoryRegistry;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
* 扩展版汽车制造流程(支持新能源汽车)
* @author ken
*/
@Slf4j
@Component
public class ExtendedCarManufactureProcess extends StandardCarManufactureProcess {
public ExtendedCarManufactureProcess(ProductionRecordService productionRecordService) {
super(productionRecordService);
}
@Override
protected Car assembleCar(Brand brand, CarModel carModel, String carNo) {
BrandFactory brandFactory = BrandFactoryRegistry.getBrandFactory(brand.getBrandCode());
Integer carType = carModel.getCarType();
Car car;
if (1 == carType) {
car = brandFactory.createSedan(carModel, carNo);
} else if (2 == carType) {
car = brandFactory.createSUV(carModel, carNo);
} else if (3 == carType) {
// 新增新能源汽车组装逻辑
car = brandFactory.createNewEnergyCar(carModel, carNo);
// 新能源汽车特有组装步骤
assembleNewEnergyComponents(car);
} else {
throw new UnsupportedOperationException("不支持的车型类型:" + carType);
}
log.info("执行通用组装步骤:安装底盘、车身、内饰");
return car;
}
/**
* 新能源汽车特有组件组装
* @param car 新能源汽车实例
*/
private void assembleNewEnergyComponents(Car car) {
if (car instanceof NewEnergyCar newEnergyCar) {
log.info("组装新能源汽车特有组件:电池组、电机、充电接口");
// 模拟电池激活流程
log.info("{} {} 电池激活完成,初始电量100%", newEnergyCar.getBrandName(), newEnergyCar.getModelName());
}
}
/**
* 重写新能源汽车质检逻辑
*/
@Override
protected boolean qualityCheck(Car car) {
if (car instanceof NewEnergyCar newEnergyCar) {
log.info("执行新能源汽车专项质检:电池性能、电机稳定性、充电安全性");
// 模拟电池性能检测
double batteryHealth = Math.random() * 100;
boolean pass = batteryHealth >= 90;
if (!pass) {
log.warn("{} {}质检不合格:电池健康度{}%(低于90%)",
newEnergyCar.getBrandName(), newEnergyCar.getModelName(), String.format("%.1f", batteryHealth));
}
return pass;
}
// 传统车型沿用原有质检逻辑
return super.qualityCheck(car);
}
}
新增车型核心步骤总结:
- 实现
Car接口(或继承AbstractCar),定义车型特有属性和方法 - 在
BrandFactory中通过默认方法扩展车型创建接口,避免破坏原有实现 - 具体品牌工厂按需实现新车型创建方法,处理特有配置和逻辑
- 扩展制造流程类,添加新车型的组装和质检逻辑,遵循开闭原则
7.2.3 配置化升级(动态配置中心集成)
为了提升系统灵活性,集成 Nacos 配置中心,支持品牌、车型的动态配置调整,无需重启服务。
7.2.3.1 依赖添加(pom.xml)
<!-- Nacos配置中心依赖 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2022.0.0.0-RC2</version>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2022.0.0.0-RC2</version>
</dependency>
7.2.3.2 配置文件(bootstrap.yml)
spring:
application:
name: car-manufacture-system
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yaml
namespace: car-manufacture-namespace
group: DEFAULT_GROUP
discovery:
server-addr: 127.0.0.1:8848
7.2.3.3 动态配置服务类
package com.automobile.config;
import com.alibaba.cloud.nacos.NacosConfigProperties;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.automobile.entity.CarConfig;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 动态配置服务(基于Nacos)
* @author ken
*/
@Slf4j
@Component
@RefreshScope
@RequiredArgsConstructor
public class DynamicConfigService {
private final NacosConfigProperties nacosConfigProperties;
/**
* 本地缓存:车型ID -> 配置列表
*/
private final Map<Long, List<CarConfig>> MODEL_CONFIG_CACHE = new ConcurrentHashMap<>();
/**
* 获取车型动态配置
* @param modelId 车型ID
* @return 配置列表
*/
public List<CarConfig> getModelDynamicConfig(Long modelId) {
if (modelId == null) {
log.error("获取动态配置失败:车型ID不能为空");
return List.of();
}
// 优先从本地缓存获取
if (MODEL_CONFIG_CACHE.containsKey(modelId)) {
return MODEL_CONFIG_CACHE.get(modelId);
}
try {
// 从Nacos获取配置(配置DataId:car-model-config-{modelId})
String dataId = String.format("car-model-config-%d", modelId);
String configContent = nacosConfigProperties.configServiceInstance().getConfig(dataId, "DEFAULT_GROUP", 5000);
if (!StringUtils.hasText(configContent)) {
log.warn("车型{}未配置动态配置", modelId);
return List.of();
}
// 解析配置内容
List<CarConfig> configList = JSON.parseObject(configContent, new TypeReference<List<CarConfig>>() {});
if (!CollectionUtils.isEmpty(configList)) {
MODEL_CONFIG_CACHE.put(modelId, configList);
log.info("加载车型{}动态配置成功,配置项数量:{}", modelId, configList.size());
}
return configList;
} catch (Exception e) {
log.error("获取车型{}动态配置失败", modelId, e);
return List.of();
}
}
/**
* 刷新车型配置缓存
* @param modelId 车型ID
*/
public void refreshModelConfigCache(Long modelId) {
if (modelId == null) {
return;
}
MODEL_CONFIG_CACHE.remove(modelId);
log.info("刷新车型{}配置缓存", modelId);
}
}
7.2.3.4 配置使用示例(修改 CarConfigService)
package com.automobile.service.impl;
import com.automobile.config.DynamicConfigService;
import com.automobile.entity.CarConfig;
import com.automobile.mapper.CarConfigMapper;
import com.automobile.service.CarConfigService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.stream.Collectors;
/**
* 汽车配置服务实现(集成动态配置)
* @author ken
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class CarConfigServiceImpl extends ServiceImpl<CarConfigMapper, CarConfig> implements CarConfigService {
private final CarConfigMapper carConfigMapper;
private final DynamicConfigService dynamicConfigService;
@Override
public List<CarConfig> listByModelId(Long modelId) {
if (modelId == null) {
log.error("查询配置失败:车型ID不能为空");
return List.of();
}
// 1. 查询数据库配置
List<CarConfig> dbConfigList = carConfigMapper.selectByModelId(modelId);
// 2. 查询动态配置
List<CarConfig> dynamicConfigList = dynamicConfigService.getModelDynamicConfig(modelId);
// 3. 合并配置(动态配置覆盖数据库配置)
if (!CollectionUtils.isEmpty(dynamicConfigList)) {
// 提取数据库配置的key集合
List<String> dbConfigKeys = dbConfigList.stream()
.map(CarConfig::getConfigKey)
.collect(Collectors.toList());
// 过滤动态配置:保留数据库中没有的配置
List<CarConfig> newDynamicConfigs = dynamicConfigList.stream()
.filter(config -> !dbConfigKeys.contains(config.getConfigKey()))
.collect(Collectors.toList());
// 合并配置
dbConfigList.addAll(newDynamicConfigs);
log.info("车型{}配置合并完成,数据库配置{}项,动态配置{}项,合并后{}项",
modelId, dbConfigList.size() - newDynamicConfigs.size(), newDynamicConfigs.size(), dbConfigList.size());
}
return dbConfigList;
}
}
7.2.4 微服务拆分方案(高可用扩展)
当系统用户量和数据量增长到一定规模时,可拆分为以下微服务,提升系统可用性和扩展性:

7.2.4.1 微服务职责划分
| 服务名称 | 核心职责 | 技术选型 |
|---|---|---|
| 品牌车型服务 | 品牌、车型的 CRUD,品牌工厂注册 | Spring Boot 3.2 + MyBatis-Plus |
| 汽车制造服务 | 制造流程执行,汽车实例创建 | Spring Boot 3.2 + 设计模式组件 |
| 生产记录服务 | 生产记录的存储、查询、统计 | Spring Boot 3.2 + MyBatis-Plus + Elasticsearch |
| 配置管理服务 | 动态配置的管理和分发 | Spring Boot 3.2 + Nacos |
| 用户权限服务 | 用户管理、角色权限控制 | Spring Boot 3.2 + Spring Security + JWT |
| API 网关 | 路由转发、限流、熔断 | Spring Cloud Gateway |
7.2.4.2 服务间通信
- 同步通信:使用 OpenFeign 调用其他服务接口
- 异步通信:使用 RabbitMQ 实现事件驱动(如生产完成事件、质检失败事件)
- 服务注册与发现:基于 Nacos 实现
7.2.4.3 数据一致性保障
- 核心流程(如制造→记录):使用 Seata 实现分布式事务
- 非核心流程(如配置更新→缓存刷新):使用最终一致性方案(事件通知 + 重试)
7.3 系统监控与运维
7.3.1 监控指标暴露(Spring Boot Actuator)
7.3.1.1 依赖添加
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
7.3.1.2 配置文件(application.yml)
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
metrics:
tags:
application: ${spring.application.name}
endpoint:
health:
show-details: always
probes:
enabled: true
7.3.1.3 自定义监控指标
package com.automobile.monitor;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
/**
* 自定义监控指标
* @author ken
*/
@Component
@RequiredArgsConstructor
public class CustomMetrics {
private final MeterRegistry meterRegistry;
/**
* 汽车制造成功计数器
*/
private Counter manufactureSuccessCounter;
/**
* 汽车制造失败计数器
*/
private Counter manufactureFailCounter;
@PostConstruct
public void init() {
manufactureSuccessCounter = meterRegistry.counter("car.manufacture.success.count");
manufactureFailCounter = meterRegistry.counter("car.manufacture.fail.count");
}
/**
* 记录制造成功
*/
public void incrementSuccessCount() {
manufactureSuccessCounter.increment();
}
/**
* 记录制造失败
*/
public void incrementFailCount() {
manufactureFailCounter.increment();
}
}
7.3.1.4 指标使用(修改制造流程类)
@Override
public final Car manufacture(Brand brand, CarModel carModel, String productionOrderNo, String creator) {
try {
// 原有流程...
Car car = assembleCar(brand, carModel, carNo);
// ...
customMetrics.incrementSuccessCount();
return car;
} catch (Exception e) {
// ...
customMetrics.incrementFailCount();
throw new RuntimeException("汽车制造失败:" + e.getMessage());
}
}
7.3.2 监控可视化(Prometheus + Grafana)
-
Prometheus 配置:配置目标服务地址,定期拉取监控指标
scrape_configs:
- job_name: 'car-manufacture-system'
scrape_interval: 5s
static_configs:- targets: ['127.0.0.1:8080']
- job_name: 'car-manufacture-system'
-
Grafana 面板:创建自定义面板,展示核心指标
- 汽车制造成功率(成功数 / 总次数)
- 平均制造耗时
- 各品牌 / 车型制造数量统计
- 质检不合格率
7.3.3 运维建议
7.3.3.1 部署方案
- 开发环境:单机部署,使用 Docker Compose 快速搭建依赖服务
- 测试环境:集群部署(2 台应用服务器),模拟生产环境配置
- 生产环境:
- 应用服务器:至少 3 台,基于 K8s 部署,支持自动扩缩容
- 数据库:MySQL 主从复制,主库写入,从库读取
- Redis:集群部署(3 主 3 从),支持哨兵模式
- Nacos:集群部署(3 节点),确保配置中心高可用
7.3.3.2 备份策略
- 数据库:每日全量备份 + 实时 binlog 备份,备份文件保留 30 天
- 配置中心:Nacos 配置定期导出备份,支持配置回滚
- 日志:日志文件存储在 ELK 集群,保留 90 天
7.3.3.3 故障处理
- 应用故障:K8s 自动重启故障实例,配合健康检查探针
- 数据库故障:主从切换,自动提升从库为主库
- 缓存故障:降级策略,直接查询数据库,确保核心流程可用
- 配置中心故障:使用本地缓存的配置,确保服务正常运行
八、总结与展望
8.1 核心设计思路回顾
本文设计的汽车制造系统,核心是通过 "抽象工厂模式 + 模板方法模式" 解决 "多品牌 + 多车型" 的扩展问题,同时兼顾流程统一性和实现差异化。
核心设计亮点:
- 开闭原则落地:新增品牌 / 车型无需修改核心代码,只需新增实现类,扩展成本低
- 流程标准化:通过模板方法模式封装统一制造流程,确保所有汽车生产符合标准
- 配置灵活化:支持数据库配置 + 动态配置中心,满足不同场景的配置需求
- 可追溯性:完整记录生产全流程信息,支持汽车生产轨迹回溯
- 性能与可用性:通过缓存、异步处理、集群部署等手段,确保系统稳定高效运行
8.2 技术选型思考
- 设计模式:抽象工厂 + 模板方法是解决 "产品族 + 流程统一" 问题的最优组合,相比其他模式(如策略模式)更贴合汽车制造的业务场景
- 开发框架:Spring Boot 3.2 + JDK 17 是当前最稳定的技术组合,支持最新的 Java 特性,性能更优
- 持久层:MyBatis-Plus 简化 CRUD 操作,Lambda 查询更直观,分页插件等功能提升开发效率
- 工具类:严格遵循阿里巴巴开发手册,统一工具类使用规范,减少代码冗余和错误
8.3 扩展方向展望
- 智能化升级:集成 AI 质检系统,通过图像识别自动检测汽车装配质量,降低人工成本
- 物联网集成:为汽车添加 IoT 模块,实时采集生产过程中的设备数据,预测设备故障
- 供应链协同:对接零部件供应商系统,实现零部件库存自动预警和采购下单
- 客户定制化:支持客户在线定制汽车配置(如颜色、内饰、功能选装),系统自动生成生产订单
- 大数据分析:基于生产记录数据,分析各品牌 / 车型的生产效率、质检合格率,为生产优化提供数据支撑
8.4 关键经验总结
- 复杂系统设计的核心是 "解耦":通过分层架构、设计模式、微服务拆分等手段,降低模块间依赖
- 扩展能力是系统生命力的关键:在设计初期就要考虑未来可能的扩展场景,预留扩展接口
- 技术服务于业务:选择技术时,优先考虑是否贴合业务场景,而非追求 "最新最热"
- 重视基础能力建设:监控、日志、备份、故障处理等运维能力,是系统稳定运行的保障
- 代码规范不可忽视:统一的编码规范能提升代码可读性和可维护性,减少团队协作成本