簡體   English   中英

域對象工廠是什么樣的?

[英]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要比這更多嗎?

任何幫助都會非常感謝。

使用工廠有很多主要原因:

1.摘要對象的創建

在單元測試方面,這是架構中最有用的結構之一。 讓工廠負責創建實例會使測試時更容易引入模擬。

此外,作為額外的好處,您不再與您使用的類的名稱緊密耦合。

2.簡化實例化

在這里,您必須考慮兩個方面。 首先 - 基於某些條件實例化不同對象的能力 - 在helmbert的答案中已經很好地描述了(對他而言+1)

另一種情況是在實例化域對象時,這更復雜。 像這樣的東西:

$employees = new EmployeeCollection;
$address = new Location;
$class = $type . `Company`;
$company = new $class( $employee, $address );

在創建HoldingCompany實例之前,還有很多工作要做。 但這整個過程可以在工廠完成。 特別是如果您的域對象工廠充分利用正確實現的DIC(這是非常罕見的,順便說一句)。

3.在對象在應用程序中釋放之前准備對象

永遠不應該在構造函數中進行任何計算。 這使得無法測試該代碼。 構造函數應該只包含簡單的變量賦值。

但是這引入了一個問題:有時你需要做一些邏輯操作,然后才能讓其他代碼結構處理你的實例化對象。 作為初學者,我們通常在構造函數中執行此操作。 但現在放在哪里?

這是工廠拯救的地方。

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.

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