簡體   English   中英

PHP中的延遲加載類方法

[英]Lazy loading class methods in PHP

我有一個類有一些相當大的方法。 在它的基本和最常見的狀態中,大多數功能都不是必需的,所以我想知道是否有一種延遲加載只是部分類的方法。 該方法需要能夠訪問私有/受保護的成員,使這將是理想的,如果該方法是原產於類,但是在尋找其他的解決方案,我碰上了其中討論在回調中使用私有成員這將是一個可行的解決方案(我將使用包含調用回調和延遲加載該類的函數的單獨類。 那是2009年,以及這個功能是否已經在PHP的更高版本中刪除了我不知道,但它似乎不適用於5.3.5

有沒有辦法做到這一點,或者你對我應該看的其他模式有什么建議嗎?

謝謝。


哇! 感謝所有的答案。 我認為你們中有很多人認為這是一個可能的過早優化,或者更糟糕的是,根本不是優化是非常有效的,我將進行分析以檢查我所解決的任何解決方案實際上是否有助於不傷害。 ...現在正確閱讀和消化你的所有想法。 再次感謝。

從PHP 5.4開始,您可以(重新)綁定匿名函數和閉包

<?php

class Foo
{
    private $bar = 1;
}

$getBar = function() { return $this->bar; };

$foo = new Foo;
$foo->getBar = $getBar->bindTo($foo, $foo);

echo call_user_func($foo->getBar); // prints "1"

有關Closure實現和潛在問題的討論,請參閱https://wiki.php.net/rfc/closures/object-extension

通常,如果您發現您的類有很多長方法,請嘗試將它們分解為更小的塊。 用簡單的英語描述這些方法的用途。 為每個“和”創建一個新方法並將代碼移動到那里。

還要看看該類中的各種屬性。 如果其中一些在概念上一起進行,請考慮將它們變成自己的對象。 將訪問這些屬性的任何方法移動到新對象以進行內聚。

我也有點質疑你想要在課堂上“懶惰加載”方法的動機。 將它們放在那里沒有性能上的復雜性,即使你不使用它們也是如此。 如果這是用於性能優化,那么您可能正在從錯誤的一端接近它。

另一種選擇是使用Traits ,甚至更簡單的組合

回調解決方案看起來非常難看。
您可以使用合成模式和自動加載:

class MyClass
{

protected $logger;

function SomeFunction($arg)
{
    $this->Logger()->write($arg);
}

function Logger()
{
    if (empty($this->logger)) $this->Logger = new Logger(); //lazy initialization of method
    return $this->logger;
}

}

但是,我不得不說,所有這些只是微觀優化,不要浪費你的時間。 創建新對象和自動加載另一個文件(它使用磁盤)的時間將比使用“大”方法對對象的簡單初始化更大。

我不知道只加載一部分類的(性能有效)方法。

我認為你需要將類的方法分成子類,並使用自動加載來加載它們。

完成后,您可以考慮做這樣的事情:

class myMainClass
 {

   function bigFatMethod($argument, $argument2)
    {
      return mySubClass::bigFatMethod($this, $argument, $argument2); 
      // (pass $this if necessary)
    }
 }  

這將保持bigFatMethod()調用內部myMainClass ,必要的代碼被加載時,才,但在內部,因為使用的是自動加載bigFatMethod()實際上是調用。

顯然,您需要重寫bigFatMethod()以便可以靜態調用它,而不是訪問$this ,您必須讓它訪問在其第一個參數(在父類中傳遞$this中傳遞的對象。

我自己從來沒有這樣做過 - 我傾向於將類分成子類,並單獨解決它們 - 但我不能看到以這種方式做事的任何巨大缺點。

如果你願意,你甚至可以使用__call()魔術方法抽象bigFatMethod() ,該方法將查找它必須加載的子類,執行該方法並返回結果。

你的班級可能會嘗試做太多。 我建議嘗試將其分成單獨的服務。 然后,您可以使用依賴注入容器(例如, Pimple )來延遲加載實際使用的那些服務。

我建議不要濫用繼承權。 相反,你應該贊成合成而不是繼承 這使您的設計更清晰,代碼庫更易於維護。

<?php
class BigClass
{
  public function lazy()
  {
    return include 'lazy.func.php';
  }
}

這應該工作並滿足您的要求。 我對它可能產生的任何副作用並沒有太多考慮。

只加載一部分課 - 這根本不可能。 當您創建類的新實例時,它會初始化整個類,因此您不需要延遲加載函數

您可以編寫一個包含所有基本功能的基類,然后使用繼承來逐步添加更多專用功能,並且只在需要時使用繼承類。

PHP對象繼承

您可以使用魔術類方法__get動態加載屬性,或使用魔術方法__call來委托其他類/方法。 當您需要初始化屬性或方法等時,這些都非常棒,只有在訪問它們時。

奇怪的是,我最近在博客上談到了這件事,因為我需要在我的一個項目中進行大規模的課程。 這有點牽扯,但我試圖簡單地解釋一下。 它可能會給你一些指示。

http://www.kalekold.net/index.php?post=16

http://php.net/manual/en/language.oop5.magic.php

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM