首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >你还在用if else吗?

你还在用if else吗?

作者头像
lyb-geek
发布于 2018-09-27 01:43:35
发布于 2018-09-27 01:43:35
1.2K00
代码可运行
举报
文章被收录于专栏:Linyb极客之路Linyb极客之路
运行总次数:0
代码可运行

面向过程设计和面向对象设计的主要区别是:是否在业务逻辑层使用冗长的if else判断。如果你还在大量使用if else,当然,界面表现层除外,即使你使用Java/C#这样完全面向对象的语言,也只能说明你的思维停留在传统的面向过程语言上。

传统思维习惯分析

  为什么会业务逻辑层使用if else,其实使用者的目的也是为了重用,但是这是面向过程编程的重用,程序员只看到代码重用,因为他看到if else几种情况下大部分代码都是重复的,只有个别不同,因此使用if else可以避免重复代码,并且认为这是模板Template模式。

  他范的错误是:程序员只从代码运行顺序这个方向来看待它的代码,这种思维类似水管或串行电路,水沿着水管流动(代码运行次序),当遇到几个分管(子管),就分到这几个分管子在流动,这里就相当于碰到代码的if else处了。

  而使用OO,则首先打破这个代码由上向下顺序等同于运行时的先后循序这个规律,代码结构不由执行循序决定,由什么决定呢?由OO设计;设计模式会取代这些if else,但是最后总是由一个Service等总类按照运行顺序组装这些OO模块,只有一处,这处可包含事务,一般就是Service,EJB中是Session bean。

  一旦需求变化,我们更多的可能是Service中各个OO模块,甚至是只改动Service中的OO模块执行顺序就能符合需求。

  这里我们也看到OO分离的思路,将以前过程语言的一个Main函数彻底分解,将运行顺序与代码其他逻辑分离开来,而不是象面向过程那样混乱在一起。所以有人感慨,OO也是要顺序的,这是肯定的,关键是运行顺序要单独分离出来。

  是否有if else可以看出你有没有将运行顺序分离到家。

设计模式的切入口

  经常有人反映,设计模式是不错,但是我很难用到,其实如果你使用if else来写代码时(除显示控制以外),就是在写业务逻辑,只不过使用简单的判断语句来作为现实情况的替代者。

   还是以大家熟悉的论坛帖子为例子,如ForumMessage是一个模型,但是实际中帖子分两种性质:主题贴(第一个根贴)和回帖(回以前帖子的帖子),这里有一个朴素的解决方案: 建立一个ForumMessage,然后在ForumMessage加入isTopic这样判断语句,注意,你这里一个简单属性的判断引入,可能导致你的程序其他地方到处存在if else 的判断。

  如果我们改用另外一种分析实现思路,以对象化概念看待,实际中有主题贴和回帖,就是两种对象,但是这两种对象大部分是一致的,因此,我将ForumMessage设为表达主题贴;然后创建一个继承ForumMessage的子类ForumMessageReply作为回帖,这样,我在程序地方,如Service中,我已经确定这个Model是回帖了,我就直接下溯为ForumMessageReply即可,这个有点类似向Collection放入对象和取出时的强制类型转换。通过这个手段我消灭了以后程序中if else的判断语句出现可能。

  从这里体现了,如果分析方向错误,也会导致误用模式。

  讨论设计模式举例,不能没有业务上下文场景的案例,否则无法决定是否该用模式

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
main() {
ifcase A{

//do with strategy A

}else(case B){

//do with strategy B

}else(case C){

//do with strategy C

}

}

 这段代码只是纯粹的代码,没有业务功能,所以,在这种情况下,我们就很难确定使用什么模式,就是一定用策略模式等,也逃不过还是使用if else的命运,设计模式不是魔法,不能将一段毫无意义的代码变得简单了,只能将其体现的业务功能更加容易可拓展了。

业务逻辑是我们使用设计模式的切入点,而在分解业务逻辑时,我们习惯则可能使用if else来实现,当你有这种企图或者已经实现代码了,那么就应该考虑是否需要重构Refactoring了。

