Categories: 其他重构

基于 重构 简化条件逻辑 重构条件代码实现

1、现有的实现如下

<?php

namespace Modules\ThemeStoreDB\ThemeSetting;

use Illuminate\Support\Str;

class ThemeVersion
{
    const SPECIAL_IDENTIFIER = '-h.'; // 特殊版本标识
    const HYPHEN = '-'; // 连字符

    public string $semantic;

    function __construct(string $semantic)
    {
        $this->semantic = $semantic;
    }

    /**
     * 对比两个「PHP 规范化」的版本数字字符串,添加例外:-h.
     * @param self $version
     * @return int 在第一个参数小于,等于或大于第二个参数时,该比较函数必须相应地返回一个小于,等于或大于 0 的整数
     */    public function compare(self $version): int
    {
        if (Str::contains($this->semantic, self::SPECIAL_IDENTIFIER) && !Str::contains($version->semantic, self::SPECIAL_IDENTIFIER) && Str::before($this->semantic, self::HYPHEN) == Str::before($version->semantic, self::HYPHEN)) {
            return 1;
        } elseif (!Str::contains($this->semantic, self::SPECIAL_IDENTIFIER) && Str::contains($version->semantic, self::SPECIAL_IDENTIFIER) && Str::before($this->semantic, self::HYPHEN) == Str::before($version->semantic, self::HYPHEN)) {
            return -1;
        } else {
            return version_compare($this->semantic, $version->semantic);
        }
    }

2、参考 10.1 分解条件表达式(Decompose Conditional),调整为如下

<?php

namespace Modules\ThemeStoreDB\ThemeSetting;

use Illuminate\Support\Str;

class ThemeVersion
{
    const SPECIAL_IDENTIFIER = '-h.'; // 特殊版本标识
    const HYPHEN = '-'; // 连字符

    public string $semantic;

    function __construct(string $semantic)
    {
        $this->semantic = $semantic;
    }

    /**
     * 对比两个「PHP 规范化」的版本数字字符串,添加例外:-h.
     * @param self $version
     * @return int 在第一个参数小于,等于或大于第二个参数时,该比较函数必须相应地返回一个小于,等于或大于 0 的整数
     */    public function compare(self $version): int
    {
        if (self::isSpecial($this->semantic) && !self::isSpecial($version->semantic) && self::isMainEqual($this->semantic, $version->semantic)) {
            return 1;
        } elseif (!self::isSpecial($this->semantic) && self::isSpecial($version->semantic) && self::isMainEqual($this->semantic, $version->semantic)) {
            return -1;
        } else {
            return version_compare($this->semantic, $version->semantic);
        }
    }

    /**
     * 返回版本是否是特殊版本
     * @param string $semantic
     * @return bool
     */    private static function isSpecial(string $semantic): bool
    {
        return Str::contains($semantic, self::SPECIAL_IDENTIFIER);
    }

    /**
     * 返回两个版本的主版本号是否相等
     * @param string $semantic1
     * @param string $semantic2
     * @return bool
     */    private static function isMainEqual(string $semantic1, string $semantic2): bool
    {
        return self::getMain($semantic1) == self::getMain($semantic2);
    }

    /**
     * 获取版本的主版本号
     * @param string $semantic
     * @return string
     */    private static function getMain(string $semantic): string
    {
        return Str::before($semantic, self::HYPHEN);
    }
}

3、10.2 合并条件表达式(Consolidate Conditional Expression)。将检查条件提炼成一个独立的函数对于厘清代码意义非常有用,因为它把描述“做什么”的语句换成了“为什么这样做”。



    /**
     * 对比两个「PHP 规范化」的版本数字字符串,添加例外:-h.
     * @param self $version
     * @return int 在第一个参数小于,等于或大于第二个参数时,该比较函数必须相应地返回一个小于,等于或大于 0 的整数
     */    public function compare(self $version): int
    {
        if (self::isSpecialGt($this->semantic, $version->semantic)) {
            return 1;
        } elseif (self::isSpecialLt($this->semantic, $version->semantic)) {
            return -1;
        } else {
            return version_compare($this->semantic, $version->semantic);
        }
    }

    /**
     * 当两个版本中仅存在一个特殊版本时,第一个版本大于第二个版本
     * @param string $semantic1
     * @param string $semantic2
     * @return bool
     */    private static function isSpecialGt(string $semantic1, string $semantic2): bool
    {
        return self::isSpecial($semantic1) && !self::isSpecial($semantic2) && self::isMainEqual($semantic1, $semantic2);
    }

    /**
     * 当两个版本中仅存在一个特殊版本时,第一个版本小于第二个版本
     * @param string $semantic1
     * @param string $semantic2
     * @return bool
     */    private static function isSpecialLt(string $semantic1, string $semantic2): bool
    {
        return !self::isSpecial($semantic1) && self::isSpecial($semantic2) && self::isMainEqual($semantic1, $semantic2);
    }
}

4、10.3 以卫语句取代嵌套条件表达式(Replace Nested Conditional with Guard Clauses)。如果某个条件极其罕见,就应该单独检查该条件,并在该条件为真时立刻从函数中返回。这样的单独检查常常被称为“卫语句”(guard clauses)。

<?php

namespace Modules\ThemeStoreDB\ThemeSetting;

use Illuminate\Support\Str;

class ThemeVersion
{
    const SPECIAL_IDENTIFIER = '-h.'; // 特殊版本标识
    const HYPHEN = '-'; // 连字符

    public string $semantic;

    function __construct(string $semantic)
    {
        $this->semantic = $semantic;
    }

    /**
     * 对比两个「PHP 规范化」的版本数字字符串,添加例外:-h.
     * @param self $version
     * @return int 在第一个参数小于,等于或大于第二个参数时,该比较函数必须相应地返回一个小于,等于或大于 0 的整数
     */    public function compare(self $version): int
    {
        if (self::isSpecialGt($this->semantic, $version->semantic)) {
            return 1;
        }
        if (self::isSpecialLt($this->semantic, $version->semantic)) {
            return -1;
        }

        return version_compare($this->semantic, $version->semantic);
    }

    /**
     * 返回版本是否是特殊版本
     * @param string $semantic
     * @return bool
     */    private static function isSpecial(string $semantic): bool
    {
        return Str::contains($semantic, self::SPECIAL_IDENTIFIER);
    }

    /**
     * 返回两个版本的主版本号是否相等
     * @param string $semantic1
     * @param string $semantic2
     * @return bool
     */    private static function isMainEqual(string $semantic1, string $semantic2): bool
    {
        return self::getMain($semantic1) == self::getMain($semantic2);
    }

    /**
     * 获取版本的主版本号
     * @param string $semantic
     * @return string
     */    private static function getMain(string $semantic): string
    {
        return Str::before($semantic, self::HYPHEN);
    }

    /**
     * 当两个版本中仅存在一个特殊版本时,第一个版本大于第二个版本
     * @param string $semantic1
     * @param string $semantic2
     * @return bool
     */    private static function isSpecialGt(string $semantic1, string $semantic2): bool
    {
        return self::isSpecial($semantic1) && !self::isSpecial($semantic2) && self::isMainEqual($semantic1, $semantic2);
    }

    /**
     * 当两个版本中仅存在一个特殊版本时,第一个版本小于第二个版本
     * @param string $semantic1
     * @param string $semantic2
     * @return bool
     */    private static function isSpecialLt(string $semantic1, string $semantic2): bool
    {
        return !self::isSpecial($semantic1) && self::isSpecial($semantic2) && self::isMainEqual($semantic1, $semantic2);
    }
}

永夜