簡體   English   中英

類對象的靜態引用

[英]Static reference of a class object

我已經編寫了幾個類,使用時都需要實例化。

我的目標是在嘗試在實例化的類之間創建動態訪問時能夠擁有一個完美的組織。

在一個類中,它將基於剛剛執行的操作而調用幾種方法。 這些方法中的一種將是其他類的方法。 (當前為靜態方法)我將編輯這些行以控制類之間的行為。

我的意思是動態的,如果其中一種靜態方法不可用或以后將可用,那么它只是執行另一種方法以在內部完成任務。

我的問題是有關適當的OOP的問題。 我不確定是否有更好的方法,或者我在做什么會導致問題。 雖然,它工作得很好。

我在下面准備了一個例子。 其中,是代表,不是實際情況。 執行文件一是一種情況,執行文件二是另一種情況。

executingFileOne.php

require_once 'login.php';
$login = new Login();

require_once 'serverData.php';
$servDat = new serverData();

//blah blah blah

executingFileTwo.php

require_once 'serverData.php';
$servDat = new serverData();

//blah blah blah

的login.php

class Login {

    private static $thisClass = null;

    public function __construct(){
        //Get and set user data.
        self::setStaticClass($this);
    }

    public static function setStaticClass(&$inputClass){
        self::$thisClass = $inputClass;
    }

    //Methods Methods Methods

    //---Methods Executed by class at specific times---------------
    // - - - Used to get input from other classes

    //Methods Methods Methods

    //-------------------------------------------------------------

    //---Methods for other classes.--------------------------------
    // - - - Used to output data to other classes
    public static function getUserID(){
        die('Test'.self::$thisClass->userID);
    }

    //Methods Methods Methods of other classes.

    //-------------------------------------------------------------
}

serverData.php

class serverData {

    private static $thisClass = null;

    public function __construct(){
        //work work work
        //an IF statement detected needing to register userID on serverData
            $this->registerOnServer();
        //work work work
        self::setStaticClass($this);
    }

    //Methods Methods Methods

    public function registerOnServer(){
        //work work work
        $this->userID = $this->getUserID();
        //add userID to registration data.
    }

    //---Methods Executed by class at specific times---------------
    // - - - Used to get input from other classes
    private function getUserID(){
        if (class_exists('Login')) {
            return Login::getUserID();
        } else {
            return 0;
        }
    }
    //-------------------------------------------------------------

    //---Methods for other classes.--------------------------------
    // - - - Used to output data to other classes

    //Methods Methods Methods of other classes.

    //-------------------------------------------------------------
}

這是使用靜態類時的幾個問題之一,並且由於偷偷摸摸的自注冊和使用現場的強耦合而變得更加復雜。 目前,對於這個問題,我普遍知道的“最佳”解決方案(我鼓勵使用的一種解決方案)是使用依賴注入。

此外,在DI之上使用IoC(控制反轉)容器可以使所有內容連接在一起並管理使用壽命是理智的過程。 不要恢復到一個Service Locator模式除了在非常特殊的情況或DI +國際奧委會beautiy丟失!)

盡管使用非正式的鴨子式“接口”就足夠了,但是使用編碼接口有助於分類-並且IoC容器經常(但並非總是)能夠注冊和解析組件。

// This is the service (interface) that different components will provider
inteface ILogin {
   public function getUserID ();
}

// Primary component (implementation) for the login service (interface)
class Login implements ILogin {
   // Note:
   // Constructor does NOT "register itself statically"; even when using
   // an approach similar to the original, use a proper Singleton Design.

   public function getUserID () { /* .. */ }
}

// Alternative/mock component (implementation) for the login service (interface)
class NoLogin implements ILogin {
   public function getUserID () { return 0; }
}

// Class (possibly also a component) that uses the login service dependency
class ServerData {
    // Constructor-based DI; the components are supplied as arguments
    // (There is also property-based DI.)
    public function __constructor(ILogin $login) {
        $this->login = $login;
    }

    // Later on we use the service
    // (It is a bit silly just to proxy the service, which should be
    //  injected elsewhere as required, but this mirrors the original.)
    public function getUserID () {
        // If not using a "mock service", then guard $this->login for null
        // because it is now an optional dependency; the appropriate approach
        // will vary based upon specific use-case.
        return $this->login->getUserID();
    }
}

然后稍后:

// File 1-
// Note how dependency is "injected" into the server data
$servDat = new ServerData(new Login());

// File 2-
// A different dependency providing the same contract/service is used
$servDat = new ServerData(new NoLogin());
// Or, if ServerData guards usage and the service is "optional"
// $servDat = new ServerData(null);

因此,這是DI的一種形式(盡管通用術語是IoC,DI是其中的一種實現),它的核心-簡單,但不是很令人興奮,並且可能變得乏味。 同樣,即使依賴項已被移出立即使用站點之外,它們仍然在創建實例並手動注入組件的使用者上有效地進行了硬編碼。

現在,具有DI + IoC的魔力適合什么地方? 組件已注冊到IoC容器中,並且IoC容器用於實例化對象-這樣的容器足夠智能,可以自動解決 DI依賴關系。 那么File#1和File#2之間的唯一區別是它們使用略有不同的IoC配置(一個用於ILogin服務,一個使用Login,另一個使用NoLogin)。

IoC的其他有用功能是可以配置對象生存期。 在這種情況下,Login組件(完成登錄服務)可能是每個請求的實例,實際上是“單一行為”-區別在於它不能在請求之間泄漏, 並且 Login組件現在與ServerData類松散耦合。

IoC容器還有很多其他內容-請參閱PHP DI ,其中似乎有相當不錯的介紹。 請注意,可以使用上面介紹的相同的 DI就緒代碼(在PHP-DI中)來進行組件解析。 (錯誤是免費的。)

我的一個朋友向我展示了一個比我更好的選擇。 可能不是正確的解決方案,但是更好。

看到我實例化我的類,並且可以通過全局調用變量來簡單地訪問其他類中的。 而不是創建任何靜態的東西。

例如:

require_once 'login.php';
$login = new Login();

require_once 'serverData.php';
$servDat = new serverData();

//blah blah blah


class Login {

    public function __construct(){
        //Get and set user data.
    }

    //Methods Methods Methods

    //---Methods Executed by class at specific times---------------
    // - - - Used to get input from other classes

    //Methods Methods Methods

    //-------------------------------------------------------------

    //---Methods for other classes.--------------------------------
    // - - - Used to output data to other classes
    public static function getUserID(){
        die('Test'.$this->userID);
    }
    //-------------------------------------------------------------
}

class serverData {

    public function __construct(){
        //work work work
        //an IF statement detected needing to register userID on serverData
            $this->registerOnServer();
        //work work work
    }

    //Methods Methods Methods

    public function registerOnServer(){
        //work work work
        $this->userID = $this->getUserID();
        //add userID to registration data.
    }

    //---Methods Executed by class at specific times---------------
    // - - - Used to get input from other classes
    private function getUserID(){
        global $login;
        if ($login != null) {
            return $login->getUserID();
        } else {
            return 0;
        }
    }
    //-------------------------------------------------------------

    //---Methods for other classes.--------------------------------
    // - - - Used to output data to other classes

    //Methods Methods Methods

    //-------------------------------------------------------------
}

暫無
暫無

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

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