设计模式与架构模式(高级)——面向对象与函数式结合的实战指南!

举报
喵手 发表于 2026/01/15 17:47:46 2026/01/15
【摘要】 开篇语哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,...

开篇语

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云/阿里云/华为云/51CTO;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

1. 常用设计模式重审(何时用 / 如何实现 / 函数式变体)

工厂(Factory)

  • 意图:把对象创建与使用分离,隐藏具体实现,便于扩展、测试与替换。

  • 何时用:当创建逻辑复杂、需根据上下文/配置/策略返回不同实现时。

  • 实现要点

    • 简单工厂:静态方法根据输入返回不同实现。
    • 抽象工厂/工厂方法:将创建责任推给子类或外部配置。
    • 在 DI 框架下:用 @Configuration / @BeanProvider/FactoryBean 实现可插拔创建。
  • 函数式变体:工厂返回 Supplier<T>Function<Context, T>,工厂由高阶函数构建,便于组合与测试。

策略(Strategy)

  • 意图:把算法/行为封装成可替换的策略,实现运行时替换或组合。

  • 何时用:有大量 if/else 根据类型/配置切换行为时。

  • 实现要点

    • 定义策略接口 Policy,把实现注册到 Map<PolicyKey, Policy> 或用 DI 的 @Qualifier 注入集合。
    • 在工厂/上下文中选择策略并执行。
  • 函数式变体:策略实现为 Function<Request, Result>,用高阶函数/组合器组合多个策略(例如 andThen / compose)。

示例(策略替换 if-else,Java)

public interface PricingStrategy {
    Money apply(Order order);
}

@Component
public class DefaultPricingStrategy implements PricingStrategy { ... }

@Component("vip")
public class VipPricingStrategy implements PricingStrategy { ... }

@Service
public class PricingService {
    private final Map<String, PricingStrategy> strategies;
    public PricingService(List<PricingStrategy> list) {
        this.strategies = list.stream().collect(toMap(s -> s.getClass().getSimpleName().toLowerCase(), s -> s));
    }
    public Money price(Order o){
        return strategies.getOrDefault(o.getCustomerType(), strategies.get("default")).apply(o);
    }
}

责任链(Chain of Responsibility)

  • 意图:把处理请求的不同处理器串成链,按顺序尝试处理,减少条件分支。
  • 场景:复杂验证、拦截器、过滤器、审批流。
  • 实现要点:每个 handler 负责 bool handle(ctx),不处理则传递给下一个。可用函数式流水线 Stream/Flux实现链式处理。

事件驱动(Event-Driven)

  • 意图:松耦合组件通过事件异步通信,解耦执行顺序并提高可扩展性。
  • 场景:跨模块通知、异步补偿、扩展点。
  • 实现要点:定义事件类型、发布者、订阅者(同步/异步),考虑可靠投递(至少一次/恰好一次)、幂等性与事件溯源(Event Sourcing)。
  • 函数式变体:事件流为 Flux<Event>,用操作符做流式处理与组合。

CQRS(Command Query Responsibility Segregation)

  • 意图:把写模型(Command)与读模型(Query)分离,优化可伸缩性与一致性模型。

  • 何时用:读写模式、读取高并发但写少、需要不同存储/表示的场景。

  • 实现要点

    • 写侧:事件或命令处理,更新权威源(Event Store/DB)。
    • 读侧:投影/物化视图,通常为专门的查询 DB(优化查询)。
    • 关注:最终一致性、投影延迟、事务边界、回滚与补偿。
  • 与 Event Sourcing 结合:写侧把状态变更记录为事件流,读侧由事件构建投影。

Event Sourcing(事件溯源)

  • 意图:不存状态快照(或次要快照),而存所有使状态变更的事件,通过重放事件重建实体状态。
  • 优点:完全审计、易于回放/调试、兼容 CQRS。
  • 缺点:实现复杂、事件版本化、存储成本、快照策略与合并策略要设计好。
  • 实现要点:事件版本控制、快照机制、幂等消费、事件合规(schema evolutions)。

2. 微服务 / 分布式下的架构模式(实战重点)

(短列:核心思想、常见实现、工程注意点)

