我的目标是创建可以同时使用静态和非静态方式的类。两种方式都必须使用相同的方法,但方式不同
非静态方式:
$color = new Color("#fff");
$darkenColor = $color->darken(0.1);
静态方式:
$darkenColor = Color::darken("#fff", 0.1);
因此,在此示例中,方法darken
既可以用于现有对象,也可以用作Color
类的静态方法。但是根据它的使用方式,它使用不同的参数。
这样的课程应该如何设计?创建此类类的好模式是什么?
Class将有许多不同的方法,因此它应该避免在每个方法的开头大量检查代码。
答案 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不支持重载方法...
那就是说,个人我会将静态方法移动到不同的类,例如ColorManager
或ColorCalculator
,甚至更好,如果使颜色变暗的代码足够复杂你会有更多这样的操作,我只用这种方法创建一个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。它们是功能性的或程序性的。因此,只需使用一个函数......