【工厂和策略设计模式妙用】解决接口选择与多重if-else 问题
利用工厂和策略模式解决接口选择与多重if-else问题
在软件开发中,我们经常会遇到需要根据不同的条件选择不同实现的情况。传统的if-else或switch-case方式虽然直观,但随着业务逻辑复杂度的增加,会导致代码难以维护和扩展。工厂模式和策略模式的组合可以优雅地解决这个问题。
问题场景
假设我们有一个支付系统,需要根据不同的支付方式(支付宝、微信、银行卡等)调用不同的支付接口。传统实现可能是:
public void pay(String paymentType, BigDecimal amount) {
if ("alipay".equals(paymentType)) {
// 调用支付宝支付逻辑
} else if ("wechat".equals(paymentType)) {
// 调用微信支付逻辑
} else if ("bank".equals(paymentType)) {
// 调用银行卡支付逻辑
}
// 更多支付方式...
}
这种实现方式存在以下问题:
- 违反开闭原则 - 新增支付方式需要修改原有代码
- 代码臃肿 - 随着支付方式增加,方法会越来越长
- 难以维护 - 所有逻辑集中在一个方法中
解决方案:工厂 + 策略模式
1. 定义策略接口
public interface PaymentStrategy {
void pay(BigDecimal amount);
}
2. 实现具体策略类
public class AlipayStrategy implements PaymentStrategy {
@Override
public void pay(BigDecimal amount) {
// 支付宝支付具体实现
System.out.println("使用支付宝支付:" + amount);
}
}
public class WechatPayStrategy implements PaymentStrategy {
@Override
public void pay(BigDecimal amount) {
// 微信支付具体实现
System.out.println("使用微信支付:" + amount);
}
}
public class BankCardStrategy implements PaymentStrategy {
@Override
public void pay(BigDecimal amount) {
// 银行卡支付具体实现
System.out.println("使用银行卡支付:" + amount);
}
}
3. 创建策略工厂
public class PaymentStrategyFactory {
private static final Map<String, PaymentStrategy> strategies = new HashMap<>();
static {
strategies.put("alipay", new AlipayStrategy());
strategies.put("wechat", new WechatPayStrategy());
strategies.put("bank", new BankCardStrategy());
}
public static PaymentStrategy getStrategy(String paymentType) {
if (paymentType == null || paymentType.isEmpty()) {
throw new IllegalArgumentException("支付类型不能为空");
}
PaymentStrategy strategy = strategies.get(paymentType);
if (strategy == null) {
throw new IllegalArgumentException("不支持的支付类型: " + paymentType);
}
return strategy;
}
}
4. 使用策略模式
public class PaymentService {
public void pay(String paymentType, BigDecimal amount) {
PaymentStrategy strategy = PaymentStrategyFactory.getStrategy(paymentType);
strategy.pay(amount);
}
}
优势分析
- 符合开闭原则:新增支付方式只需添加新的策略类并在工厂中注册,无需修改现有代码
- 代码清晰:每个支付方式的逻辑封装在各自的类中
- 易于维护:支付逻辑分散到各个策略类,降低复杂度
- 可扩展性强:可以轻松添加新的支付方式
- 便于测试:每个策略类可以单独测试
进阶优化
使用Spring框架的依赖注入
如果使用Spring框架,可以进一步优化:
@Service
public class PaymentStrategyFactory {
@Autowired
private Map<String, PaymentStrategy> strategies;
public PaymentStrategy getStrategy(String paymentType) {
PaymentStrategy strategy = strategies.get(paymentType);
if (strategy == null) {
throw new IllegalArgumentException("不支持的支付类型: " + paymentType);
}
return strategy;
}
}
// 策略实现类添加@Component注解
@Component("alipay")
public class AlipayStrategy implements PaymentStrategy {
// 实现
}
@Component("wechat")
public class WechatPayStrategy implements PaymentStrategy {
// 实现
}
结合枚举类型
public enum PaymentType {
ALIPAY("alipay", "支付宝支付"),
WECHAT("wechat", "微信支付"),
BANK("bank", "银行卡支付");
private String code;
private String desc;
// 构造方法、getter等
}
然后在工厂中使用枚举值作为key,提高类型安全性。
总结
工厂模式和策略模式的组合是解决条件分支过多问题的经典方案。它将选择逻辑与业务逻辑分离,使系统更加灵活、可扩展。在实际开发中,可以根据项目具体情况选择适合的实现方式,结合框架特性进一步优化。
【工厂和策略设计模式妙用】解决接口选择与多重if-else 问题的更多相关文章
- oop的三种设计模式(单例、工厂、策略)
参考网站 单例模式: 废话不多说,我们直接上代码: <?php /** 三私一公 *私有的静态属性:保存类的单例 *私有的__construct():阻止在类的外部实例化 *私有的__clone ...
- 给jdk写注释系列之jdk1.6容器(9)-Strategy设计模式之Comparable&Comparator接口
前面我们说TreeMap和TreeSet都是有顺序的集合,而顺序的维持是要靠一个比较器Comparator或者map的key实现Comparable接口. 既然说到排序,首先我们不用去关心什 ...
- java 策略设计模式
在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查找.排序等,一种常用的方法是硬编码(Hard Coding)在 ...
- Java(Android)编程思想笔记02:组合与继承、final、策略设计模式与适配器模式、内部类、序列化控制(注意事项)
1.组合和继承之间的选择 组合和继承都允许在新的类中放置子对象,组合是显式的这样做,而继承则是隐式的做. 组合技术通常用于想在新类中使用现有类的功能而非它的接口这种情形.即在新类中嵌入某个对象,让其实 ...
- Head First设计模式——策略设计模式
策略设计模式 说在前面的话 入软件一年啦,平心而论,总算不限于只会钻研些基础的语言语法了,数据结构和算法也恶补的差不多了.所以~趁着现在一边实习一边啃<Head First设计模式>的功夫 ...
- C#软件设计——小话设计模式原则之:接口隔离原则ISP
前言:有朋友问我,设计模式原则这些东西在园子里都讨论烂了,一搜一大把的资料,还花这么大力气去整这个干嘛.博主不得不承认,园子里确实很多这方面的文章,并且不乏出色的博文.博主的想法是,既然要完善知识体系 ...
- Java设计模式之策略设计模式
1.什么是-策略设计模式 在软件开发中常常遇到这种情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查找.排序等,一种常用的方法是硬编码(Ha ...
- java策略设计模式
1.概述 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们可以相互替换,让算法独立于使用它的客户而独立变化. 其实不要被晦涩难懂的定义所迷惑,策略设计模式实际上就是定义一个接口,只要实现 ...
- 简单工厂模式&策略模式-简介与区别
不得不说,这两种模式真的很像. 相似点:都用到了面向对象的继承.多态.抽象,都拥有相似的结构. 不同点:工厂模式仅提供具体的实例对象,怎么使用这个对象是client的自由,策略模式client可以通过 ...
- JAVA学习笔记--策略设计模式与适配器模式
一.策略设计模式 创建一个能够根据所传递对象的不同而具有不同行为的方法被称为策略设计模式:这类方法包含所要执行的算法中固定不变的部分,而“策略”包含变化的部分.策略就是传递进去的参数对象,它包含要执行 ...
随机推荐
- HttpClient使用方法总结及工具类封装
1. 引入httpclient依赖 首先,需要确认项目中是否已引入过httpclient依赖,如果没有引入过,需要在pom.xml中添加以下代码引入httpclient依赖: <dependen ...
- 轻松的工作(deepseek)
组长:"这里有一百多个地震波形文件,把每一个地震建立一个文件夹,并把地震波形放到对应日期的地震中." 我想:一个一个整好麻烦想摸会鱼 让我们来deepseek吧~ 首先,生成文件夹 ...
- DevOps工程师
DevOps工程师 1. DevOps工程师的任务是什么? 设计.构建.测试和部署可伸缩的分布式系统,实现从开发到部署的自动化 管理代码库(如Git.SVN.BitBucket等),包括代码合并与集成 ...
- soapUI参数化总结
1.新建项目目录 以获取用户贡献等级为例,目录如下: 2.添加DataSource和DataSource Loop 选中Test Step右键分别新建DataSource和DataSource Loo ...
- win7激活,2023年亲测可用 ,win7激活密钥,激活码
还在找激活密钥,激活win7吗,试了无数个都激活不了? 直接用这个工具激活吧,亲测可用,用过的都知道. WIN7Chew-WGA0.9.exe 阿里云盘:https://www.aliyundrive ...
- AI 重塑测试,2025 年何去何从?
各位技术同仁,特别是奋斗在软件质量保障一线的朋友们,大家好! 2025 年的软件测试领域,AI 早已不是锦上添花的"时髦概念",而是决定效率.质量乃至生存空间的"核心引擎 ...
- 三-select模型
select模型是对简单C/S模型的优化,他解决了accept函数阻塞等待连接的问题.并且允许应用程序同时监视多个套接字,从而实现简单的并发请求.通过调用select函数确认一个或多个套接字当前的状态 ...
- MongoDB中distinct的用法
作用 获取集合中指定字段的不重复值,并以数组的形式返回 语法 db.collection_name.distinct(field,query,options) field:指定返回的字段(string ...
- [安洵杯 2019]easy_serialize_php 1 WP
[安洵杯 2019]easy_serialize_php 1 WP 这道题目考察的主要是序列化与反序列化过程中,对象逃逸的一个漏洞. 说是对象逃逸,我觉得可能叫对象注入比较形象. 首先题目上来可以看到 ...
- L2-4、选择微调还是提示工程?企业级内容生成的最佳实践
一.Prompt 工程与模型微调的本质区别 Prompt 工程的特点 Prompt 工程是通过精心设计输入提示来引导大语言模型生成所需输出的技术.它不改变模型的基本参数,而是利用现有模型能力. 工作原 ...