设计模式:干掉if else的几种方法

这篇具有很好参考价值的文章主要介绍了设计模式:干掉if else的几种方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问题

if (variable == value1) {
	// 业务逻辑1
} else if (variable == value2) {
	// 业务逻辑2
} else {
	// 业务逻辑3
}

存在的问题:

  1. 如果业务逻辑过多if else可能要写多达几百行,这样代码可读性很差,不利于寻找bug和理解代码
  2. 如果if后面的判断逻辑过长,则代码可读性不强
  3. 如果将其写在一个核心代码里面,则新增功能时需要修改核心代码,要是不小心改到其他的代码就凉凉了
  4. 当业务逻辑1、业务逻辑2、业务逻辑3存在通用逻辑时,则无法很好的复用代码
  5. 总的来说就是代码可扩展性差、可读性差、可复用性差。可扩展性差,说明修改时需要修改以前的代码,增加了风险。可读性差,说明代码一大段一大段的,想要修改一个东西得到处找,而且逻辑复杂难以读懂。可复用性差,不止写的时候累,改的时候也累,因为虽然是同样的逻辑,但是你写在了10个地方,你就需要改10次。

初级:switch

switch (variable) {
       case value1:
           commonDoSomething();
           doSomething1();
           break;
       case value2:
       	   commonDoSomething();
           doSomething2();
           break;
       default:
           commonDoSomething();
           doSomething3();
           break;
}

改进:

  1. 使用switch增加了可读性,但是在一些复杂判断逻辑时,明显不如if else 方便
  2. 将业务逻辑抽象成函数,将公有逻辑全部抽出来,增加了代码的可读性、可复用性

存在的问题:

  1. 和if else一样,如果条件分支过多switch可能要写多达几百行,这样代码可读性很差,不利于寻找bug和理解代码
  2. 和if else一样,如果将其写在一个核心代码里面,则新增功能时需要修改核心代码,要是不小心改到其他的代码就凉凉了

中级:多态

   public interface Animal {
       void makeSound();
   }
   public class Dog implements Animal {
       public void makeSound() {
           System.out.println("业务逻辑1");
       }
   }

   public class Cat implements Animal {
       public void makeSound() {
           System.out.println("业务逻辑2");
       }
   }
    public class Main {
      public static void main(String[] args) {
         Animal animalDog = new Dog();
   		 animalDog.makeSound();
   		 Animal animalCat = new Cat();
   		 animalCat.makeSound();
     }
   }

改进:

  1. 使用多态将业务逻辑拆分到各个类中,极大的降低了同一个模块中的代码了,使得可读性提高了很多
  2. 可以使用继承抽象类方式的多态,这样还可以共用逻辑复用代码,提高了代码的可复用性

存在的问题:

  1. 新增业务逻辑时仍然需要修改核心代码

高级:策略模式+Map

 public interface Strategy {
       void doSomething();
   }

   public class StrategyA implements Strategy {
       public void doSomething() {
           //业务逻辑1
       }
   }

   public class StrategyB implements Strategy {
       public void doSomething() {
            //业务逻辑2
       }
   }

  public class Main {
      public static void main(String[] args) {
         Strategy strategy = getStrategy();
   		 strategy.doSomething();
     }
  }
   

改进:
使用策略模式,可以发现策略模式和多态其实也没有多大的区别,但关键就在于getStrategy()方法,它的实现的多变,可以大大提高代码的可扩展性,无需修改了核心代码

Map的实现

public GetStrategy {
	private static final Map<String, Strategy> map = new HashMap(){{
		put("StrategyA", new StrategyA());
		put("StrategyB", new StrategyB());
	}};//双花括号表示一个类继承HashMap类并重写其构造方法
	public Strategy getStrategy(String strategyName) {
		return map.get(strategyName);
	};
}

实现:
1.将所有的策略中存储在一个Map中,这样当我们需要增加逻辑时只需要增加一个put即可,代码可扩展性很强,而且getStrategy()里面的代码和使用getStrategy()方法的核心逻辑都无需修改。
2.策略名可以在最开始的配置代码中传入,如配置类中就传入
存在的问题
如果是复杂的逻辑来决定需要选取的策略,而不是通过策略名来选取的话,就无法实现,如果要实现的话需要增加一个策略匹配器,如下:

public interface Matcher {
	public String match() {
		//判断逻辑,返回策略名
	}
}

//使用
public class Main {
      public static void main(String[] args) {
         Strategy strategy = getStrategy(new MatcherImpl().match());
   		 strategy.doSomething();
     }
  }

优缺点:文章来源地址https://www.toymoban.com/news/detail-465912.html

  1. 使用策略匹配器的优点就是,方便自己传入不同的策略匹配器的实现,来进行不同的规则匹配,这样可以扩展。
  2. 但是其缺点就是,如果一个匹配器中逻辑过于复杂,则又会陷入if else的困境
    解决方案:
class MatcherChain {
	private List<Matcher> matcherList = new ArrayList(){{
	add(new MatcherA());
	add(new MatcherB());
}};
	
