层级:速记 01-styles / 深入 d01-styles / 本页=详解。每种风格:定义 -> 机制 -> 真实系统 -> Java 代码 -> 考试考法。
定义:整批输入一次性处理完,再输出给下一道工序。数据驱动的「整批」形态。
机制:工序 A 完全结束后工序 B 才开始,中间以完整数据文件衔接。
真实系统:银行日终结算(白天攒交易流水,夜间批量入账)、Hive 离线数仓、工资核算月度批处理。
Java 代码(典型批处理框架 Spring Batch 的结构):
// 读取流水 -> 处理 -> 写总账,整批执行
@Bean
public Step settleStep(JobRepository repo, PlatformTransactionManager tx) {
return new StepBuilder("settleStep", repo)
.<Transaction, LedgerEntry>chunk(1000, tx) // 每1000条一事务
.reader(flatFileReader("transactions_20260827.dat"))
.processor(this::toLedgerEntry) // 转记账分录
.writer(jdbcBatchWriter("ledger"))
.build();
}
考试考法:选择题给「夜间批量、整批处理、顺序执行」选批处理;与管道的区别在「增量 vs 整批」。
定义:流式增量处理,前级过滤器输出即后级输入,管道负责衔接。
机制:每个过滤器独立工作,不需要等整批数据;流到哪处理到哪。
真实系统:Unix 管道 ps aux | grep nginx | wc -l、编译器(词法→语法→语义→代码生成)、Flink 流计算。
Java 代码(JDK 自带的流式管道思想):
// 每一步只依赖上一步的输出,可自由组合
List<String> result = transactions.stream()
.filter(t -> t.getStatus() == FAILED) // 过滤器1:筛失败单
.map(t -> t.getOrderId()) // 过滤器2:取单号
.distinct() // 过滤器3:去重
.sorted() // 过滤器4:排序
.collect(toList());
考试考法:案例题描述「数据流逐步加工、各阶段可并行、前段输出后段输入」-> 管道-过滤器;优点考「支持复用与并行」、缺点考「不适合交互应用」。
定义:单线程自顶向下调用,最古老的结构化风格。
机制:主程序掌控流程,子程序被调用执行后返回控制权。
真实系统:传统 C 结构化程序、早期 MIS 系统、现在仍常见于脚本与简单工具。
Java 代码:
public class Settlement {
public static void main(String[] args) {
List<Trade> trades = loadTrades(); // 步骤1
List<Entry> entries = convert(trades); // 步骤2
writeLedger(entries); // 步骤3
report(entries.size()); // 步骤4
}
}
考试考法:作为「层次型的退化形态」出现在选择题;明确「单线程、无并发」特征。
定义:封装数据与操作为对象,通过消息(方法调用)协作。
机制:封装=隐藏内部状态;多态=同一消息不同响应;继承=复用定义。
真实系统:一切现代业务系统。
Java 代码(多态如何支撑架构演化——新增渠道不动核心):
public interface PaymentChannel {
PayResult pay(PayRequest req);
}
public class WechatChannel implements PaymentChannel { ... }
public class AlipayChannel implements PaymentChannel { ... }
// 新增「银联云闪付」时:只加类,不改核心调度——开闭原则
public class UnionPayChannel implements PaymentChannel { ... }
public class PayService {
private final Map<String, PaymentChannel> channels;
public PayResult pay(String channelCode, PayRequest req) {
return channels.get(channelCode).pay(req); // 多态分发
}
}
考试考法:与「面向对象分析与设计」结合考封装/多态的架构价值(隔离变化);「对象间松耦合靠接口抽象」是送分点。
定义:系统按职责分层,每层只依赖直接下层,服务单向向上。
机制:第 N 层调用第 N-1 层的接口;下层不知道上层存在。
真实系统:OSI 七层、TCP/IP、J2EE 经典三层(表示-业务-数据)、你写过的每一个 Controller-Service-Mapper。
Java 代码(Controller 不认识 Mapper,依赖被层间隔断):
@RestController // 表示层:只做协议转换
public class OrderController {
private final OrderService service; // 只依赖业务层接口
@PostMapping("/orders")
public Result<Long> create(@RequestBody OrderDto dto) {
return Result.ok(service.create(dto));
}
}
@Service // 业务层:事务边界在这里
public class OrderService {
private final OrderMapper mapper; // 只依赖数据层接口
@Transactional
public Long create(OrderDto dto) { ... }
}
@Mapper // 数据层:只有SQL与映射
public interface OrderMapper {
int insert(Order order);
}
考试考法:案例必考。优点「复用/移植/并行开发/关注点分离」、缺点「跨层调用破坏分层、多层中转性能损耗」。若案例问「严格分层 vs 松散分层」:严格=只能调相邻下层;松散=可跨层调用(性能好、纯度低)。
定义:独立进程间显式消息传递协作,无共享内存。
机制:点对点消息(请求-响应或单向通知),进程各自独立生命周期。
真实系统:微服务间 gRPC 调用、操作系统 IPC、 actor 模型(Akka)。
Java 代码:
// gRPC:跨进程显式调用,接口契约先行
public class PayGrpcService extends PayServiceGrpc.PayServiceImplBase {
@Override
public void pay(PayRequest req, StreamObserver<PayResult> obs) {
PayResult r = payService.handle(toDomain(req));
obs.onNext(r); obs.onCompleted();
}
}
考试考法:与「事件驱动」对比考:进程通信=显式定向(我知道发给谁);事件驱动=隐式广播(我不关心谁处理)。
定义:构件通过发布事件解耦,订阅者被事件触发,发布者不知道谁在听。
机制:发布-订阅;事件源发出通知,系统自动调用所有订阅者。
真实系统:GUI 点击事件、Spring ApplicationEvent、MQ 异步解耦、你做的支付回调通知。
Java 代码(Spring 事件,业务零侵入扩展):
// 1. 定义事件
public class OrderPaidEvent {
private final Long orderId;
private final BigDecimal amount;
}
// 2. 发布方:支付成功只管发布,不认识任何下游
@Service
public class PayService {
private final ApplicationEventPublisher publisher;
@Transactional
public void payOk(Long orderId, BigDecimal amount) {
ledger.record(orderId, amount);
publisher.publishEvent(new OrderPaidEvent(orderId, amount));
}
}
// 3. 订阅方1:积分(后加的功能,主流程零改动)
@EventListener
public void addPoints(OrderPaidEvent e) { pointsService.add(...); }
// 4. 订阅方2:短信通知
@TransactionalEventListener(phase = AFTER_COMMIT)
public void notify(OrderPaidEvent e) { sms.send(...); }
考试考法:案例高频「系统需要灵活扩展新功能、发布者与处理者解耦」-> 事件驱动;缺点考「控制流不直观、调试难」。
定义:解释执行自定义语言/指令集的虚拟机。
机制:解释引擎逐条读取指令 -> 查上下文 -> 执行动作。
真实系统:Python/JVM 字节码解释执行、SQL 引擎、Excel 公式引擎、工作流引擎的规则表达式。
Java 代码(手写迷你解释器核心:表达式求值):
// 表达式语法树:解释器逐节点求值
interface Expr { int eval(Map<String, Integer> env); }
record Num(int v) implements Expr {
public int eval(Map<String, Integer> env) { return v; }
}
record Var(String name) implements Expr {
public int eval(Map<String, Integer> env) { return env.get(name); }
}
record Add(Expr l, Expr r) implements Expr {
public int eval(Map<String, Integer> env) {
return l.eval(env) + r.eval(env);
}
}
// 解释执行:"金额 + 税额" -> 100 + 13
int total = new Add(new Var("amount"), new Var("tax"))
.eval(Map.of("amount", 100, "tax", 13)); // =113
考试考法:识别特征「自定义语言、规则灵活多变、无需编译」;解释器 vs 规则系统:前者是通用引擎,后者是知识+推理的特化。
定义:知识库 + 推理机的虚拟机特化,用规则而非代码表达业务逻辑。
机制:规则库(条件->动作)+ 工作内存(事实)+ 推理机(匹配-冲突消解-执行循环)。
真实系统:Drools 风控规则引擎、保险费率、营销满减、你 ERP 里的审批流条件路由。
Java 代码(Drools 规则文件,业务人员可维护):
// rules/discount.drl —— 改规则不用发版
rule "VIP用户大额订单95折"
when
$o : Order(amount > 5000, customer.vipLevel >= 5)
then
$o.setDiscount(0.95);
update($o);
end
rule "黑名单用户拦截"
when
Order(customer.blacklisted == true)
then
throw new OrderRejectException("风控拦截");
end
考试考法:「业务规则频繁变化、需要业务人员参与配置」-> 规则系统;与解释器归入虚拟机类(都是「用数据表达行为」)。
定义:中心数据被动存储,客户端主动访问读写。
机制:所有构件围绕共享数据集工作;数据结构稳定,操作围绕它增删改查。
真实系统:MIS/ERP/你写的一切 CRUD 系统。
Java 代码(ERP 各模块围绕「主数据」工作):
// 财务/库存/采购模块都围绕同一份物料主数据
@Service
public class InventoryModule {
public void deduct(Long itemId, int qty) {
Material m = repo.findForUpdate(itemId); // 中心数据
m.setQty(m.getQty() - qty);
}
}
考试考法:案例描述「多模块共享核心数据、数据结构稳定」-> 数据库风格;与黑板对比的判定点是「客户端主动 vs 知识源竞争写」。
定义:中心数据主动驱动,多个知识源监视黑板、竞相更新。
机制:知识源观察黑板状态,条件满足即出手修改;无中央控制器决定谁先谁后。
真实系统:语音识别(声学/语法/语义知识源竞相解读)、雷达信号处理、AI 推理平台。
Java 代码(示意:多知识源监听黑板):
class Blackboard {
private final Map<String, Object> state = new ConcurrentHashMap<>();
private final List<KnowledgeSource> sources = new ArrayList<>();
void update(String key, Object val) {
state.put(key, val);
sources.forEach(KnowledgeSource::inspect); // 每次变更触发知识源检查
}
}
interface KnowledgeSource {
boolean canContribute(Blackboard b); // 条件满足?
void contribute(Blackboard b); // 竞相贡献
}
考试考法:低频但好认:「没有确定性解法、多专家协作逐步逼近答案」-> 黑板。
| # | 风格 | 一句话识别 | 代表系统 |
|---|---|---|---|
| 1 | 批处理 | 整批顺序 | 银行日终 |
| 2 | 管道-过滤器 | 流式增量 | 编译器/Unix |
| 3 | 主程序-子程序 | 单线程自顶向下 | 传统结构化 |
| 4 | 面向对象 | 封装+多态 | 一切现代系统 |
| 5 | 层次型 | 单向依赖分层 | Controller-Service-Mapper |
| 5 | 进程通信 | 显式消息 | gRPC |
| 7 | 事件驱动 | 发布订阅 | Spring事件/MQ |
| 8 | 解释器 | 解释自定义语言 | JVM/公式引擎 |
| 9 | 规则系统 | 规则库+推理机 | Drools风控 |
| 10 | 数据库 | 被动中心数据 | ERP/MIS |
| 11 | 黑板 | 知识源竞争 | 语音识别 |
① 归纳系统特征(数据流形态?交互密度?规则多变?) ② 匹配风格并点出核心机制(一两句) ③ 优点两条 + 对该场景的适配理由 ④ 补一句风险/代价(体现权衡意识,案例高分关键)