在PHP中重载属性和方法 - 原因是什么?

时间:2012-01-03 12:02:01

标签: php overloading

为了完全可爱的功能命名原因而使用重载是否是一个好主意? :)

例如:

echo $store->product->getPrice($currency);

  • product将调用__get然后__getObject('product')执行magik的操作并返回当前被视为对象的产品(如果是第一次调用则会实例化)

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生成并不是那么多

3 个答案:

答案 0 :(得分:3)

重载的缺点是,你必须自己描述“漂亮的API”,因为文档工具无法理解你在方法中做了什么。另一点是,它通常是“太多魔术”:你使你的代码更难理解你实现的魔法。

另一方面,我认为您没有任何问题。它在我眼中更加清洁。

旁注:只要你没有实现魔术方法,避免在方法开头使用双下划线。

答案 1 :(得分:3)

  

为了完全可爱的功能命名原因而使用重载是否是一个好主意? :)

没有。我的意思是,这取决于。 :)让我们为编程生活增添一些精彩和可爱:

$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开始。

这个例子显示的是那些魔术函数可用于重载装饰。可以,但绝不能。看到很棒的API,它本身就很棒:

$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已经需要知道如何调用{{1}通过使用(现在不再是魔法)Awesome方法来利用它的功能:

__get

如果您现在认为 public function __get($name) { return '<3 ' . parent::__get($name) . ' <3'; } 是您的API,您可以看到它无法轻易地从想要使用它的其他代码网中轻载过载。

因此,具体代码中的重载可能没什么问题,API不应该阻止它。但是当API本身过载时,事情可能变得困难。

不仅仅是编码,添加动态/魔术也使得调试变得困难。因此,最好对您创建的API保持清晰,并提供更具体的界面,然后只需Awesome[]。你可以给出具体的名称并且效果很好;)

然后它更可爱:

->

答案 2 :(得分:1)

通过坚持面向对象的设计原则,可以获得收益。第一个示例允许通过从工厂生成产品对象来进行松散耦合。有关OO设计原则的更多信息,请参阅S.O.L.I.D. and G.R.A.S.P.