仅仅因为可爱的函数命名原因而使用重载是一个好主意吗?:)
例如: echo $store->product->getPrice($currency);
-
product
将调用__get,然后调用__getObject('product'),它执行神奇的事情并返回当前被视为对象的产品(如果它是第一次调用,则将其实例化)
echo $store->product('dog')->getPrice($currency);
- 这里
product
将调用__call,然后调用__callObject('product',…)…
没有重载的替代方法是:
if(!$store->product)
$store->product = new Product();
echo $store->product->getPrice($currency);
和
$product = new Product('dog');
echo $product->getPrice($currency);
我非常喜欢重载,因为我可以为我的类获得很好的API。但是缺点是重载的东西比直接调用属性/方法要慢15倍。
像这样使用重载是可以的吗?
在我当前的应用程序中,我没有调用重载成员超过1000次。这应该不会对性能产生太大影响。也许额外的0.1秒,考虑到一个站点通常在0.5 - 1s内生成,这并不是那么多
仅仅因为可爱的函数命名原因而使用重载是一个好主意吗?:)
。我是说,这要看情况。:)让我们为我们的编程生活添加一些令人敬畏和可爱的东西:
$ordinary = new stdClass();
$ordinary->Caption = 'Hello';
class Awesome
{
private $ordinary;
public function __construct($ordinary) {
$this->ordinary = (array) $ordinary;
}
public function __get($name) {
$value = '';
return $this->ordinary[$name];
}
}
class Lovely extends Awesome
{
public function __get($name)
{
return '<3 ' . parent::__get($name) . ' <3';
}
}
我必须承认,这个例子可能有点夸张,但它显示了一些东西。
首先,假设API是针对类的。所以它从一个非常普通的stdClass
开始。
$awesome = new Awesome($ordinary);
echo $awesome->Caption, "'n"; # This caption is just awesome by itself!
# Hello
然后看看更可爱的API示例:
$lovely = new Lovely($ordinary);
echo $lovely->Caption, "'n"; # This caption is lovely, hughs and kisses everyone!
# <3 Hello <3
所以在这个例子中,对于Lovely
来说这是个好主意但是对于Awesome
来说就没用了,因为Awesome
实际上更容易获得:
$awesome = $ordinary;
这让我想到了一点,API中的重载只能在特定的点上有用。正如Lovely
所示,它可以用来装饰另一个(没有太多指定的对象),但它也表明这只是一次性的:Lovely
已经需要知道如何调用Awesome
来使用它的功能(现在不再神奇了)__get
方法:
public function __get($name)
{
return '<3 ' . parent::__get($name) . ' <3';
}
当你现在认为Awesome
是你的API时,你可以看到它阻止了自己被其他想要使用它的代码重载。
所以重载在具体代码中是可以的,API不应该阻止它。但是当API本身重载时,事情就变得很困难了。
不仅对于编码,添加动态/魔法也会使调试变得困难。因此,最好对您创建的api保持清晰,并提供比[]
或->
更具体的接口。你可以给事物起具体的名字,这很有效;)
和它比起来更可爱:
echo $store->getObject('product')->getPrice($currency);
重载的缺点是,您必须自己描述"漂亮的API",因为文档工具无法理解您在方法中做了什么。另一点是,它通常是"太多的魔法":你实现的魔法越多,你的代码就越难以理解。
另一方面,我认为你的替代方案没有任何问题。在我眼里它甚至更干净。旁注:避免在方法的开头使用双下划线,只要你没有实现魔法方法。
坚持面向对象的设计原则带来了好处。第一个示例通过从工厂生成产品对象来实现松耦合。有关OO设计原则的更多信息,请参见S.O.L.I.D.和G.R.A.S.P.