簡體   English   中英

PHP OOP ::對Factory類感到困惑,並將對象傳遞給構造函數

[英]PHP OOP :: getting confused about Factory class and passing objects to constructors

我正在嘗試確保我的應用程序強制執行依賴注入,但是我有點不高興。

class Factory {

public $sessionId;
public $config;
public $lib;

function __construct() {
    $this->getSessionId();
}

function getSessionId() {
    if (isset($_COOKIE['sk'])) {
        $this->sessionId = trim($_COOKIE['sk']);
    } else {
        $sm = $this->createSessionManager();
        $this->sessionId = trim($sm->getNewKey());
        setcookie("sk", $this->sessionId, time() + 3600 * 3, "/");
        setcookie("vb", 0, 0, "/");
    }

}

function createBasket() {
    $t = $this->createTicket();
    $co = $this->createContribution();
    $cfg = $this->createConfig();
    $basket = new Basket($t, $co, $cfg);
    return $basket;
}

function createTicket() {
     $sm = $this->createSessionManager();
    $cfg = $this->createConfig();
    $ticket = new Ticket($this->sessionId, $sm, $cfg);
    return $ticket;
}

....}

首先,我想知道我是否以正確的方式對待事物。 瀏覽器調用的示例查看器頁面為:

function __autoload($class_name) {
    include 'classes/' . $class_name . '.class.php';
}

$factory = new Factory;

$performance = $factory->createPerformance();
$pno = (isset($_GET['pno']) ? $_GET['pno'] : 0);
print $performance->displayHtmlListing($pno);

我的其他問題/問題與我如何防止“捕獲22”情況有關,在這種情況下,對象A需要對象B,而在極少數情況下,它將需要對象A。

例如,在Factory類中:

function createParser() {
    $am = $this->createApiManager();
    $parser = new Parser($am);
    return $parser;
}

解析器對象被傳遞一個對象到構造函數中,以滿足其在業務邏輯中的依賴性。 它的工作是讀取文件請求,如果滿足特定條件,則需要抓住$ am對象(APIManager)並向API發出請求。 問題在於APIManager通過Parser對象傳遞所有請求,而我在不破壞業務規則或添加冗余條件代碼的情況下,無法輕松刪除對Parser的依賴。

想知道是否有人對如何解決此問題有任何想法?

謝謝,詹姆斯

更新:

有關依賴性問題的更多信息:

ApiManager.caller()-它的工作是轉到API URL,發送GET變量,並檢索結果。

幾乎所有類都使用此caller()方法(也許很好的理由使其成為超類並擴展需要它的類?)。

caller()的部分職責是檢查正在進行的API調用。 如果滿足特定條件,則需要停止並調用SessionManager.getNewSession(),后者將使用相同的API並檢索值。 僅在完成此操作后,原始請求(在caller()中)才能完成。

問題在於SessionManager.getNewSession()也使用了caller()。

這只是恕我直言,但是具有包含“ manager”,“ context”,“ parser”等名稱的大量類是代碼的味道。 我並不是說這些類肯定是錯誤的-實際上幾乎每個應用程序都包含它們。 但是考慮一下-解析器是您擁有的東西,還是正在解析對象所做的事情? 現實世界中有沒有標題為“ API Manager”的家伙? 他是否與會話管理器一起出去,詢問您有關TPS報告的信息? 等等。

考慮一下您的類設計-我並不是說它是“錯誤的”-因為我還沒有看到它,而且它還是主觀的-但是您的類是在模擬現實世界的實體,還是在模擬可以對實體進行? 或者,更糟糕的是,他們是否在建模某種任意的工作流程? 你們所有的班級都有明確定義的職責,並且不嘗試做與他們無關的瘋狂事情嗎?

基本上,您會遇到此問題,因為您的類設計不是最佳的。 特別是,如果一個類的實例,需要另一個類反之亦然的實例才能正常工作,你可能會重新考慮從你的設計中獲益。

更新以響應詹姆斯的更新

ApiManager.caller()-它的工作是轉到API URL,發送GET變量,並檢索結果。

OOP的思想之一是,類表示實體(名詞),方法表示動作(動詞)。 這里的ApiManager是一個實體(有點抽象,但是我們會繼續使用它),但是caller()不是一個動作-即您不能“調用”某些東西。 但是,您可以call()某些東西-我猜在ApiManager的上下文中,這將“調用” API。 我知道這只是2個小寫字母,但這對ApiManager所做的事情的心理概念產生了很大的影響。

幾乎所有類都使用此caller()方法(也許很好的理由使其成為超類並擴展需要它的類?)。

繼承最適合用於支持多態性,而不是代碼共享-我不會那樣做...

caller()的部分職責是檢查正在進行的API調用。 如果滿足特定條件,則需要停止並調用SessionManager.getNewSession(),后者將使用相同的API並檢索值。 僅在完成此操作后,原始請求(在caller()中)才能完成。

一個問題是caller()不應該承擔責任,因為它應該是一個動作(例如call() ),而不是事物。 行動不能承擔責任。 它應該做一些事情,最好是簡單的事情。 與ApiManager作為事物和call()作為ApiManager進行的操作的想法保持一致,下面是一個最基本的示例,說明我如何期望ApiManager可以工作:

class ApiManager {

    private $session;
    private $url;

    // You'll probably need to set up the object differently;
    // this is just an example....
    public function __construct($url) {
        $this->setURL($url);
    }

    function call() {
        if ($this->session is expired) {
            // instead of calling SessionManager.getNewSession() here,
            // why not just fold the session management functionality
            // into ApiManager? They both use the same API, after all...
            $session = $this->getNewSession();
        }
        // do your call & return the response
    }

    public function setURL($url) {
        $this->url = $url;
    }

    private function getNewSession() {
        // get a new session
        $this->session = $my_new_session;
    }

}

您會注意到上面的類中的所有方法都是動作,它們都可以執行某些操作。 錦上添花的是,不再需要擔心SessionManager的依賴項注入,因為它不再存在! 畢竟,API會話實際上只是ApiManager需要知道的東西,不是嗎? :)

暫無
暫無

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

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