← 返回导航

详解:经典架构风格

五大类11种风格逐个详解:定义+机制+真实系统+Java代码+考试考法

层级:速记 01-styles / 深入 d01-styles / 本页=详解。每种风格:定义 -> 机制 -> 真实系统 -> Java 代码 -> 考试考法。

1. 批处理(Batch Sequential)

定义:整批输入一次性处理完,再输出给下一道工序。数据驱动的「整批」形态。

机制:工序 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 整批」。

2. 管道-过滤器(Pipes and Filters)

定义:流式增量处理,前级过滤器输出即后级输入,管道负责衔接。

机制:每个过滤器独立工作,不需要等整批数据;流到哪处理到哪。

真实系统: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());

考试考法:案例题描述「数据流逐步加工、各阶段可并行、前段输出后段输入」-> 管道-过滤器;优点考「支持复用与并行」、缺点考「不适合交互应用」。

3. 主程序-子程序(Main Program - Subroutine)

定义:单线程自顶向下调用,最古老的结构化风格。

机制:主程序掌控流程,子程序被调用执行后返回控制权。

真实系统:传统 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
    }
}

考试考法:作为「层次型的退化形态」出现在选择题;明确「单线程、无并发」特征。

4. 面向对象(OO)

定义:封装数据与操作为对象,通过消息(方法调用)协作。

机制:封装=隐藏内部状态;多态=同一消息不同响应;继承=复用定义。

真实系统:一切现代业务系统。

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);  // 多态分发
    }
}

考试考法:与「面向对象分析与设计」结合考封装/多态的架构价值(隔离变化);「对象间松耦合靠接口抽象」是送分点。

5. 层次型(Layered)

定义:系统按职责分层,每层只依赖直接下层,服务单向向上。

机制:第 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 松散分层」:严格=只能调相邻下层;松散=可跨层调用(性能好、纯度低)。

6. 进程通信(Independent Processes / Message Passing)

定义:独立进程间显式消息传递协作,无共享内存。

机制:点对点消息(请求-响应或单向通知),进程各自独立生命周期。

真实系统:微服务间 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();
    }
}

考试考法:与「事件驱动」对比考:进程通信=显式定向(我知道发给谁);事件驱动=隐式广播(我不关心谁处理)。

7. 事件驱动(Event-Driven, Implicit Invocation)

定义:构件通过发布事件解耦,订阅者被事件触发,发布者不知道谁在听。

机制:发布-订阅;事件源发出通知,系统自动调用所有订阅者。

真实系统: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(...); }

考试考法:案例高频「系统需要灵活扩展新功能、发布者与处理者解耦」-> 事件驱动;缺点考「控制流不直观、调试难」。

8. 解释器(Interpreter)

定义:解释执行自定义语言/指令集的虚拟机。

机制:解释引擎逐条读取指令 -> 查上下文 -> 执行动作。

真实系统: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 规则系统:前者是通用引擎,后者是知识+推理的特化。

9. 规则系统(Rule-Based System)

定义:知识库 + 推理机的虚拟机特化,用规则而非代码表达业务逻辑。

机制:规则库(条件->动作)+ 工作内存(事实)+ 推理机(匹配-冲突消解-执行循环)。

真实系统: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

考试考法:「业务规则频繁变化、需要业务人员参与配置」-> 规则系统;与解释器归入虚拟机类(都是「用数据表达行为」)。

10. 数据库风格(Repository / Database)

定义:中心数据被动存储,客户端主动访问读写。

机制:所有构件围绕共享数据集工作;数据结构稳定,操作围绕它增删改查。

真实系统: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 知识源竞争写」。

11. 黑板(Blackboard)

定义:中心数据主动驱动,多个知识源监视黑板、竞相更新。

机制:知识源观察黑板状态,条件满足即出手修改;无中央控制器决定谁先谁后。

真实系统:语音识别(声学/语法/语义知识源竞相解读)、雷达信号处理、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黑板知识源竞争语音识别

案例题答题模板(选风格)

① 归纳系统特征(数据流形态?交互密度?规则多变?) ② 匹配风格并点出核心机制(一两句) ③ 优点两条 + 对该场景的适配理由 ④ 补一句风险/代价(体现权衡意识,案例高分关键)