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

时间:2015-04-19 09:14:51

标签: php class design-patterns static non-static

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

非静态方式:

$color = new Color("#fff");
$darkenColor = $color->darken(0.1);

静态方式:

$darkenColor = Color::darken("#fff", 0.1);

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

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

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

3 个答案:

答案 0 :(得分: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);
    }
}

另一种方法是将静态方法放在Color中并给它一个不同的名称,例如createDarken(每次都应该相同,所以所有静态工厂方法都会被调用{{ 1}}以方便用户使用。)

<强> callStatic

另一种可能性是使用魔术方法createX__call。代码看起来像这样:

__callStatic

请注意,这有点凌乱。就个人而言,我不会使用这种方法,因为它对你的类的用户来说不是那么好(你甚至没有合适的PHPDocs)。对于程序员来说,这是最简单的,因为在添加新函数时不需要添加大量额外代码。

答案 1 :(得分:1)

根据您的代码示例和您的评论,我了解您的方法->darken()将根据该属性的当前值修改$color对象中的属性。另一方面,静态::darken()方法将返回变暗颜色的值......

如果我理解正确,你可以这样做:

class Color {

    protected $value;

    public static function darkenColor($value, $coef) {
        $darkened = //Darken $value using $coef somehow...
        return $darkened;
    }

    public function darken($coef) {
        $darkened = Color::darkenColor($this->value, $coef);
        $this->value = $darkened;
        return $darkened;
    }
}

使用这种方法,您不需要重复使颜色变暗的代码,并且您可以提供类中的动态和静态方法。
静态方法“完成工作”,可以独立调用,动态方法只使用静态方法进行计算并将结果分配给对象属性。
请注意,您必须为方法使用不同的名称,因为PHP不支持重载方法...


那就是说,个人我会将静态方法移动到不同的类,例如ColorManagerColorCalculator,甚至更好,如果使颜色变暗的代码足够复杂你会有更多这样的操作,我只用这种方法创建一个ColorDarkener类......

class Color {

    protected $value;

    public function darken($coef) {
        $darkened = ColorDarkener::darken($this->value, $coef);
        $this->value = $darkened;
        return $darkened;
    }
}

class ColorDarkener {

    public static function darken($value, $coef) {
        $darkened = //Darken $value using $coef somehow...
        return $darkened;
    }
}

答案 2 :(得分:1)

由于您特别询问设计

  

如何设计这样的课程?

他们不应该。

您提供了两种方法来执行相同的完全事情。这几乎不是一个好主意。它违反了单一责任原则以及其他SOLID原则。

相反,保持对象有状态,并提供辅助函数:

class Color {
    public function __construct($color) {/**/}
    public function darken($by) {/**/}
}
function darken($color, $by) {
    return (new Color($color))->darken($by);
}

因为PHP支持一流的功能,所以不必将其设为静态。

设计模式而言,静态方法不存在OOP设计模式,因为静态方法不是OOP。它们是功能性的或程序性的。因此,只需使用一个函数......