zoukankan      html  css  js  c++  java
  • 代码简洁之二:函数只做一件事儿

    函数应该做一件事。做好这件事。只做这一件事。

    所以我们简化代码的一个简单方式就是不断拆分函数(Extract Method),一直拆分,拆分到不能再分出一个函数为止。

    拆函数的过程就是一个概括目的、步骤,提取抽象层次动名词的过程。不要做只是解释代码的简单概括,要让函数中的语句处于一个相同抽象层次,如果是更细节的事儿,请再进一步拆分出一个函数出来。
    让代码拥有自顶向下的阅读顺序。

    以我之前写的一个列表显示的action(MVC框架里面的某个控制器里面的一个方法),最开始代码是这样的:

    // 接收查询的参数
    $minDate = trim($this->input->get_post('startDate', true));
    $maxDate = trim($this->input->get_post('endDate', true));
    $gameId = trim($this->input->get_post('gameId', true));
    $adPositionId = trim($this->input->get_post('adPositionId', true));
    $orderField = trim($this->input->get_post('orderField', true));
    $order = trim($this->input->get_post('order', true));
    $page = intval($this->input->get_post('page', true));
    $pageSize = intval($this->input->get_post('pageSize', true));
    
    if (!$order || !in_array($order, array('asc', 'desc'))) {
        $order = 'desc';
    }
    
    if (!$orderField || !isset($this->_fieldsMappingArray[$orderField])) {
        $searchParam['sort_by'] = 'date';
    } else {
        $searchParam['sort_by'] = $this->_fieldsMappingArray[$orderField];
    }
    
    if (!$minDate) {
        $minDate = date('Y-m-d', strtotime('-1 day'));
    }
    
    if (!$maxDate) {
        $maxDate = date('Y-m-d');
    }
    
    if (strtotime($minDate)) {
        $searchParam['minDate'] = strtotime($minDate . ' 00:00:00');
    }
    
    if (strtotime($maxDate)) {
        $searchParam['maxDate'] = strtotime($maxDate . ' 23:59:59');
    }
    // .......一系列的判断
    
    // 开始调用查询
    $this->load->model('webgame_model');
    $result = $this->webgame_model->getStatisData();
    // 一系列组装数据
    $this-view('users/webgameStatisList.php', $data);

    这些代码写得很”质朴“,但是也很冗余,在这个function里面干了太多的事儿,杂乱无章,随着传入参数越来越多,接收部分和处理部分的代码会越来越长。虽然我不想轻易的狗带,但是容我做一个悲伤的表情,好么?
    而且其实很多列表的action都是类似的,完全可以封装一些公共处理的方法,让代码抽象层次变得低一些,最终落地。

    不过,首先我们得整理一下思路和步骤,把思路写越详细越好,细到不能再分出一个步骤。我借鉴《代码简洁之道》里面的建议,用TO 的那种引导方式来梳理。

    1.要获取查询结果,先拿处理查询参数,然后再判断参数合法性,然后再进行查询。 (这是最大的思路步骤)
    2.要处理查询参数,要先拿到传过来的参数做一些逻辑处理。 ---->getSearchFileds()
    3.要判断参数合法性,要进行一系列业务逻辑的判断,最后返回错误信息,统一处理。 ----> checkParam()
    4.要进行查询获取结果,要先把引入model,然后处理组装数据,最后返回。把所有组装细节都放在查询获取里面。 ----> _searchWebGameStatis()
    最终代码简化如下:

    // 接收处理查询参数
    $params = $this->getSearchFileds($this->searchFiledOptions, $_REQUEST);
    
    // 判断参数合法性
    if ($tips = $this->checkParam()) {
        $this->message->tips($tips);
    }
    
    // 查询获取游戏统计数据
    $statis = $this->_searchWebGameStatis($params);
    
    $statis['searchs'] = $params;
    
    // 其他导航信息组装
    $this->template->cpView('users/webGameStatis', $statis);

    关于getSearchFieds等的内部实现等,因为每个人的思路不同,我就不细表了。(以后单独开一篇文章细表也可以哒)但是整个简化思路就是这样。

    当我们明确自己的目标和单一职责的步骤,世界都给我们让步。好的代码就是每一行都是函数的调用,而函数都只做一件事儿。读代码就像读一篇短小的文章,简单易懂,出了任何问题,责任链明确,直接去找那个function就好了。


    古人没有骗我:不积跬步无以至千里。

  • 相关阅读:
    HDU5643-King's Game
    KM算法详解+模板
    二分图最大匹配(匈牙利算法)
    二分图判断(交叉染色)
    能被2、3、4、5、6、7、8、9 等数整除的数的特征
    Codeforces Round #306 (Div. 2) ABCDE(构造)
    HDU5627--Clarke and MST (bfs+位运算)
    Educational Codeforces Round 82 (Rated for Div. 2)
    2020 CCPC Wannafly Winter Camp Day5
    Codeforces Round #618 (Div. 2)
  • 原文地址:https://www.cnblogs.com/freephp/p/5094979.html
Copyright © 2011-2022 走看看