PHP:提供静态和非静态方法的类的设计模式

pie*_*e6k 5 php static design-patterns class non-static

我的目标是创建可以静态非静态方式使用的类.两种方式都必须使用相同的方法,但方式不同

非静态方式:

$color = new Color("#fff");
$darkenColor = $color->darken(0.1);
Run Code Online (Sandbox Code Playgroud)

静态方式:

$darkenColor = Color::darken("#fff", 0.1);
Run Code Online (Sandbox Code Playgroud)

因此,在此示例中,方法darken既可以用于现有对象,也可以用作Color类的静态方法.但是根据它的使用方式,它使用不同的参数.

应该如何设计这样的课程?创建此类类的好模式是什么?

类将有许多不同的方法,因此它应该避免在每个方法的开头大量检查代码.

tim*_*tim 1

PHP并不真正支持方法重载,所以实现起来并不是那么简单,但是有方法。

为什么要提供静态和非静态?

我首先要问自己的是,是否真的需要提供静态和非静态方法。它看起来过于复杂,可能会让您的颜色类别的用户感到困惑,并且似乎并没有增加那么多好处。我会采用非静态方法并完成它。

静态工厂类

您基本上想要的是静态工厂方法,因此您可以创建一个额外的类来实现这一点:

class Color {

    private $color;

    public function __construct($color)
    {
        $this->color = $color;
    }

    public function darken($by)
    {
        // $this->color = [darkened color];
        return $this;
    }
}

class ColorFactory {
    public static function darken($color, $by) 
    {
        $color = new Color($color);
        return $color->darken($by);
    }
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是将静态方法放在里面Color并给它一个不同的名称,例如createDarken(每次都应该相同,因此createX为了用户方便,将调用所有静态工厂方法)。

静态调用

另一种可能是使用魔法方法__call__callStatic。代码应该如下所示:

class Color {

    private $color;

    public function __construct($color)
    {
        $this->color = $color;
    }

    // note the private modifier, and the changed function name. 
    // If we want to use __call and __callStatic, we can not have a function of the name we are calling in the class.
    private function darkenPrivate($by) 
    {
        // $this->color = [darkened color];
        return $this;
    }

    public function __call($name, $arguments)
    {
        $functionName = $name . 'Private';
        // TODO check if $functionName exists, otherwise we will get a loop
        return call_user_func_array(
            array($this, $functionName),
            $arguments
        );
    }

    public static function __callStatic($name, $arguments)
    {
        $functionName = $name . 'Private';
        $color = new Color($arguments[0]);
        $arguments = array_shift($arguments);
        // TODO check if $functionName exists, otherwise we will get a loop
        call_user_func_array(
            array($color, $functionName),
            $arguments
        );
        return $color;

    }
}
Run Code Online (Sandbox Code Playgroud)

但请注意,这有点混乱。就我个人而言,我不会使用这种方法,因为它对于您班级的用户来说不太好(您甚至不能拥有适当的 PHPDocs)。但这对于程序员来说是最简单的,因为在添加新功能时不需要添加大量额外的代码。