Saga(分布式事务的补偿方案)

  • 两种风格

    • Choreography(编排式):服务通过事件通知彼此,链式触发流转(无中心)。优点:松耦合;缺点:难以观测/验证全流程状态。
    • Orchestration(协调器):单一 Saga 协调器负责执行命令并在失败时触发补偿。优点:易于跟踪与控制;缺点:有中心依赖。
  • 实现要点

    • 每步实现本地事务并发布事件或等待协调器命令。
    • 失败时提供补偿操作(Compensating Action),补偿可能是逆操作或补偿事件。
    • 设计 idempotency(幂等)和保证顺序。
    • 建议用状态机保存 Saga 状态(pending → success/failure → compensating → done)。
  • 工程实践:用消息中间件(Kafka/Rabbit)、持久化 Saga 状态、超时/重试策略、可视化监控。

Circuit Breaker(熔断器)

  • 目的:当被依赖服务出现故障或高延迟时短路调用,保护自身资源。
  • 实现要点:统计失败率/延迟、阈值打开熔断、定时半开探测,结合重试与退避(exponential backoff)。
  • 常用实现:Resilience4j、Hystrix(已退役)等。注意:熔断器应与限流、bulkhead 共同使用。

Bulkhead(舱壁)

  • 目的:隔离资源(线程池、连接池、队列)防止单一故障耗尽整个系统资源。
  • 实现要点:按功能/上下文分配独立线程池或限制并发请求数;在容器层用 Kubernetes 的资源限额实现隔离。
  • 与其他模式搭配:结合 Circuit Breaker、限流(Rate Limiting)和负载剪裁(Load Shedding)。

其他:Retry、Timeout、Rate Limiting、Back-pressure

  • 最佳实践:短路优先(timeout → fallback → retry with backoff),确保幂等;在链路中限制最大并发和请求队列长度。

3. 模块化、插件化设计实践(工程级实践)

  • 分层与边界:保持清晰的模块边界(API/DTO/Domain),用依赖反转(接口)隐藏实现细节。

  • 插件化实现策略

    • Java ServiceLoader:适合简单插件加载。
    • SPI + ClassLoader:更灵活的热插拔(但要小心类加载器隔离)。
    • OSGi / Module System:需要更强的模块化支持与生命周期管理。
    • 在 Spring 中:把 plugin 实现作为模块,使用 @ConditionalOnProperty / @Profile 激活;或使用 SpringFactoriesLoader 自动发现。
  • 接口设计原则(为了插件化)

    • 保持稳定的接口契约(尽量向后兼容)。
    • 使用 adapter/facade 隔离内部变化。
    • 明确插件生命周期(init/start/stop)与资源清理。
  • 测试与安全:对插件隔离运行时进行限制;对第三方插件做签名与权限校验(安全沙箱)。

4. 设计模式的反模式与可维护性考量

  • 过度设计(Overengineering):把“模式”当作模板机械复制,导致代码复杂且难懂。原则:简单优先,先实现直观版本,必要时再抽象。

  • 金锤(Golden Hammer):每个问题都用熟悉的模式(例如用事件驱动解决同步问题)会导致成本膨胀。

  • 上帝对象 / 巨型服务:没有明确边界,造成难以演化与测试。

  • 过度抽象:过多的接口和抽象层会增加认知成本。衡量标准:是否提高可测试性、是否减少重复、是否提升可替换性。

  • 忘记可观察性:分布式系统没有充足的 tracing/metrics/logs,会把模式变成黑箱。

  • 可维护性 checklist

    • 代码能被读懂(少量注释 + 明确命名)
    • 单元测试覆盖策略边界
    • 集成测试覆盖失败/补偿路径
    • 监控与告警(SLO、p95/p99、错误率)
    • 设计文档(接口契约/事件规范)

5. 实战练习(两项:策略替换 if-else;实现简单 Saga 流程)

练习 A:用策略模式替换 if-else 污染点(步骤)

  1. 识别:找到大量基于 type/enumswitch/if 代码块(例如付款方式:if (type==ALIPAY) ... else if (WECHAT) ...)。

  2. 抽象接口

    public interface PaymentHandler {
        boolean supports(PaymentType t);
        PaymentResult handle(PaymentRequest req);
    }
    
  3. 实现类:每个支付方式作单独实现,并用注解/配置注册到容器。

  4. 策略选择器(Registry):

    public class PaymentRouter {
        private final List<PaymentHandler> handlers;
        public PaymentResult route(req){
            return handlers.stream()
                           .filter(h -> h.supports(req.getType()))
                           .findFirst()
                           .orElseThrow(...)
                           .handle(req);
        }
    }
    
  5. 测试与回归:用单元测试覆盖每个 handler;删除旧的 if/else;逐步回退保障。

