你一定要知道业务开发最常用的两种设计模式

简介: 文章介绍了业务开发中最常用的两种设计模式:策略模式和异步形式的责任链模式,通过具体案例展示了它们在代码解耦、扩展性增强以及提升响应速度方面的应用,并强调了设计模式在提升代码质量和开发效率中的重要性。

一、背景

很多做业务开发的同学,很多认为平时写业务代码工作就是简单的增删改查,没有挑战,写的代码不会像一些开源框架那么优雅,随着你积累的经验越来越多,你应该跳出这种思维,业务代码也可以写的很优雅,也可以有较好的可读性扩展性

我们可以观察公司内,或者团队内工作时间长一点的同事写的代码,一般都可以找到可以学习的代码。如果你读过Spring源码的同学可以知道,Spring代码有一个非常大的特点就是扩展性极强,他扩展性强一个很重要的原因是恰当的使用了很多设计模式。

本文将结合案例分析平时业务开发中使用频率最高的两种设计模式<<策略模式>>与<<责任链模式>>。

二、策略模式

以支付功能为例子,我们知道支付一般都支持多种支付方式,我们支付功能在后端发起,不同的支付方式其实就是策略,我们可以通过策略模式来完成支付功能。将不同的支付方式代码进行解耦。

public interface PaymentStrategy {
   
   
    void pay(double amount);
}

public class WeChatPaymentStrategy implements PaymentStrategy {
   
   
    @Override
    public void pay(double amount) {
   
   
        // 微信支付逻辑
    }
}

public class AlipayPaymentStrategy implements PaymentStrategy {
   
   
    @Override
    public void pay(double amount) {
   
   
        // 支付宝支付逻辑
    }
}
import java.util.HashMap;
import java.util.Map;

public class PaymentStrategyFactory {
   
   
    private Map<String, PaymentStrategy> strategies = new HashMap<>();

    public void registerStrategy(String name, PaymentStrategy strategy) {
   
   
        strategies.put(name, strategy);
    }

    public PaymentStrategy getStrategy(String name) {
   
   
        return strategies.get(name);
    }
}

使用策略模式:

public class Main {
   
   
    public static void main(String[] args) {
   
   
        PaymentStrategyFactory factory = new PaymentStrategyFactory();

        // 注册支付策略
        factory.registerStrategy("wechat", new WeChatPaymentStrategy());
        factory.registerStrategy("alipay", new AlipayPaymentStrategy());

        // 获取支付策略
        PaymentStrategy wechatStrategy = factory.getStrategy("wechat");
        PaymentStrategy alipayStrategy = factory.getStrategy("alipay");

        // 使用支付策略
        wechatStrategy.pay(100.0);
        alipayStrategy.pay(150.0);
    }
}

通过上方实际例子,我们可以发现策略模式很好的将不同的支付方式进行了解耦,如果业务需要新增一种支付方式,我们不需要改原先的支付方式代码,这样可以达到对扩展开发,对修复关闭的设计原则,对于测试范围也可控了。

三、异步形式的责任链模式

责任链模式在业务开发中也是可以使用频率高的设计模式,我们以展示商品为例:

详情.jpg

商品页面,包含商品标题,主图等基础信息,商品价格,商品优惠活动,商品库存等等。

在微服务架构中,商品基础信息,商品价格,商品优惠活动,商品库存都是一个独立的领域服务,他们通过rpc进行通信,如果我们一个一个调用,这样代码看起来就是一本流水账,过程式编码,整体的响应时间也会拉长。最初的想法可能是这样写的:

1、查询商品基础信息
2、查询商品价格
3、查询商品活动
4、查询商品库存

由于这几个服务逻辑比较独立,其实是可以并行调用,我们可以结合责任链模式CompletableFuture进行优化。

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

// 商品信息类
class ProductInfo {
   
   
    //模拟商品基础信息
    private String basicInfo;
    //商品价格
    private double price;
    //模拟商品活动信息
    private String activity;
    //模拟商品库存
    private int inventory;

    // 省略构造函数、getter和setter
}

// 定义责任链节点接口 补全商品处理接口
interface ServiceHandler {
   
   
    CompletableFuture<Void> handle(ProductInfo productInfo);
}

// 实现商品基础信息补全节点
class BasicInfoServiceHandler implements ServiceHandler {
   
   
    @Override
    public CompletableFuture<Void> handle(ProductInfo productInfo) {
   
   
        CompletableFuture<Void> future = new CompletableFuture<>();
        // 模拟异步调用外部服务,修改商品信息对象
        CompletableFuture.runAsync(() -> {
   
   
            // 补充商品基础信息数据
            productInfo.setBasicInfo("...");
            future.complete(null);
        });
        return future;
    }
}

// 实现商品价格补全节点
class PriceServiceHandler implements ServiceHandler {
   
   
    @Override
    public CompletableFuture<Void> handle(ProductInfo productInfo) {
   
   
        CompletableFuture<Void> future = new CompletableFuture<>();
        // 模拟异步调用外部服务,修改商品信息对象
        CompletableFuture.runAsync(() -> {
   
   
            // 补充商品价格数据
            productInfo.setPrice(100.0);
            future.complete(null);
        });
        return future;
    }
}

