2013-01-15 126 views
2

我正在尋找一個基於對象類型實例化不同子類或使用子類的方法擴展Base類的架構解決方案。根據PHP中的對象類型實例化不同的類

舉個例子: 有一個基類用戶和幾個子類合作伙伴客戶主持人具有特定方法的自己的構造函數。 當我打電話

$user = new User($userid); 

我想用戶

class User 
{ 
    public function __construct($userid) { 
    self::initDB(); 

    if ($this->isPartner()) { 
     //extend this class with the methods of "Partner" child class and run "Partner" class constructor 
    } 

    if ($this->isClient()) { 
     //extend this class with the methods of "Client" child class and run "Client" class constructor 
    } 

    if ($this->isModerator()) { 
     //extend this class with the methods of "Moderator" child class and run "Moderator" class constructor 
    } 
    } 
} 

要返回我的對象​​與所有取決於什麼樣的角色呢用戶有方法。

我知道我的邏輯被打破了某處,我提供的例子是錯誤的。但我現在看到的唯一解決方案是構建一個擁有所有角色所有方法的巨人類 - 這看起來像一團糟。

回答

4

首先,你的數據庫邏輯應該完全獨立於你的域對象(用戶等)。否則,你違反了單一責任原則(SRP)。

設置類類似如下(基類用戶和多個子類):

class User 
{ 
    private $id; 
    // getters and setters go here 
} 

class Moderator extends User {} 
class Partner extends User {} 
// etc 

然後,創建某種UserManager類的實現看起來像下面的界面:

interface UserManagerInterface { 
    function loadUserById($id); 
} 

該方法的實現應該從數據庫中加載傳遞的用戶ID信息,查看它是什麼類型(合作伙伴,主持人等),然後實例化適當的類並提供適當的信息。

+0

Lusitanian,謝謝你的回答! 所以我會怎樣創建)的用戶(或子女)的實例對象將被 1創建的UserManager類 2的實例)調用方法loadUserById它會返回一個正確的對象 看起來一樣的方式工廠模式(通過擁有類userManager有一個靜態方法)。但工廠模式看起來更短,更好。爲什麼更糟? –

+0

UserManager不會是靜態類。它可以被實例化並且提供可擴展且易於單元測試的代碼,並且也與單一責任原則(OOP)保持一致。 – Lusitanian

2

問題是,您無法撥打new User並獲得除User對象以外的任何內容。

這聽起來像是工廠模式的完美用例。

這最簡單的形式使用靜態方法來調用正確的構造函數。

所以你可以有這樣的代碼:

class User { 
    public static function create($userid) { 
     // get user from the database 

     // set $isPartner to true or false 
     // set $isClient to true or false 
     // set $isModerator to true or false 

     if ($isPartner) { 
      return new Partner($userid); 
     } elseif ($isClient) { 
      return new Client($userid); 
     } elseif ($isModerator) { 
      return new Moderator($userid); 
     } else { 
      return new User($userid); 
     } 
    } 
} 

你可以調用User::create($userid)得到適當的對象。

如果你的代碼結構合理,那麼沿着Lusitanian的答案(充實完成)可能會做出更好,更靈活的工作。

+0

這並沒有解決SRP違規問題,實際上也引入了靜態工廠反模式。工廠是正確的路要走,但它應該在另一個類中確保可測試的固體代碼。 – Lusitanian

+0

@Lusitanian我不認爲你會從這一點開始承擔單一的責任,說實話。當然,一個實例化的,靈活的,可測試的工廠往往是理想的,但並不總是可以實現的。我稍微編輯了我的答案;我希望它讓你滿意。 – lonesomeday

+0

呵呵,我想我的主要問題是他問了架構,並用oop標記了這一點,所以如果他剛開始他的應用程序指向他的方向是正確的,但我明白你來自哪裏。 – Lusitanian

相關問題