[英]What does a domain object factory look like?
我有一個DataMapperFactory
,我認為我正確地做了它,有一個但我有一個DomainObjectFactory
也有意義,但它似乎毫無意義。 就是這個:
namespace libs\factories;
use models as Models;
class DomainObjectFactory {
public function build($name) {
$className = 'Models\\' . $name;
return new className();
}
}
我能看到的唯一優勢是我保持new
運算符不會出現在我的代碼中。
DomainObjectFactory
要比這更多嗎?
任何幫助都會非常感謝。
使用工廠有很多主要原因:
在單元測試方面,這是架構中最有用的結構之一。 讓工廠負責創建實例會使測試時更容易引入模擬。
此外,作為額外的好處,您不再與您使用的類的名稱緊密耦合。
在這里,您必須考慮兩個方面。 首先 - 基於某些條件實例化不同對象的能力 - 在helmbert的答案中已經很好地描述了(對他而言+1) 。
另一種情況是在實例化域對象時,這更復雜。 像這樣的東西:
$employees = new EmployeeCollection;
$address = new Location;
$class = $type . `Company`;
$company = new $class( $employee, $address );
在創建HoldingCompany
實例之前,還有很多工作要做。 但這整個過程可以在工廠完成。 特別是如果您的域對象工廠充分利用正確實現的DIC(這是非常罕見的,順便說一句)。
你永遠不應該在構造函數中進行任何計算。 這使得無法測試該代碼。 構造函數應該只包含簡單的變量賦值。
但是這引入了一個問題:有時你需要做一些邏輯操作,然后才能讓其他代碼結構處理你的實例化對象。 作為初學者,我們通常在構造函數中執行此操作。 但現在放在哪里?
這是工廠拯救的地方。
public function create( $name )
{
$instance = new $name;
if ( is_callable($instance, false, 'prepare') )
{
$instance->prepare();
}
return $instance;
}
現在,當您使用$factory->create('foobar')
,您的對象已完全准備好使用。
通常,您可以使用工廠從特定實現中抽象出來。 如果使用new <classname>
運算符,則每次都實例化一個特定的類。 如果要在以后將此類與其他實現交換,則必須手動更改每個new
語句。
工廠模式允許您從特定類中抽象 。 有效的最小用例可能是這樣的:
interface UserInterface {
public function getName();
}
class UserImplementationA implements UserInterface {
private $name;
public function getName() { return $this->name; }
}
class UserImplementationB implements UserInterface {
public function getName() { return "Fritz"; }
}
class UserFactory {
public function createUser() {
if (/* some condition */) return new UserImplementationA();
else return new UserImplementationB();
}
}
$f = new UserFactory();
$u = $f->createUser(); // At this point, you don't really have to care
// whether $u is an UserImplementationA or
// UserImplementationB, you can just treat it as
// an instance of UserInterface.
當這變得非常有用時,一個用例(很多)是在進行單元測試時。 在測試驅動開發中,您經常使用模擬對象 (實現特定接口但實際上沒有做任何事情的對象)替換類的依賴關系。 使用工廠模式,使用模擬類透明地替換特定類很容易。
public function build($name) {
$className = 'Models\\' . $name;
return new $className();
}
這對你有用。
定義對象工廠是一種很好的做法,當您想要為對象設置一些默認屬性時,您也不必擔心某些類存在於哪個命名空間或目錄中。
例:
public function createButton($name){
require("home/lib/display/Button.php") ;
$button = new Button($name, "some default param") ;
$button->visible = true ;
return $button ;
}
你只需要通過這些工廠快速制作默認對象,除了保持new
詞。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.