首页 > 其他分享 >写代码不用"if"行不行,曾经的反 if 运动

写代码不用"if"行不行,曾经的反 if 运动

时间:2023-11-26 09:33:05浏览次数:36  
标签:代码 cry 不用 行不行 animal print True self def

如果在IT行业的时间够长的话,可能还记得大约10几年前,设计模式风靡一时的时候,有过一段反 "if" 的运动。

所谓的反"if"运动,其实是夸大了"if"语句带来的问题,比如当时提出的问题有:

  1. 代码不好维护,特别是if或者else中的代码比较多的时候
  2. ifelse if分支太多的时候,代码难以阅读和修改
  3. 阅读含有if的代码时,必须在自己的头脑中模拟执行,会消耗你的精神能量
  4. ... ... 等等

这些问题确实存在,但是因为这些就彻底禁止if的话,就过于极端,因噎废食了。
代码中分支和循环是不可避免的,完全禁止if之后,在某些时候会产生了更加复杂和令人发指的代码,
所以,最后这个反"if"的运动也不了了之,慢慢消亡了。

不过,为了反"if"而产生的一些替代方案,我挑了三个还值得一看的方案,供大家参考参考。
其它还有很多方案都不太靠谱,就不一一赘述了。

1. 拆分成多个方法

这种重构"if"的方法是将每个分支单独封装成一个独立的方法。
比如:

def select_model(is_regression=True):
    if is_regression:
        print("选择【回归】模型")
    else:
        print("选择【分类】模型")

# 测试代码
select_model(True)
select_model(False)

# 运行结果
选择【回归】模型
选择【分类】模型

示例中,方法select_model通过is_regression参数来决定调用哪种模型。

重构之后:

def select_regression():
        print("选择【回归】模型")

def select_classifier():
        print("选择【分类】模型")

# 测试代码
select_regression()
select_classifier()

# 运行结果
选择【回归】模型
选择【分类】模型

将原方法拆分为两个新方法,"if"就消失了。

2. 改成多态

如果一个函数中分支比较多,比如:

def cry(animal):
    if animal == "dog":
        print("{} :汪汪~".format(animal))
    elif animal == "cat":
        print("{} :喵喵~".format(animal))
    elif animal == "sheep":
        print("{} :咩咩~".format(animal))
    elif animal == "cow":
        print("{} :哞哞~".format(animal))
    else:
        print("无法识别动物:{}".format(animal))

# 测试代码
cry("dog")
cry("cat")
cry("sheep")
cry("cow")

# 运行结果
dog :汪汪~
cat :喵喵~
sheep :咩咩~
cow :哞哞~

cry函数根据不同的参数来判断输出内容,
如果分支多了,并且每个分支中的代码也比较多的时候,会比较难于维护。

对于上面的"if"分支较多的情况,可以用多态的方式来改造。
也就是,封装一个抽象类,其中包含抽象方法cry,然后不同的动物继承抽象类实现自己的cry方法。

from abc import ABCMeta, abstractclassmethod

class Animal(metaclass=ABCMeta):
    def __init__(self, name) -> None:
        self.name = name

    @abstractclassmethod
    def cry(self):
        pass

class Dog(Animal):
    def __init__(self) -> None:
        super().__init__("dog")

    def cry(self):
        print("{} :汪汪~".format(self.name))


class Cat(Animal):
    def __init__(self) -> None:
        super().__init__("cat")

    def cry(self):
        print("{} :喵喵~".format(self.name))


class Sheep(Animal):
    def __init__(self) -> None:
        super().__init__("sheep")

    def cry(self):
        print("{} :咩咩~".format(self.name))


class Cow(Animal):
    def __init__(self) -> None:
        super().__init__("cow")

    def cry(self):
        print("{} :哞哞~".format(self.name))

# 测试代码
animal = Dog()
animal.cry()

animal = Cat()
animal.cry()

animal = Sheep()
animal.cry()

animal = Cow()
animal.cry()

# 运行结果
dog :汪汪~
cat :喵喵~
sheep :咩咩~
cow :哞哞~

3. 将条件判断内联

对于比较复杂的条件判断,可以用内联的方式的来改善。
比如,下面构造一个略微复杂的判断:

def complex_judge(foo, bar, baz):
    if foo:
        if bar:
            return True

    if baz:
        return True
    else:
        return False

# 测试代码
print(complex_judge(True, True, False))
print(complex_judge(True, False, False))
print(complex_judge(False, True, True))

# 运行结果
True
False
True

这样写不仅阅读比较困难,增加或修改判断条件时也很麻烦。

用内联的方式(也就是用 andor)修改后,简洁很多。

