2013-10-27 57 views
1

我有一個叫「查看器」的小類。這個類應該查看每個頁面的正確佈局或類似的東西...從數據庫獲取數據get-method的東西?

我有一個名爲getFirstPage的方法,當調用此方法的用戶將得到一個設置值,其頁面當前設置爲第一頁。我有一些代碼在這裏,我想它的工作原理,但我真的不舒爾我做了正確的方式:

class Viewer { 

private $db; 
private $user; 
private $firstPage; 

function __construct($db, $user) { 

    $this->db = $db; 

    if(isset($user)) { 
     $this->user = $user; 
    } else { 
     $this->user = 'default'; 
    } 
} 

function getFistPage() { 
    $std = $db->prepare("SELECT firstPage FROM settings WHERE user = ':user'"); 
    $std->execute(array(':user' => $user)); 
    $result = $std->fetch(); 
    $this->firstPage = $result['firstPage']; 

    return $this->firstPage; 
} 
} 

我GET方法取出由DATABSE設置(到目前爲止好?)。問題是,那麼我必須使用這個get方法來設置私有變量firstPage。似乎我應該有一個設置方法來做到這一點,但我真的不能有一個只從數據庫中獲取設置的set方法,對吧?因爲此對象的用戶應該能夠假定已經在對象中定義了一個設置...

我應該怎麼做?

回答

1

我認爲你的方法並不差。最重要的是在構造函數中傳遞$db,你這樣做。用戶可以是構造函數或方法本身的參數,這取決於應用程序對用戶的'永久性'。

有幾個小的事情,我會改善:爲PDO對象

  1. 使用類型提示。因此,任何使用你的'庫'的人都知道應該注入什麼樣的對象。
  2. 幾乎從不使用private知名度,請使用protected代替。因此,如果有人想擴展你的班級,他仍然可以訪問你的房產。
  3. 不要使用isset/empty來檢查$ user,而是引入一個默認值。因此,任何調用您的方法並查看參數的人都知道發生了什麼。
  4. 始終明確使用public可見性。這是一個很好的做法,您不會混淆例如Java開發人員,他們默認爲package
  5. 如果您確實想創建高質量的代碼,請檢查每種可能的錯誤狀態,以免發生致命錯誤。 PDO::fetch可以返回false,並且應該在以數組形式訪問結果之前檢查此錯誤狀態。
  6. 如果您決定將$firstPage保存爲對象狀態,則應在下次調用該方法時重用該對象。但是,如果您編寫一個通用的Web應用程序,我不認爲您真的想將其置於對象狀態。相反,只需返回結果即可。

然後,你的代碼應該是這樣的:

class Viewer { 

    /** @var PDO $db */ 
    protected $db; 
    protected $user; 

    public function __construct(PDO $db, $user = 'default') { 
    $this->db = $db; 
    $this->user = $user; 
    } 

    public function getFistPage() { 
    $std = $this->db->prepare("SELECT firstPage FROM settings WHERE user = ':user'"); 
    $std->execute(array(':user' => $this->user)); 
    $result = $std->fetch(); 

    if ($result !== false) { 
     return $result['firstPage']; 
    } else { 
     throw new YourException('Failed to fetch first page.'); 
     // or return false/null; 
    } 
} 

編輯:你應該總是完全建立在構造對象的狀態,你不應該做任何的計算在裏面。另外,避免使用類似初始化的方法。在這種情況下,構造函數確保我們有PDO和$user參數設置(對象狀態)。然後,你可以在方法中進行計算而不需要傳遞額外的參數(這很好,它支持對象封裝)。

+0

寫這個方法的時候我完全忘記了public關鍵字!我的第一個想法是在構造函數中初始化所有的值(應該不止是第一頁),但後來我發現你不應該那樣做。我應該怎麼做,如果我想在此時初始化多個參數?我可以寫一個初始化方法嗎? – theva

+0

初始化方法被認爲是不好的做法。您只需在構造函數中設置對象狀態並在方法中執行所有計算。在調用getFirstPage方法之前,爲什麼要初始化'firstPage'? –

+0

作爲查看器的對象取決於當前用戶設置,因此作爲實例的對象在沒有firstPage設置的情況下不會完成。 – theva

1

吸氣劑不應該改變物體的狀態。但是,有時候成員變量不是實際對象狀態的一部分,而是用於內部緩存。你應該問自己 - 是firstPage部分狀態?班級的用戶是否應該關心它是否設置?除了表現,對象的價值是否有所不同?如果沒有,則可以將其設置在吸氣器中。

+0

非常好的一點,也許是最重要的。 –