资讯专栏INFORMATION COLUMN

代码重构之消除分支结构

Markxu / 655人阅读

摘要:一为什么要消除当写下第一行时就为发展成几十个埋下了伏笔当一个有可能臃肿时那么它一定会臃肿墨菲一个例子看起来非常美妙简洁但是当系统慢慢复杂化角色不断的丰富就变成这样的代码来个极端的例子可以说非常可怕了二如何消除消除这种条件里都是

一. 为什么要消除 if-else

当写下第一行 if-else 时,就为发展成几十个 if-else 埋下了伏笔.

当一个 if-else 有可能臃肿时,那么它一定会臃肿.  --墨菲

一个例子:

$userType = "";
if ($userTypeID == 1){
    $userType = "Admin";
}elseif($userTypeID == 2){
    $userType = "Corporate Customers";
}

看起来非常美妙,简洁.但是当系统慢慢复杂化,角色不断的丰富,就变成这样的代码:

$userType = "";
if ($userTypeID == 1){
    $userType = "Admin";
}elseif($userTypeID == 2){
    $userType = "Corporate Customers";
}elseif($userTypeID == 3){
    $userType = "Editorial Users";
}elseif($userTypeID == 4){
    $userType = "Photographers";
}elseif($userTypeID == 5){
    $userType = "Vendors";
}

来个极端的例子:

可以说非常可怕了.

二. 如何消除 if-else

消除这种条件里都是定值的 if-else 我们可以采用 查表法 来消除.

通过容器将对应的关系进行存储。通过运算得出相应关系中的其中一方的结果,再通过这个结果去容器中找对应的另一个内容

通俗的说,就是建立一个对象或者数组的 hash 表, key 值存储条件判断, value 存储符合该条件判断的逻辑处理.
比如上面的代码可以写成:

  const USER_TYPE_ADMIN = 1;
  const USER_TYPE_CORPORATE = 2;
  const USER_TYPE_EDITORIAL = 3;
  const USER_TYPE_PHOTOGRAPHERS = 4;
  const USER_TYPE_VENDORS = 5;

  public function getUserTypeName($key = null){
    $data = array(
      self::USER_TYPE_ADMIN => "Admin",
      self::USER_TYPE_CORPORATE => "Corporate Customers",
      self::USER_TYPE_EDITORIAL => "Editorial Users",
      self::USER_TYPE_PHOTOGRAPHERS => "Photographers",
      self::USER_TYPE_VENDORS => "Vendors",
    );
    return $key === null ? $data : (isset($data[$key]) ? $data[$key] : "");
  }

这样,上面的一大段的 if-else 就一行代码搞定: $userType = User::getUserTypeName($userTypeID)

用 JavaScrip 语言来描述:

let userTypeObj = {
    1: "Admin",
    2: "Corporate Customers",
    3: "Editorial Users",
    4: "Photographers",
    5: "Vendors",
};

let userTypeName = userTypeObj[userTypeID];

上面的例子只是不同的 userTypeID 获取不同的 userTypeName. 考虑更复杂的情况,当不同的 userTypeID 时进行不同逻辑处理.

if (userTypeID == 1) {
    //Todo ...
} else if(userTypeID == 2) {
    //Todo ...
} else if(userTypeID == 3) {
    //Todo ...
} else if(userTypeID == 4) {
    //Todo ...
}

这个时候可以把里面的逻辑处理代码抽出来为一个函数:

let userTypeObj = {
    1: () => {
        //Todo...
    },
    2: () => {
        //Todo...
    },
    3: () => {
        //Todo...
    },
    4: () => {
        //Todo...
    },
};

userTypeObj[userTypeID]();

以上代码也可以以 php 的可变变量/面向对象的多态特性来实现.

缺点:查表法的实现,要做越界检查,还要确保下标计算不会重复,如果使用面向对象的多态特性来实现,也有策略类增多等问题.

这个查表法的实现,其实是策略模式的思想.

策略模式指的是定义一系列的算法,把他们一个个的封装起来.策略模式的目的就是将算法的使用与算法的实现分离开来.

更多关于策略模式的讲解,请看这里

三. 总结

if-else 当然是有用的,比如 mysql 链接, curl 的返回码等等.当开始写的时候,只有一个 if-else ,我们可以不去消除,但是当要写到第三个第四个分支,或者每个条件分支里面都有大段大段的逻辑处理代码,我们就要考虑消除它了.

当条件语句不是定值,而是范围值的时候,如何消除 if-else 求教:

if(x < 30){
    //todo
}else if(x >= 30 ){
    //todo
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/29648.html

相关文章

  • 代码重构消除分支结构

    摘要:一为什么要消除当写下第一行时就为发展成几十个埋下了伏笔当一个有可能臃肿时那么它一定会臃肿墨菲一个例子看起来非常美妙简洁但是当系统慢慢复杂化角色不断的丰富就变成这样的代码来个极端的例子可以说非常可怕了二如何消除消除这种条件里都是 一. 为什么要消除 if-else 当写下第一行 if-else 时,就为发展成几十个 if-else 埋下了伏笔. 当一个 if-else 有可能臃肿时,那么...

    littlelightss 评论0 收藏0
  • React 单元测试策略及落地

    摘要:写好的单元测试,对开发速度项目维护有莫大的帮助。我认为单元测试的上下文存在于敏捷中。接下来一小节,就可以正式进入如何做的环节了如何写好单元测试。前面说到,我们对单元测试寄予 写好的单元测试,对开发速度、项目维护有莫大的帮助。前端的测试工具一直推陈出新,而测试的核心、原则却少有变化。与产品代码一并交付可靠的测试代码,是每个专业开发者应该不断靠近的一个理想之地。本文就围绕测试讲讲,为什么我...

    nifhlheimr 评论0 收藏0
  • js数据结构-二叉树(二叉堆)

    摘要:二叉树二叉树是一种树形结构,它的特点是每个节点最多只有两个分支节点,一棵二叉树通常由根节点,分支节点,叶子节点组成。 二叉树 二叉树(Binary Tree)是一种树形结构,它的特点是每个节点最多只有两个分支节点,一棵二叉树通常由根节点,分支节点,叶子节点组成。而每个分支节点也常常被称作为一棵子树。 showImg(https://segmentfault.com/img/bVbmEd...

    ningwang 评论0 收藏0
  • 重构---改善既有代码的设计》

    摘要:为何重构重构有四大好处重构改进软件设计如果没有重构,程序的设计会逐渐腐败变质。经常性的重构可以帮助维持自己该有的形态。你有一个大型函数,其中对局部变量的使用使你无法采用。将这个函数放进一个单独对象中,如此一来局部变量就成了对象内的字段。 哪有什么天生如此,只是我们天天坚持。 -Zhiyuan 国庆抽出时间来阅读这本从师傅那里借来的书,听说还是程序员的必读书籍。 关于书的高清下载连...

    baihe 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<