Whip Monstrous Code Into Shape 12-Too Many Method Parameters is a Sign

分享 oustn ⋅ 于 2016-12-23 20:22:49 ⋅ 最后回复由 JokerLinly 2016-12-24 09:53:05 ⋅ 439 阅读

As a general guideline, when you find yourself wanting to create a method with four or more parameters, that might be an indication that there's a missing class. You may want to refactor. As always, rules are meant to be broken, but, nonetheless, train yourself to be suspicious of such methods.


这个视频讲的是避免方法中有过多的参数。

一般来说,方法中最好保持最多三个参数,方法中有三个以上参数的时候就要考虑是不是应该用一个类来替代。类(class)本质上是一种自定义的类型(type)。创建一个类,就是创建了一种新的类型,具有特定的外观与行为。

参数过多带来的问题显而易见。首先是违背职责单一原则,通常参数过多的很大一个原因就是添加了各种“表示参数”,比如 boolean 的值,或者类似于 $type 的变量。这些参数的加入仿佛在宣告“本函数干的事可不止一件”,随之而来的就是方法中各种的if 判断,这种情况下还不如把不同情况分拆成不同的方法。

另外一个情况参数过多带来的逻辑层级混乱,本来不同层级的逻辑随着参数加入都掺合在一起。

另外参数过多对于测试来说是很大的麻烦,你必须模拟不同参数的组合情况并做相应的测试;在调用的时候也可能出错,参数过多导致调用的时候需要一个一个参数好好对应。

想象一个情景,有一个 compress(打包) 方法,用来给样式文件打包。

function compress($file, $destination)
{
    // todo ...
}

开始只有两个参数,只能针对 css 文件打包。随着项目进展,这个方法被扩展到不仅可以针对css 打包,也可以针对 js 文件打包,所以代码就进化成这个样子:

function compress($file, $fileType, $destination, $compressor)
{
    if ($fileType == 'css') {
        // todo ...
    }
    if ($fileType == 'js') {
        if ($compressor) {
            // todo ...
        } else {
            // todo ...
        }
    }
}

随着参数的增多,这个方法的职责也变多,要判断文件类型,要选择不同的压缩工具,要处理压缩。。。

这个时候就要考虑把有些参数封装到一个类中。compress 的职责就是压缩文件,而文件本身的类型以及对应的压缩工具可以是一种“类型(type)”,也就是可以创建一个对应的类。

interface CompressionStrategy
{
    public function compress();
}

class JavascriptStrategy implements CompressionStrategy
{
    private $file;

    private $destination;

    private $compressor;

    public function __construct($file, $destination)
    {

        $this->file = $file;
        $this->destination = $destination;
    }

    public function compress()
    {
        // TODO: ...
    }
}

class CssStrategy implements CompressionStrategy
{
    private $destination;

    private $file;

    private $compressor;

    public function __construct($file, $destination)
    {

        $this->destination = $destination;
        $this->file = $file;
    }

    public function compress()
    {
        // TODO: ...
    }
}

这个时候 compress 方法就很简单了,层级的逻辑也很清楚,就是调用一个可压缩的文件的压缩方法而已。

function compress(CompressionStrategy $strategy)
{
    $strategy->compress();
    // ....
}

而且通过类型上溯你可以随意的添加更多的类型,只要实现了 CompressionStrategy 接口。

Oustn

本帖已被设为精华帖!
本帖由 Summer 于 3周前 加精
回复数量: 3
暂无评论~~
  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
Ctrl+Enter