2017-08-30 50 views
-1

我想設計一個無狀態類,用於在應用程序的多個位置重複使用同一個實例,而不會產生任何副作用。這是必要的,因爲許多依賴注入容器總是返回類的相同實例。PHP - 設計無狀態類

假設我們有DirectoryUtils類:

<?php 

class DirectoryUtils{ 

    private $dir; 

    public function __constructor($dir){ 
    if($this->checkDirectory($dir)){ 
     $this->dir = $dir; 
    }else{ 
     throw new Exception("Invalid Directory"); 
    } 
    } 

    public function deleteAllFiles(){ 
    // code to delete all files in $this->dir; 
    } 

    public function renameDirectory($newName){ 
    // code to rename $this->dir name to $newName 
    } 

    private function checkDirectory($dir){ 
    // check if directory exists, is writable... 
    } 

} 

這個類的一個實例是難受重用。如何使它無狀態?

+2

StateLess ==不知道以前發生過什麼。 – RiggsFolly

+1

*這是必要的,因爲許多依賴注入容器總是返回類的相同實例* - 其中許多容器也允許您解決此問題。你嘗試了哪些? – iainn

+0

@iainn PHP-DI將在下一個主要版本中刪除原型範圍。 – Bob

回答

0

我想你需要擴大你正在調查此範圍:什麼是你可以把在DI容器重複使用一個有意義的服務?

你們班的問題並不在於它是有狀態的,而是它的名字反映了對其目的的誤解。此類代表特定目錄因此應適當命名,例如

$my_home_dir = new Directory('/home/imsop'); 
$your_home_dir = new Directory('/home/abskmj'); 
$diff_tool->compareDirs($my_home_dir, $your_home_dir); 

在您的DI容器,那麼您需要把這個類的幾個特定情況下,你需要訪問特定的目錄,例如

[ 
    'CacheDir' => function($config) { 
     return new Directory($config['cache_path']); 
    }, 
    'LogDir' => function($config) { 
     return new Directory($config['log_path']); 
    } 
] 

另一種類型,你可以創建服務的是一個工廠,其抽象文件系統的一部分,併爲您提供不同的Directory對象,例如:

$my_home_dir = $factory->getHomeDir('imsop'); 

這裏,國家在構建DI可能是工作的基本目錄:

[ 
    'DirectoryFactory' => function($config) { 
     return new DirectoryFactory($config['base_dir_path']); 
    } 
] 

這兩個類都不是「無狀態的」,但都是不可改變 - 一旦構建,您不會將它們更改爲指向不同的目錄,您爲每個目的使用不同的實例。

DirectoryFactory類實際上可以通過硬編碼所有邏輯(例如「主目錄始終爲'/home/' . $user_name」)而成爲無狀態。這對放入DI容器仍然有用,因爲您可以用不同的硬編碼規則或測試模擬替換版本。但是,如圖所示,從這個意義上說,缺乏狀態並不是它作爲「單身人士」有用的必要先決條件。

0

如何使之成爲無國籍

你不談論 '無國籍' 在這裏。見https://en.wikipedia.org/wiki/Stateless

讓你的功能的靜態:https://secure.php.net/manual/en/language.oop5.static.php

class DirectoryUtils { 
    ... 

    public static function renameDirectory($newName) { 
     ... 
    } 

} 

那麼你只需調用它像這樣:

DirectoryUtils::renameDirectory($name); 
+0

我不是在談論靜態方法......看這裏:http://php-di.org/doc/scopes.html – Bob

+0

你在談論單身人士然後。 –

+0

Singleton範圍(與PHP-DI相關),而不是單例設計模式。 – Bob

0

一個無狀態類的基本規則是沒有任何實例變量/屬性來存儲狀態。類方法類似於僅在參數上工作的實用程序或輔助函數。

重寫類:

<?php 

class DirectoryUtils{  

    public function deleteAllFiles($dir){ 
    // code to delete all files in $dir; 
    } 

    public function renameDirectory($dir, $newName){ 
    // code to rename $dir name to $newName 
    } 
} 
+0

'無狀態類的基本規則是沒有任何實例變量/屬性來存儲狀態'那麼爲什麼甚至有一個構造函數? –

+0

PHP不添加默認構造函數。 [參考](https://stackoverflow.com/questions/7909073/why-php-has-no-default-constructor)。但是,如果所有方法都是靜態的,則不需要構造函數。 – abskmj

+0

實際上,它可能有一些共享屬性,例如可以通過調用共享的數據庫連接 –