// 实现商品活动补全节点
class ActivityServiceHandler implements ServiceHandler {
   
   
    @Override
    public CompletableFuture<Void> handle(ProductInfo productInfo) {
   
   
        CompletableFuture<Void> future = new CompletableFuture<>();
        // 模拟异步调用外部服务,修改商品信息对象
        CompletableFuture.runAsync(() -> {
   
   
            // 补充商品活动数据
            productInfo.setActivity("...");
            future.complete(null);
        });
        return future;
    }
}

// 实现商品库存服务节点
class InventoryServiceHandler implements ServiceHandler {
   
   
    @Override
    public CompletableFuture<Void> handle(ProductInfo productInfo) {
   
   
        CompletableFuture<Void> future = new CompletableFuture<>();
        // 模拟异步调用外部服务,修改商品信息对象
        CompletableFuture.runAsync(() -> {
   
   
            // 补充商品库存数据
            productInfo.setInventory(100);
            future.complete(null);
        });
        return future;
    }
}

// 责任链
class ServiceHandlerChain {
   
   
    private List<ServiceHandler> handlers = new ArrayList<>();

    public void addHandler(ServiceHandler handler) {
   
   
        handlers.add(handler);
    }

    public ProductInfo execute(ProductInfo productInfo) {
   
   
        CompletableFuture<Void>[] futures = handlers.stream()
                .map(handler -> handler.handle(productInfo))
                .toArray(CompletableFuture[]::new);
        //等待所有的异步补全任务处理完成   
        CompletableFuture<Void> allOfFuture = CompletableFuture.allOf(futures);
        allOfFuture.join(); // 等待所有异步操作完成
        return productInfo;
    }
}

调用责任链,实现商品信息补全:

public class Main {
   
   
    public static void main(String[] args) {
   
   
        // 创建商品信息对象
        ProductInfo productInfo = new ProductInfo();

        // 创建责任链
        ServiceHandlerChain chain = new ServiceHandlerChain();
        chain.addHandler(new BasicInfoServiceHandler());
        chain.addHandler(new PriceServiceHandler());
        chain.addHandler(new ActivityServiceHandler());
        chain.addHandler(new InventoryServiceHandler());

        // 执行责任链
        ProductInfo result = chain.execute(productInfo);

        // 处理最终的商品信息对象
    }
}

通过责任链模式+CompletableFuture优化调整,我们将商品各自补全逻辑进行拆分互不依赖,如果需要展示商品其他信息可以扩展新节点,而且每个节点都是异步化处理,提升整体响应速度

四、总结

本文结合实际例子对于业务开发工作中最常用两个设计模式进行了总结,适当使用设计模式可以把一些业务需求实现的更加优雅,对于未来的扩展性也打下了基础,给后期开发测试都减少了工作量,设计模式可以结合我们实际业务适当调整,变成适合我们自己业务的模式,比如上面的异步形式的责任链

关注我们一起学习技术吧,坚持相信有输入一定要有输出,希望我们的技术能力越来越强大。

image.png

相关文章
|
5月前
|
设计模式 Java Spring
Java 设计模式之责任链模式:优雅处理请求的艺术
责任链模式通过构建处理者链,使请求沿链传递直至被处理,实现发送者与接收者的解耦。适用于审批流程、日志处理等多级处理场景,提升系统灵活性与可扩展性。
640 2
|
消息中间件 存储 RocketMQ
Rocketmq如何保证消息不丢失
文章分析了RocketMQ如何通过生产者端的同步发送与重试机制、Broker端的持久化存储与消息重试投递策略、以及消费者端的手动提交ack与幂等性处理,来确保消息在整个传输和消费过程中的不丢失。
|
Java 程序员
谈谈程序员如何学习新技术
文章分享了作者学习新技术的经验和方法,从确定学习目标、制定学习计划到学中坚持和学后应用,强调了持续学习的重要性,并鼓励程序员通过实践、写作、分享和开源贡献等方式不断成长和提升技术能力。
|
NoSQL 关系型数据库 MySQL
做电商业务开发这几年,我学到的系统稳定性建设方法
文章总结了电商业务开发中保障系统稳定性的关键方法,包括代码健壮性、安全变更、系统链路梳理、接口降级与限流、定期降级演练、预案准备、系统压测、日常巡检、中间件巡检、值班制度和告警机制,强调了稳定性建设是一个长期任务,需要持续迭代优化,并保持对生产系统的敬畏之心。
|
存储 监控 Java
OpenFeign请求拦截器组件RequestInterceptor原理与使用场景
该文章讲述了OpenFeign中的请求拦截器组件RequestInterceptor的原理及其常见使用场景。
OpenFeign请求拦截器组件RequestInterceptor原理与使用场景
|
开发者
如何画业务架构图
如何快速上手画业务架构图
13154 2
|
消息中间件 存储 RocketMQ
2分钟看懂RocketMQ延迟消息核心原理
本文从源码层面解析了RocketMQ延迟消息的实现原理,包括延迟消息的使用、Broker端处理机制以及定时任务对延迟消息的处理流程。
2分钟看懂RocketMQ延迟消息核心原理
|
消息中间件 缓存 负载均衡
复盘女朋友面试4个月的RocketMQ面试题
这篇文章复盘了面试中关于RocketMQ的高频题目,包括架构组成、使用姿势、功能原理及高级特性,并强调了理解这些实现机制对于面试成功的重要性。
复盘女朋友面试4个月的RocketMQ面试题
|
前端开发 JavaScript
前端模拟接口工具推荐——Apifox(mock数据)【图解教程】
前端模拟接口工具推荐——Apifox(mock数据)【图解教程】
4768 1

热门文章

最新文章