	public String match() {
		for (Matcher matcher : matcherList) {
			String strategyName = matcher.match()
			if (strategyName != null) {
  				return strategyName;
  			}
		}
	}
}
  1. 将每个if都拆分为一个Matcher,使用List线性表数据结构将其存储起来,表明其的先后顺序关系,就类似不同的if直接的先后顺序关系。
  2. 然后循环调用Matcher匹配器的match方法,如果判断逻辑匹配上,则改Matcher返回对应的策略名。
  3. 扩展也很方便,只需新建一个Matcher将其加入matcherList即可,但要注意添加进列表的顺序,如果条件逻辑之间有重合

到了这里,关于设计模式:干掉if else的几种方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【开源与项目实战:开源实战】82 | 开源实战三(中):剖析Google Guava中用到的几种设计模式

    上一节课,我们通过 Google Guava 这样一个优秀的开源类库,讲解了如何在业务开发中,发现跟业务无关、可以复用的通用功能模块,并将它们从业务代码中抽离出来,设计开发成独立的类库、框架或功能组件。 今天,我们再来学习一下,Google Guava 中用到的几种经典设计模式:

    2024年02月11日
    浏览(67)
  • 策略模式解决if-else问题

    释义: 策略模式是一种行为设计模式,它允许在运行时根据不同的情况来选择不同的策略。 这种模式支持开闭原则,在不修改现有代码的前提下,动态的添加、删除、替换算法。 组成部分: 策略接口(Strategy) :它是一个接口,具体的策略实现类去实现这个接口,就可以提供

    2024年02月03日
    浏览(37)
  • 策略模式+Spring配置类优化多if..else思路

    场景: 假设设备上报不同类型的消息,我们要对不同类型的消息做不同的处理。如果我们通过if..else的方式处理的话会显得比较冗余。 例如: 那么对于不同消息的不同的处理逻辑我们可以单独放在一个实现类中,这些类有着相同的行为,所以我们可以定义一个接口: 针对于不

    2024年02月15日
    浏览(42)
  • 记录--卸下if-else 侠的皮衣!- 策略模式

    给我一个功能,我总是要写很多if-else,虽然能跑,但是维护起来确实很难受,每次都要在一个方法里面增加逻辑,生怕搞错,要是涉及到支付功能,分分钟炸锅 我总是不知道之前写的逻辑在哪里,一个方法几百行逻辑,而且是不同功能点冗余在一起!这可能让我牺牲大量时间

    2024年02月16日
    浏览(41)
  • 不需要策略模式也能避免满屏if/else

    java 复制代码 public static void main(String[] args) { int a = 1; if(a == 1){ System.out.println(\\\"执行a=1的逻辑\\\"); }else if (a == 2){ System.out.println(\\\"执行a=2的逻辑\\\"); }else if (a == 3){ System.out.println(\\\"执行a=3的逻辑\\\"); }else if (a == 4){ System.out.println(\\\"执行a=4的逻辑\\\"); }else if (a == 5){ System.out.println(\\\"执行a=5的逻辑

    2024年02月06日
    浏览(88)
  • Java实现单例模式的几种方法

    单例模式作为23中设计模式中最基础的设计模式,一般实现方式为 ①私有化构造方法 ②提供一个获取对象的静态方法 除此之外,实现单例模式的方法还有很多种,这篇文章主要介绍实现单例模式的几种方法。 目录 一、懒汉式单例 二、懒汉式单例优化(双重检测锁) 三、饿

    2024年02月12日
    浏览(38)
  • 用策略模式干掉代码里大量的if-eles或则Swatch,提升B格由面向过程转为面向对象

    其实很简单 if里面的多个魔法常量 和HashMap里面的key是不是可以等比互换呢!! 所以我们核心就是从一个类似于HashMap这种的容器里去获取某一个key,就等同于进去到了if 的对应分支 而if 的对应分支 里面的业务,交给HashMap的Value去调方法完成没毛病把 --比如上述代码是判断字

    2024年02月08日
    浏览(39)
  • 用策略模式加工厂模式优化多重if-else或者switch代码

    情景:通过不同的出行方式和数量拿到不同的减碳量 代码从controller开始贴 是为了更贴近真实场景 原始代码 controller: 枚举类: TravelEnum: service: 改进: controller: swevice: 其中 GreenTravelModeService 是一个接口: GreenTravelModeService 有三个实现类,分别代表 三种不同出行方式获得减碳的

    2024年02月03日
    浏览(42)
  • 【状态模式】拯救if-else堆出来的屎山代码

    我想大家平时都在开发重都遇见过屎山代码,这些屎山代码一般都是由于复杂且庞大的if-else造成的,状态模式,是一种很好的优化屎山代码的设计模式,本文将采用两个业务场景的示例来讲解如何使用状态模式拯救屎山代码。 目录 前言 1.网购业务场景 1.1.需求 1.2.if else的实

    2024年02月12日
    浏览(39)
  • springboot工厂模式解决if_else流程和问题点解决

    spring中的Bean由IOC容器进行管理,和普通工厂的区别就是springboot中的类不能通过自己New出来使用,如果通过new写入到工厂,涉及到相关实现类调用其他Service(该service在正确情况下正常注入),注入的Service也会报错异常Null,也就是工厂注入失败。 工厂中的相关Bean也通过Spring

    2023年04月09日
    浏览(65)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包