[英]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.