簡體   English   中英

根據PHP中的對象類型實例化不同的類

[英]instantiate different class based on the object type in PHP

我正在尋找一種基於對象類型實例化不同子類或使用子類方法擴展基類的體系結構解決方案。

舉個例子:有一個基類User和幾個子類PartnerClientModerator ,它們具有特定的方法和自己的構造函數。 當我打電話時

$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
    }
  }
}

為了給我一個具有所有方法的對象,具體取決於用戶的角色。

我知道我的邏輯在某處被破壞了,而我提供的示例是錯誤的。 但是我現在看到的唯一解決方案是建立一個巨型類,該類具有用於所有角色的所有方法-看起來很爛。

首先,您的數據庫邏輯應與域對象(用戶等)完全分開。 否則,您將違反單一責任原則(SRP)。

設置您的類,如下所示(基類User和多個子類):

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信息,查看其類型(伙伴,主持人等),然后實例化適當的類並合並適當的信息。

問題是您不能調用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的回答(完善)的思路編寫代碼,這將做得更好,更靈活。

暫無
暫無

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

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