工厂模式实战——SpringBoot框架下的If-else代码优化
发布日期:2021-11-18 19:17:22 浏览次数:17 分类:技术文章

本文共 5402 字,大约阅读时间需要 18 分钟。

SpringBoot框架下的If-else代码优化

1 为什么要去if-else

在开发的过程中我们可能会经常遇到if else的逻辑,写很多if else对于一位有情怀的程序员看来是不可以接受的,也影响阅读人的阅读感受,同时程序也违背了对修改关闭扩展开放的原则。在写程序的过程中我们应该尽量保证修改关闭,也就是说自己的写的代码逻辑应不该让别人在扩展逻辑的过程中进行修改,同时保证高的可扩展性。

在使用if else写程序的过程中你可能会写出如下的代码:

String type= "";if(type.equals("类型一")){
}else if(type.equals("类型二")){
}else if(...){
}else {
}

需要加一个分支逻辑就必须得去if else结构中改代码,这样不利于程序扩展,同时也非常难维护,如果业务复杂到一定的程度这块代码可能没法去重构了。

2 案例重现

2.1 案例需求

假设对于学校使用仪器要进行网上收费,然后学校可根据不同主体,比如课题组或者个人进行收费。也具有不同的收费模式。那么对于原先的代码来说需要进行多个if-else判断,代码示例如下:

public void chargeBackAndReturnResult(String chargeType,String chargeBody) {
if(chargeBody.equals("Personal")){
if(chargeType.equals("Credit")){
System.out.println("执行收费主体为个人的信用卡收费模式");//真实业务代码有200行左右 }else if(chargeType.equals(" deposit")){
System.out.println("执行收费主体为个人的储蓄卡收费模式"); } }else if(chargeBody.equals("CommonTeam")){
if(chargeType.equals("Credit")){
System.out.println("执行收费主体为课题组的信用卡收费模式"); }else if(chargeType.equals(" deposit")){
System.out.println("执行收费主体为课题组的储蓄卡收费模式"); } } }

对于这种if-else嵌套来说,即使进行方法的封装,依然不利于程序扩展,并且如果增加收费主体和收费类型,则需要继续增加if-else嵌套,影响代码的可读性。

2.2 优化方案

可以明确的是,对于不同的收费主体以及收费模式,所传入的参数基本相同。无外乎用户/课题组编号,金额等基本业务内容。那么我们就可以将收费模式统一抽象出一种行为规范作为接口,并通过不同实现类对接口进行继承。然后通过工厂进行统一管理,这就是工厂模式的核心思想。

2.2.1 接口的创建

public interface ChargeService {
String getType();//用于获取收费类型 String chargeBackAndReturnResult();//用于执行具体收费方法 }

2.2.2 实现类的创建

public class DepositPersonalChargeServiceImpl implements ChargeService{
public String getType(){
return "DepositPersonal"; } public void chargeBackAndReturnResult() {
System.out.println("执行收费主体为个人的借记卡收费模式"); }}public class DepositCommonTeamChargeServiceImpl implements ChargeService{
public String getType(){
return "DepositCommonTeam"; } public void chargeBackAndReturnResult() {
System.out.println("执行收费主体为课题组的借记卡收费模式"); }}public class CreditPersonalChargeServiceImpl implements ChargeService{
public String getType(){
return "CreditPersonal"; } public void chargeBackAndReturnResult() {
System.out.println("执行收费主体为个人的信用卡收费模式"); }}public class CreditCommonTeamChargeServiceImpl implements ChargeService{
public String getType(){
return "CreditCommonTeam"; } public void chargeBackAndReturnResult() {
System.out.println("执行收费主体为课题组的信用卡收费模式"); }}

2.2.3 工厂的创建

public class ChargeFactory{
public static Map
chargeMap=new HashMap
();//定义一个map容器 static{
chargeMap.put("DepositCommonTeam",new DepositCommonTeamChargeServiceImpl()); chargeMap.put("DepositPersonal",new DepositPersonalChargeServiceImpl()); chargeMap.put("CreditPersonal",new CreditPersonalChargeServiceImpl()); chargeMap.put("CreditCommonTeam",new CreditCommonTeamChargeServiceImpl()); }//写入map的值 public static ChargeService getChargeService(String chargeType){
ChargeService chargeService=chargeMap.get(chargeType); if(chargeService!=null){
return chargeService; }else{
return null; } }}

2.2.4 测试用例

public static void main(String[] args){
ChargeService chargeService=ChargeFactory.getChargeService("DepositCommonTeam");//获取对应的Service对象 chargeService.chargeBackAndReturnResult();//调用对应的方法 }

输出结果

执行收费主体为课题组的借记卡收费模式

3 利用SpringBoot框架进行进一步优化

3.1 之前方案所存在的不足

对于案例给出的解决方案来说,存在两个缺点:

  1. 新策略添加时,不仅需要增添新的class类,还需要在Factory工厂进行对应class的添加。
  2. 参照mvc经典框架下实现代码:
//Service实现层@Servicepublic class DepositCommonTeamChargeServiceImpl implements ChargeService{
@Autowired UserService userService; public String getType(){
return "DepositCommonTeam"; } public void chargeBackAndReturnResult() {
if(userService==null){
System.out.println("User服务注入失败"); }else{
System.out.println("User服务注入成功"); } System.out.println("执行收费主体为课题组的借记卡收费模式"); }}//Controller层@RestControllerpublic class Test {
@RequestMapping(value = "/charge/test",method = RequestMethod.POST) public void test(){
//经典mvc框架Controller层调用Service方法 ChargeService chargeService=ChargeFactory.getChargeService("DepositCommonTeam"); chargeService.chargeBackAndReturnResult(); }}

输出结果

User服务注入失败执行收费主体为课题组的借记卡收费模式

能够发现如果应用@Autowired注解所注入的Spring对象,在方法调用时无法获取到。

3.2 优化解决方案

修改原Factory工厂类

@Componentpublic class ChargeFactory implements ApplicationContextAware {
public static Map
chargeMap=new HashMap
();//定义一个Map类 @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//根据接口类型返回相应的所有bean Map
map = applicationContext.getBeansOfType(ChargeService.class);//通过applicationContext获取注入Spring容器中的类 map.forEach((key, value) -> chargeMap.put(value.getType(), value));//给Map类进行赋值 } public static ChargeService getChargeService(String chargeType){
ChargeService chargeService=chargeMap.get(chargeType); if(chargeService!=null){
return chargeService; }else{
return null; } }}

此时再进行结果输出

User服务注入成功执行收费主体为课题组的借记卡收费模式

转载地址:https://blog.csdn.net/weixin_39174824/article/details/99306446 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:使用docker安装多个redis进行主从配置,并使用swoole对主从延时进行监听
下一篇:设计模式详解(2)——原型模式

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年03月27日 05时09分15秒