if else替代者

  那么实战中,哪些设计模式可以替代if else呢?其实GoF设计模式都可以用来替代if else,我们分别描述如下:

  • 状态模式    当数据对象存在各种可能性的状态,而且这种状态将会影响到不同业务结果时,那么我们就应该考虑是否使用状态模式,当然,使用状态模式之前,你必须首先有内存状态这个概念,而不是数据库概念,因为在传统的面向过程的/面向数据库的系统中,你很难发现状态的,从数据库中读取某个值,然后根据这个值进行代码运行分流,这是很多初学者常干的事情。   使用传统语言思维的情况还有:使用一个类整数变量标识状态:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Order{

private int status;

//说明:

//status=1 表示订货但为查看 ;

//status=2 表示已经查看未处理;

//status=3 表示已经处理未付款

//status=4 表示已经付款未发货

//status=5 表示已经发货

}
  • 上述类设计,无疑是将类作为传统语言的函数来使用,这样导致程序代码中存在大量的if else。
  • 策略模式    当你面临几种算法或者公式选择时,可以考虑策略模式,传统过程语言情况是:从数据库中读取算法数值,数值1表示策略1,例如保存到数据库;数值为2表示策略2,例如保存到XMl文件中。这里使用if else作为策略选择的开关。
  • command模式    传统过程的思维情况是:如果客户端发出代号是1或"A",那么我调用A.java这个对象来处理;如果代号是2或"B",我就调用B.java来处理,通过if else来判断客户端发送过来的代码,然后按事先约定的对应表,调用相应的类来处理。
  • MVC模式    MVC模式的传统语言误用和Command模式类似,在一个Action类中,使用if else进行前后台调度,如果客户端传送什么命令;我就调用后台什么结果;如果后台处理什么结构,再决定推什么页面,不过,现在我们使用Struts/JSF这样MVC模式的框架实现者就不必范这种低级错误。
  • 职责链模式    职责链模式和Command模式是可选的,如果你实在不知道客户端会发出什么代号;也没有一个事先定义好的对照表,那么你只能编写一个个类去碰运气一样打开这个包看一下就可以。
  • 代理或动态代理模式    代理对象可以是符合某种条件的代表者,比如,权限检验,传统面向过程思维是:当一个用户登陆后,访问某资源时,使用if else进行判断,只有某种条件符合时,才能允许访问,这样权限判断和业务数据逻辑混乱在一起,使用代理模式可以清晰分离,如果嫌不太好,使用动态代理,或者下面AOP等方式。
  • AOP或Decorator模式   其实使用filter过滤器也可以替代我们业务中的if else,过滤器起到一种过滤和筛选作用,将符合本过滤器条件的对象拦截下来做某件事情,这就是一个过滤器的功能,多个过滤器组合在一起实际就是if else的组合。   所以,如果你实在想不出什么办法,可以使用过滤器,将过滤器看成防火墙就比较好理解,当客户端有一个请求时,经过不同性质的防火墙,这个防火墙是拦截端口的;那个防火墙是安全检查拦截等等。过滤器也如同红蓝白各种光滤镜;红色滤镜只能将通过光线中的红色拦截了;蓝色滤镜将光线中的蓝色拦截下来,这实际上是对光线使用if else进行分解。

  如图,通过一个个条件过滤器我们立体地实现了对信号的分离,如果你使用if else,说明你是将图中的条件1/2/3/4合并在一起,在同一个地方实现条件判断。

  • OO设计的总结

  还有一种伪模式,虽然使用了状态等模式,但是在模式内部实质还是使用if else或switch进行状态切换或重要条件判断,那么无疑说明还需要进一步努力。更重要的是,不能以模式自居,而且出书示人。

  真正掌握面向对象这些思想是一件困难的事情,目前有各种属于揪着自己头发向上拔的解说,都是误人子弟的,所以我觉得初学者读Thinking in Java(Java编程思想)是没有用,它试图从语言层次来讲OO编程思想,非常失败,作为语言参考书可以,但是作为Java体现的OO思想的学习资料,就错了。

  OO编程思想是一种方法论,方法论如果没有应用比较,是无法体会这个方法论的特点的,禅是古代一个方法论,悟禅是靠挑水砍柴这些应用才能体会。

  那么OO思想靠什么应用能够体会到了?是GoF设计模式,GoF设计模式是等于软件人员的挑水砍柴等基本活,所以,如果一个程序员连基本活都不会,他何以自居OO程序员?从事OO专业设计编程这个工作,如果不掌握设计模式基本功,就象一个做和尚的人不愿意挑水砍柴,他何以立足这个行业?早就被师傅赶下山。

  最后总结:将if else用在小地方还可以,如简单的数值判断;但是如果按照你的传统习惯思维,在实现业务功能时也使用if else,那么说明你的思维可能需要重塑,你的编程经验越丰富,传统过程思维模式就容易根深蒂固,想靠自己改变很困难;建议接受专业头脑风暴培训。

  用一句话总结:如果你做了不少系统,很久没有使用if else了,那么说明你可能真正进入OO设计的境地了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-08-31,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Linyb极客之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
