我来自C#,我正在努力找出使我的代码可扩展的PHP方式。
让我们说比如我有一个功能可以计算我建议的每日食物摄入量。它关注维生素,卡路里,矿物质等......
我想在我的应用程序中使用许多不同的食物对象以及查看食物不同方面的不同功能,因此我实现了IFoodNutrition
界面并使我想要与之兼容的食物类我的功能实现它。然后我声明我的函数将其作为arg
function GetRda(IFoodNutrition $food){}
在C#中,我将指定我需要在界面中使用的所有属性,所以我知道实现它的任何类都将与此函数兼容。
令我头疼的是PHP只允许接口中的方法签名。
我的问题显然是范式的转变。我不确定PHP中的等效模式是什么。我已经阅读了文档,除非你从一个抽象类继承,否则我看不到类似的替代方法,但是你只能从一个类继承,所以它不会以相同的方式工作。
由于PHP不是类型安全,我不必创建界面。有人可以将任何对象发送到该方法,如果它具有正确格式所需的属性,它将起作用。这对我来说似乎并不合适,因为我习惯于在接口中阐述事物应该如何与之交互。
我觉得至少应该在验证对象的中间有一些额外的步骤,以及开发人员可以查看的一些明显的结构,然后直观地实现他们自己的类,并在运行之前看到错误。
这样的PHP中是否有特定的模式?
答案 0 :(得分:6)
PHP只允许接口中的方法签名。
这是事实。但是,没有什么能阻止您将属性的传统getter和setter作为界面的一部分。这样做会抽象出底层的实现细节。
有人可以将任何对象发送到该方法,如果它具有正确格式所需的属性,它将起作用。
事实并非如此。您IFoodNutrition $food
的参数为type-hinted。如果此函数接收到未实现IFoodNutrition
接口的对象,则PHP将抛出致命错误。
答案 1 :(得分:0)
我的PHP知识仍然有限,但我会尝试一些关于如何解决这个问题的答案。
接受输入中的所有内容,如果输入无效,则会失败并显示异常。
function getRda ($food) { if (!($food instanceof IInterface)) { throw new \Exception('function argument should be instance of IInterface'); } //... do your magic }
在界面中,建议存在属性(例如,$ mineral的getMinerals)
虽然在对象交互之间建立合约对你没什么帮助,但它会帮助你保持代码干净
e.g。
trait Food
{
protected $minerals;
public function getMinerals ()
{
return $this->minerals;
}
}
然后,在每个类中你想要多个继承(相当于,比方说,扩展两个抽象类),使用上面的特征。
答案 2 :(得分:0)
您无法在php中定义界面中的属性。
这是有道理的,因为接口的功能是指定API,而不是实现。