练习 B:实现一个简单 Saga(Order→Payment→Inventory)

场景

  • 创建订单(Order Service)需完成支付(Payment Service)并扣库存(Inventory Service)。若任一步失败,需回滚已完成步骤(补偿)。

Orchestrator(协调型)示例思路(简化)

  • Saga 状态机NEW -> PAYMENT_PENDING -> INVENTORY_PENDING -> COMPLETED,失败走 COMPENSATING -> ROLLBACK_DONE

  • 持久化 Saga:将当前步骤、相关数据、重试计数持久化(数据库表 sagas)。

  • 步骤实现

    1. Orchestrator 发起 Payment 请求(同步或异步),记录 PAYMENT_PENDING
    2. 若 Payment 成功,调用 Inventory 扣减并记录 INVENTORY_PENDING
    3. 若 Inventory 成功,标记 Saga COMPLETED
    4. 若任何一步失败,按已完成的步骤按逆序执行补偿(例如:若 Inventory 失败且 Payment 成功,则调用 Payment Refund)。
  • 幂等与重试

    • 每个服务的操作(charge、reserve、refund)都应实现幂等(通过 requestId 或 operationId)。
    • Orchestrator 对失败使用指数退避重试,超过阈值进入人工补救或告警。
  • 事件驱动替代(Choreography)

    • 服务发布事件(OrderCreated → Payment listens → PaymentSuccess publishes PaymentSucceeded → Inventory listens …),失败由相应服务发布 PaymentFailed`,但需要机制保证补偿。
  • 示例伪代码(Orchestrator)

public class OrderSagaOrchestrator {
    void startSaga(OrderDto order){
        Saga s = sagaRepo.create(order);
        try {
            paymentService.charge(order);
            s.setState(PAYMENT_DONE); sagaRepo.save(s);
            inventoryService.reserve(order);
            s.setState(INVENTORY_DONE); sagaRepo.save(s);
            s.setState(COMPLETED); sagaRepo.save(s);
        } catch (Exception e) {
            compensate(s); // reverse completed steps
        }
    }
    void compensate(Saga s){
        if (s.state >= PAYMENT_DONE) paymentService.refund(s.order);
        // additional compensations...
        s.setState(ROLLED_BACK); sagaRepo.save(s);
    }
}
  • 监控/可观测性:记录 Saga 执行时间、失败率、补偿频次,集成分布式 trace(OpenTelemetry)与日志。

6. 常见陷阱(再提醒)

  • 把模式当成银弹:先验证痛点再引入复杂模式(例如 CQRS/EventSourcing 不应作为默认实现)。
  • 忽视一致性模型:分布式系统必须明确是强一致性还是最终一致性,设计要反映 SLA/业务要求。
  • 未处理幂等:分布式重试会导致重复执行,所有关键操作必须保证幂等或可补偿。
  • 缺少测试与监控:设计再优雅,缺乏集成测试与监控也等于“盲人修车”。
  • 滥用消息(事件泛滥):事件粒度设计不当会引发复杂的依赖链与调试难度。

7. 推荐练习路径 & 验收标准

  • 小步实验

    1. 在单体应用里把一个 if/else 分支替换为策略模式并编写完整单元测试(含边界错误)。
    2. 用两三个微服务实现一个简单的 Saga(可用本地 Kafka 或 Rabbit),包含持久化 Saga 状态、补偿逻辑、并写集成测试。
  • 验收标准

    • 代码可读且每个模式有测试覆盖;
    • 异常路径(失败、超时)被测试且能触发补偿/回滚;
    • 有度量与追踪(比如 p95 latency、Saga failure rate、补偿率)。

8. 延伸阅读(经典 & 实用)

  • 《设计模式:可复用面向对象软件的基础》(GoF)——模式语义与意图。
  • 《Patterns of Enterprise Application Architecture》——企业级架构模式。
  • 《Microservices Patterns》(Chris Richardson)——Saga、Transaction、Event-driven patterns。
  • 《Designing Data-Intensive Applications》(Martin Kleppmann)——事件源、日志、复制与一致性。
  • 关注 Resilience4j、OpenTelemetry、Event Sourcing / CQRS 实例库与社区文章。

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。


版权声明:本文由作者原创,转载请注明出处,谢谢支持!

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。