WGCNA仅仅是划分基因模块,其它都是附加分析
曾老师给我分享了一篇数据挖掘的文章,里面的WGCNA非常奇怪,我之前没见过这样的模块与表型的相关性热图
生信技能树
2023/09/04
1.6K0
WGCNA仅仅是划分基因模块,其它都是附加分析
三种转录组差异分析方法及区别你会了吗?
在做项目时,曾有小伙伴对我用edgeR进行差异分析筛选出的具体显著差异基因表示质疑,因为发表的文章清楚的说明某个基因是差异基因,但是我edgeR的分析结果并没有表明。在小伙伴的质疑下,我认真看了下文章,发现文章用的是DEseq2进行差异分析。值得注意的是该小伙伴关注的差异基因是一个离散比较大的基因,此处的离散较大可以理解为假定对照组为5,6,7;实验组则为14,13,3的情况。那为什么这个基因在edgeR分析下不是显著差异基因,然而在DEseq2的分析下是差异基因呢?这应该很大程度源于算法判定显著差异基因的区别。接着,我看了关于DEseq2与edgeR区别的描述,发现「edgeR与Deseq2都是基于负二项分布模型做的,两者处理同一组数据时,相同阈值处理大部分基因是一样的,但是也会有一部分基因会因为离散度不同导致差异不同」,如刚刚示例的基因离散度被DEseq2识别为差异,但是不被edgeR识别,所以两种算法获取的差异基因与数目是存在细微区别的。
生信菜鸟团
2022/10/31
6.2K1
三种转录组差异分析方法及区别你会了吗?
GEO数据挖掘之转录组测序数据流程-以GSE150392为例
这个包里可以画pca, 热图,火山图,韦恩图,具体每个图的算法,可以看生信技能树GEO芯片分析
生信技能树
2022/06/08
2.7K1
GEO数据挖掘之转录组测序数据流程-以GSE150392为例
比较不同流程(limma/voom,edgeR,DESeq2 )差异分析的区别
距离第一次听说生信已经十几年了,现在是邋遢大叔重新开始学代码,精力确实已不像从前,各位入坑还是要乘早。后来约莫在5年前,课题组当时有个RNA-Seq数据,lab meeting时听瑞典小哥在汇报DEGs筛选,当时感觉好是神奇。其实陆陆续续也有过学习的念头,但在对自己的各种纵容下,想法又逐渐隐没。直到2月前,机缘巧合参加了生信技能树培训,才进一步强化了自己学习生信技术的信念。
生信技能树
2021/01/05
5.3K0
初探mRNA、lncRNA联合分析之下游
虽然这个项目是在转录本水平上开展的研究,但既然我们拿到了基因表达矩阵,也干脆看一看一些基本情况,这个部分代码此处省略,基本上和后面的转录本水平对应代码,包括使用的封装函数,是一致的
生信菜鸟团
2023/08/23
8540
初探mRNA、lncRNA联合分析之下游
转录组差异分析—基本流程
读取RawCounts.csv文件,其文件形式如下图行名为ensembleid,列名为样本名称。
sheldor没耳朵
2024/07/29
3260
转录组差异分析—基本流程
GEO多数据集联合分析-文献复现
文献题目:基于生物信息学的新型铁死亡基因生物标志物和免疫浸润谱在糖尿病肾病中的应用Huang, Y., & Yuan, X. (2024). Novel ferroptosis gene biomarkers and immune infiltration profiles in diabetic kidney disease via bioinformatics. FASEB journal : official publication of the Federation of American Societies for Experimental Biology, 38(2), e23421. https://doi.org/10.1096/fj.202301357RR. IF: 4.8 Q1
用户11008504
2024/05/11
4902
TCGA数据整理-3
生信菜鸟团
2024/07/11
1600
TCGA数据整理-3
一起画个圈圈看差异基因
最近朋友看论文,看到了个展示差异基因的好看图,说想给自己的差异基因也来画一个,我研究了下,实现挺简单,现成的R包circlize 就可以做,那我们就一起来画一个圈圈吧!
生信菜鸟团
2022/04/08
1.1K0
一起画个圈圈看差异基因
并不需要得到去批次后的表达量矩阵
但是很多人理解的"去批次效应"(batch effect removal)这个操作应该是会输入一个表达量矩阵,然后输出一个表达量矩阵。其实在单细胞转录组数据分析里面并不是这样的,比如我们常见的harmony操作,它针对的就并不是原始的单细胞转录组表达量矩阵(几万个基因几万个细胞),而是pca分析结果(还是几万个细胞但是只有少量的pc)。这样的话,harmony操作后并没有修改我们的原始的单细胞转录组表达量矩阵,这一点可能会确实是让大家困惑。
生信技能树
2024/05/06
3380
并不需要得到去批次后的表达量矩阵
指定通路绘制gsea图热图和火山图
但是我们直接是对gsea分析结果的最终es值在可视化,所以是行是通路,列是癌症的,数值是gsea的es打分的矩阵。对初学者来说, 跳过了大量细节,所以跟这个教程会比较吃力,有粉丝就提问了希望可以对这些通路在在具体的癌症里面细化展示,比如绘制gsea图,热图和火山图。
生信技能树
2022/07/26
2.6K0
指定通路绘制gsea图热图和火山图
生信技能树GEO数据挖掘直播配套笔记
二代测序(RNA_seq):如果是counts 可选择limma的voom算法或者edgeR或者DESeq2。 如果是FPKM或TPM可选择limma,注意:edgeR和DESeq2只能处理count注意:count做差异分析计算上下调,FPKM或TPM进行下游可视化
生信技能树
2022/06/08
2.1K0
生信技能树GEO数据挖掘直播配套笔记
两分组差异分析的上下调基因跟PCA分析的主成分基因的交集如何
学员提出来了一个很有意思的问题, 就是表达量矩阵质量控制环节里面的PCA分析,可以看出来不同样品在二维图里面的距离,其中PC1是可以区分两个分组,如下所示:
生信技能树
2023/09/04
5770
两分组差异分析的上下调基因跟PCA分析的主成分基因的交集如何
生信技能树——GEO转录组RNA_seq_GSE162550
和生信技能树GEO转录组“GSE150392“分析类似,唯一区别就是在数据处理和ID转换这一环节略微有区别
生信技能树
2022/06/08
1.9K0
生信技能树——GEO转录组RNA_seq_GSE162550
GEO数据库中芯片数据分析思路
AnnoProbe是曾建明老师2020年开发的一款用于下载GEO数据集并注释的R包,收录在tinyarray里。 idmap##根据所给的GPL号,返回探针的注释 geoChina##根据所给的GSE号,下载对应的表达矩阵 annoGene##根据gencode中的GTF文件注释基因ID
小张小张
2023/05/25
2.1K0
TCGA数据库LUSC亚型批量差异分析
作业参考的文献:Integrated analysis reveals five potential ceRNA biomarkers in human lung adenocarcinoma
生信技能树
2020/03/11
1.7K0
基于count数据的基因差异表达分析万能代码
关于差异分析的文章中【一文就会TCGA数据库基因表达差异分析】其实有推送过,这篇文章目前为止,有近千人付费学习。
DoubleHelix
2022/06/13
4K0
基于count数据的基因差异表达分析万能代码
转录组测序结果分析
#没有任何提示就是成功了,如果有warningxx包不存在,用library检查一下。
叮当猫DDM
2024/03/19
3421
GEO数据库挖掘
输入数据是数值型矩阵/数据框,颜色的变化表示数值的大小。有相关性热图和差异基因热图。
叮当猫DDM
2023/07/16
8831
简单快速的GEO差异基因选取和绘制火山图
做GEO数据挖掘,有的时候,我们不需要做严格的分析,只想快速拿到差异基因,和简单的一张火山图。用来辅助其他的分析,如网络药理学,可以用以下的代码
sheldor没耳朵
2025/03/26
1740
简单快速的GEO差异基因选取和绘制火山图
推荐阅读
相关推荐
WGCNA仅仅是划分基因模块,其它都是附加分析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验