def complex_judge(foo, bar, baz):
    return foo and bar or baz

# 测试代码
print(complex_judge(True, True, False))
print(complex_judge(True, False, False))
print(complex_judge(False, True, True))

# 运行结果
True
False
True

4. 总结

"if"运动早已结束,对"if"彻底抛弃显得很荒谬,但也不能对此全盘否定。
"if"语句会影响阅读代码时流畅的思路,对代码中"if"的使用保持慎重的态度还是很有必要的。

标签:代码,cry,不用,行不行,animal,print,True,self,def
From: https://www.cnblogs.com/wang_yb/p/17856553.html

相关文章

  • .net core下优秀的日志框架使用解析,附源代码
    在.NETCore中,日志是一个非常重要的组件,它可以帮助我们记录应用程序的运行情况,以便在出现问题时进行排查。在本文中,我们将介绍五个优秀的.NETCore日志框架,它们分别是Serilog、NLog、Log4Net、Microsoft.Extensions.Logging和Loupe。我们将为每个框架提供使用方法及步骤,并......
  • PYTHON用KERAS的LSTM神经网络进行时间序列预测天然气价格例子|附代码数据
    全文下载链接:http://tecdat.cn?p=26519最近我们被客户要求撰写关于LSTM的研究报告,包括一些图形和统计输出。一个简单的编码器-解码器LSTM神经网络应用于时间序列预测问题:预测天然气价格,预测范围为10天。“进入”时间步长也设置为10天。)只需要10天来推断接下来的10天。......
  • 零代码AppLink平台触发事件组件
    AppLink平台组件组成AppLink平台组件分成三个板块触发事件组件、基础组件和数据连接器触发组件下有三个组件,分别是Webhook、定时器、高级Webhook,那他们在AppLink平台里的原理、触发动作以及怎么使用呢?接下来为大家演示下。Webhook是什么?Webhook是AppLink的内置组件之一,其工作原......
  • 【Flask笔记】4大章60页md笔记第5篇:Flask模板的进阶使用和案例(图文和代码)
    本文的主要内容:flask视图&路由、虚拟环境安装、路由各种定义、状态保持、cookie、session、模板基本使用、过滤器&自定义过滤器、模板代码复用:宏、继承/包含、模板中特有变量和函数、Flask-WTF表单、CSRF、数据库操作、ORM、Flask-SQLAlchemy、增删改查操作、案例、蓝图、单元测......
  • SAP ABAP 动态生成 ABAP 程序并动态调用的例子代码试读版
    本文回答笔者知识星球一个朋友的提问:汪老师您好,请教一个问题。ABAP里的程序能够动态生成吗?我的意思是,ABAP程序的源代码是从第三方传入的,然后在ABAP系统生成,并执行?有没有类似的例子可以参考?谢谢汪老师!首先笔者要提醒的是,这种根据第三方输入,动态生成ABAP程序并且执行的方......
  • 打印数组(不用方法写)
    publicclassHelloWorld{publicstaticvoidmain(String[]args){//打印数组[11,22,33]int[]arr=newint[]{11,22,33};//arr=[0,0,0]int[]arr2=newint[arr.length];//打印数组arr2for(inti=0;i<arr......
  • asp.net core webapi项目实例源代码锦集下载(72个)
    下载地址:http://www.80cxy.com/Blog/ResourceView?arId=202311251726127234f6oAkh所有代码实例(Chinese)物业收费系统,使用ASP.NETCoreMVC框架.netcorewebapi配合swagger以及其他常用功能的单层项目.NETCore实战项目之CMS系列教程的源码Asp.NetCore项目中,以服务......
  • SpringBoot2 仿B站的文章示例代码简介
    SpringBoot2仿B站的文章示例代码简介SpringBoot2是一个基于Java的开源框架,它可以帮助开发者快速构建应用程序。本文将介绍一个仿B站的文章示例代码,展示如何使用SpringBoot2构建一个简单的文章发布和展示平台。项目结构项目结构如下:java复制代码├──pom.xml......
  • 学习笔记11+代码
    一、苏格拉底挑战二、遇见的问题三、实践和代码#include<stdio.h>#include<stdlib.h>#include<string.h>#include<sys/socket.h>#include<netdb.h>#include<arpa/inet.h>#include<unistd.h>#defineMAX256#defineSERVER......
  • 一个用于多线程共享数据保护测试的简易游戏服务器代码
    #include<iostream>#include<thread>#include<list>#include<mutex>//一个线程负责从客户端读取用户的命令,放入一个队列中;//另一个线程负责从队列中读取命令并解析,假设用一个int变量代表一个命令。classA{public://这里无法模拟从网络接受命令的过程,我们......