顺序耦合

顺序耦合是指创建的类中的方法必须以特定顺序调用。以 initbeginstart 开头的方法名可能是这种行为的标志;根据上下文,这可能是反模式的标志。有时,工程师会用汽车来解释抽象概念,这里我也会这样做。

例如,下面这个类:

<?php

class BadCar
{
    private $started = false;
    private $speed = 0;
    private $topSpeed = 125;

    /**
    * Starts car.
    * @return bool
    */
    public function startCar(): bool
    {
        $this->started = true;
        return $this->started;
    }

    /**
    * Changes speed, increments by 1 if $accelerate is true, else decrease by 1.
    * @param $accelerate
    * @return bool
    * @throws Exception
    */
    public function changeSpeed(bool $accelerate): bool
    {
        if ($this->started !== true) {
            throw new Exception('Car not started.');
        }

        if ($accelerate == true) {
            if ($this->speed > $this->topSpeed) {
                return false;
            } else {
                $this->speed++;
                return true;
            }
        } else {
            if ($this->speed <= 0) {
                return false;
            } else {
                $this->speed--;
                return true;
            }
        }
    }

    /**
    * Stops car.
    * @return bool
    * @throws Exception
    */
    public function stopCar(): bool
    {
        if ($this->started !== true) {
            throw new Exception('Car not started.');
        }

        $this->started = false;

        return true;
    }
}

正如你可能注意到的,在使用其他函数之前,我们必须运行 startCar 函数,否则就会出现异常。实际上,如果你试图加速一辆未启动的汽车,它不应该做任何事情,但为了便于论证,我将其改为汽车先启动。在下一个停止汽车的示例中,我修改了类,如果你试图在汽车没有启动的情况下停止汽车,该方法将返回 false

<?php

class GoodCar
{
    private $started = false;
    private $speed = 0;
    private $topSpeed = 125;

    /**
    * Starts car.
    * @return bool
    */
    public function startCar(): bool
    {
        $this->started = true;
        return $this->started;
    }

    /**
    * Changes speed, increments by 1 if $accelerate is true, else decrease by 1.
    * @param bool $accelerate
    * @return bool
    */
    public function changeSpeed(bool $accelerate): bool
    {
        if ($this->started !== true) {
            $this->startCar();
        }

        if ($accelerate == true) {
            if ($this->speed > $this->topSpeed) {
                return false;
            } else {
                $this->speed++;
                return true;
            }
        } else {
            if ($this->speed <= 0) {
                return false;
            } else {
                $this->speed--;
                return true;
            }
        }
    }

    /**
    * Stops car.
    * @return bool
    */
    public function stopCar(): bool
    {
        if ($this->started !== true) {
            return false;
        }

        $this->started = false;
        return true;
    }
}