前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式(07)——设计原则(2)

设计模式(07)——设计原则(2)

作者头像
huofo
发布2022-03-17 09:54:47
2700
发布2022-03-17 09:54:47
举报
文章被收录于专栏:huofo's blog

KISS原则

Keep It Simple and Stupid 这个原则听起来比较简单,重点是理解什么样的代码是简单的,代码行数少就是简单的代码吗???还是说当程序的逻辑十分复杂不容易理解时就是一个复杂的代码呢???

下面就让我们来看看怎么样判断简单。

代码行数

代码就不展示了,其实懂的都懂,代码行数是一定不能作为判断依据的,因为很多代码行数少的代码,其实是采用了一些高级语法特性的。如正则表达式、位运算符等。

如果盲目的采用这些特性,会影响代码的可读性,因为这种运算法为了减少代码行数,会采用很多方式来规定一些特性,这些特性有时会不好理解。例如用位运算符来代替算数运算,这样虽然会提高代码性能和减少行数,但也不是 KISS 原则下的指导产物,其违反了代码的可读性。

逻辑复杂

那代码的逻辑复杂可以作为判断依据吗?其实也是懂的都懂,代码也不展示了(因为太复杂了,所以不展示了-v-),为什么逻辑复杂不能作为判断依据呢???

因为有些代码他就是逻辑复杂的,如果不信的话,直接打开算法相关实现,找到一个看不懂的,那么其就是我们的目标了。

因此如果没办法,在特定场景下,只能采用该算法的实现,那么使用这种复杂逻辑就不是违反 KISS 原则了,因为没办法。

场景

综上,我们该如何写出符合 KISS 原则的代码呢,具体来说,还是需要 结合业务发展和技术团队能力。

在实际场景下,我们尽量做到以下几点就可以了。

  • 不使用同事可能不懂的语法和技术,例如 lambda、正则等(不过这些还好,例如 lambda 虽然有些时候部分地方还不让使用,但其实其早已不是一个新技术了,还不懂的话,这种情况可以考虑换个地方或者进行下部门培训了)
  • 不要重复造轮子,因为自己造的轮子在一定程度上肯定没有网上大家都用的好,比较容易出现问题,而这些问题可能在对应的轮子上已经被解决来(但自己学习的时候,该造还是要造)
  • 不要过度优化,炫技,例如为了提高性能和减少代码行数,使用大量的位运算符、复杂的条件表达式等,这些都是给机器看的,一般我们都不需要在这个性能上过分的优化,反而牺牲来代码的可读性

YAGNI原则

定义

不要去设计当前用不到的功能,不要去写当前用不到的代码。

该原则是作为一个指导思想来做的,其作用就是防止过度设计,但需要注意的是其是让你不做,但需要有可能要做的意识,提前留好拓展点,这样如果要做的时候,也可以快速跟上。 **

后续会有一篇文章,来专门讲解如何在软件设计中,防止过度设计,但对对应该优化,该留好优化点如何实现。

DRY原则

定义

英语解释为:Dont repeat yourself,可以理解为不要写重复的代码,要做好代码的可复用性。但该规则跟 KISS 原则一样,听起来可能比较简单,但是在实际使用中,却要注重的一个原则。

因为在该原则中,有一个很关键的点,什么样的代码是重复的代码,只是简单的代码一样就是违反该原则了吗?下面就让我们来根据以下几种场景来判断什么是重复的代码。

实现逻辑重复

代码语言:javascript
复制
 public boolean validUsername(String username) {
        if (StrUtil.isEmpty(username)) {
            return false;
        }
        if (username.contains("77777")) {
            return false;
        }
        return true;
    }

    public boolean validNickname(String nickname) {
        if (StrUtil.isEmpty(nickname)) {
            return false;
        }
        if (nickname.contains("77777")) {
            return false;
        }
        return true;
    }

我们来看一下,这一段代码是重复的吗?

明显能看出,两个方法的执行逻辑是一模一样的,那么我们可以说其是重复的,而将其合为一个方法吗?

答案是不行的,首先如果合成一个就违反了单一职责原则,一个方法做了多件事,此外,现在两个参数的校验逻辑是一样的,因此看着重复,后面如果 nickname 的校验逻辑改了呢?那就需要侵入式的修改代码,需要在所有使用该方法的代码中进行修改,依据 nickname 来特定的进行判断,从而违反了开闭原则。

因此,实现逻辑重复,不能构成代码重复的条件。

功能语义重复

代码语言:javascript
复制
    public boolean checkPasswordByRegex(String password) {
        String regex = "123456";
        boolean matches = Pattern.matches(regex, password);
        return matches;
    }

    public boolean checkPasswordByStr(String password) {
        boolean matches = StrUtil.equals(password, "123456");
        return matches;
    }

我们来看一下,上述两段代码是否构成重复?

答案是这两段代码是重复的代码,虽然这两段代码的实现逻辑不一致,代码编写也不一致,但其仍然违反了 DRY 原则,因为这两段代码所实现的点是一样的,下面我们来看一下这样重复的代码会带来什么隐患。

这样的设计可能会导致以下问题,

  1. 当一个不知情的人看到这两段代码完成的任务是一样的,但采用的解决方式却是不一样的,则会想其的设计深意,以及不知道该用哪一个?
  2. 当函数的实现逻辑要改的时候,可能会导致修改了其中一个,而忘记修改另一个,这样则会造成逻辑的不一致。

代码执行重复

代码语言:javascript
复制
    // 代码执行重复
    public boolean validContainsA(String temp) {
        if (StrUtil.isNotEmpty(temp) && temp.contains("A")) {
            return true;
        }
        return false;
    }

    public boolean validTemp(String temp) {
        if (StrUtil.isNotEmpty(temp) && temp.contains("A")) {
            return true;
        }
        return validContainsA(temp);
    }

上述代码因为举的例子比较简单,应该能很简单的看出有一段代码被执行了两次,那么这样的设计违反了 DRY 原则吗?

我们认为其也是违反的,这里放的只是一个简单的逻辑判断,所以看不出来什么,如果这里是放了一个耗时操作呢,例如读取数据库、文件等。那么进行重复的执行,则会影响整个程序的对外性能。

总结

因此,判断如何一个代码是否是重复的,需要结合具体场景来做判断,在这里,我们可以看到代码实现方式一样不能作为判断依据,因此其实现的语义是不同的,这就是功能语义的判断范畴,而对于重复执行,我们在代码里需要做到尽量避免,因为如果重复执行费时操作,则会导致代码整体对外的性能下降。

迪米特原则

定义

迪米特原则是用来指导设计高内聚、低耦合代码的原则,因此我们先看一下什么是高内聚、低耦合。

  • 高内聚:相近的功能放到一个类或模块中,不相近的功能不要放到一个类中,暗合了单一职责原则;
  • 低耦合:类和类之间的依赖关系清晰简洁,即使有依赖,也要做到其中一个修改,依赖或被依赖的少修改。

看到想要完成的目标,现在再来看一下什么是迪米特原则。

其概念是:每个类或模块只需要了解与他关系密切即紧密关联的类或模块。再换句话说:

  • 不该有依赖关系的不要有依赖;
  • 有依赖关系,只依赖必要的接口。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-12-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • KISS原则
    • 代码行数
      • 逻辑复杂
        • 场景
        • YAGNI原则
          • 定义
          • DRY原则
            • 定义
              • 实现逻辑重复
                • 功能语义重复
                  • 代码执行重复
                    • 总结
                    • 迪米特原则
                      • 定义
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档