PHP 代码简洁之道——函数部分(二)

教程 shanhuhai 5114℃ 2评论

接上一篇PHP 代码简洁之道——函数部分(一)

8. 不要使用单例模式

(译者注:这一条有些难理解,看不懂就略过吧)

单例模式是一种反模式,Brian Button 的解释:

  1. 单例通常被用做一个全局的实例,为什么不好?因为你在代码中隐藏了依赖,而不是通过接口暴露他们。通过将一些东西放到全局来避免传递他们是一种“代码异味(code smell)”

code smell 是指能够被开发者察觉到的不好的形式

  1. 它违反了 SPR原则(single responsibility principle): 由它自己控制自己的创建和生命周期
  2. 它本身就导致了代码的紧耦合。大多数情况下这使得通过伪造数据来测试变的相当困难。

不好的

class DBConnection
{
    private static $instance;

    private function __construct($dsn)
    {
        // ...
    }

    public static function getInstance()
    {
        if (self::$instance === null) {
            self::$instance = new self();
        }

        return self::$instance;
    }

    // ...
}

$singleton = DBConnection::getInstance();

好的:

class DBConnection
{
    public function __construct(array $dsn)
    {
        // ...
    }

     // ...
}

创建 DBConneciton 的实例,并配置 DSN

这样你就可以在你的应用程序中使用 DBConnection 的实例了。

9 封装条件判断

不好的:

if ($article->state === 'published') {
    // ...
}

好的:

if ($article->isPublished()) {
    // ...
}

避免否定类型的判断

不好的:


function isDOMNodeNotPresent($node) { // ... } if (!isDOMNodeNotPresent($node)) { // ... }

好的


function isDOMNodePresent($node) { // ... } if (isDOMNodePresent($node)) { // ... }

10. 避免条件判断

这似乎是一个不可能完成的任务。人们会问“如果不用 if 语句我该怎么做?”,答案是在许多情况下,你可以用多态来实现同样的效果。你可能还会问“这样有什么好处?”,答案是我们之前提到的原则:“一个函数应该只做一件事”, 当你的类或函数中有了 if 语句,相当于告诉别人你的函数做了一件以上的事情。

不好的:

class Airplane
{
    // ...

    public function getCruisingAltitude()
    {
        switch ($this->type) {
            case '777':
                return $this->getMaxAltitude() - $this->getPassengerCount();
            case 'Air Force One':
                return $this->getMaxAltitude();
            case 'Cessna':
                return $this->getMaxAltitude() - $this->getFuelExpenditure();
        }
    }
}


好的:


interface Airplane { // ... public function getCruisingAltitude(); } class Boeing777 implements Airplane { // ... public function getCruisingAltitude() { return $this->getMaxAltitude() - $this->getPassengerCount(); } } class AirForceOne implements Airplane { // ... public function getCruisingAltitude() { return $this->getMaxAltitude(); } } class Cessna implements Airplane { // ... public function getCruisingAltitude() { return $this->getMaxAltitude() - $this->getFuelExpenditure(); } }

11. 避免类型检查(第一部分)

PHP是弱类型语言,意味着你的函数可以接收任何类型的参数。有时你会因为这点自由而受害,这时你可能会在函数中检查参数类型,有许多途径可以避免在函数能做类型检查,首先要做的是有一致的接口。

不好的


function travelToTexas($vehicle) { if ($vehicle instanceof Bicycle) { $vehicle->peddleTo(new Location('texas')); } elseif ($vehicle instanceof Car) { $vehicle->driveTo(new Location('texas')); } }

好的:

function travelToTexas(Traveler $vehicle)
{
    $vehicle->travelTo(new Location('texas'));
}

避免类型检查(第二部分)

如果现在要处理的是基础数据类型,像字符串,整型和数组。现在如果你用的 PHP7以上的版本,而且现在很明显你也不能用多态。现在你应该考虑使用类型检查或者严格模式,它使你能够在php语法层面提供静态类型检查。手动判断类型的问题是,你需要添加许多额外的代码,你获得的人造的“类型安全”抵不过你代码可读性的损失。

不好的


function combine($val1, $val2) { if (!is_numeric($val1) || !is_numeric($val2)) { throw new \Exception('Must be of type Number'); } return $val1 + $val2; }

好的

function combine(int $val1, int $val2)
{
    return $val1 + $val2;
}

12.移除废弃的代码

废弃的代码跟重复的代码一样不好,没有理由在你的代码库继续保留他们,如果你想找回他们,到版本历史中找回就行了。

不好的

function oldRequestModule($url)
{
    // ...
}

function newRequestModule($url)
{
    // ...
}

$request = newRequestModule($requestUrl);
inventoryTracker('apples', $request, 'www.inventory-awesome.io');

好的



function requestModule($url) { // ... } $request = requestModule($requestUrl); inventoryTracker('apples', $request, 'www.inventory-awesome.io');

转载请注明:大后端 » PHP 代码简洁之道——函数部分(二)

付费咨询
喜欢 (7)or分享 (0)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(2)个小伙伴在吐槽
  1. 请问博主,避免否定类型的判断那一条怎么理解呢 ? 以前写的习惯都是先判断否定条件的
    jeffrey2017-10-01 08:56 回复
    • 肯定的代码阅读起来相对轻松一些
      shanhuhai2017-10-15 13:27 回复