簡體   English   中英

Factory類是否也適用於從數據庫中提取數據的功能

[英]Is it appropriate for a Factory class to also include functionality of extracting data from a database

我掙扎的軟件開發的一個主要方面是將正確的責任委托給我的程序中的類。 在我的第一個初級角色工作,我也接觸到許多不同的設計模式和想法,有時信息可能是壓倒性的。

顯然,當我們構建軟件時,我們傾向於聲明一個類應該只對一件事和一件事負責。 它應該做得很好,僅此而已。 因此,在Factory模式的情況下,Factory類應負責構建產品並公開允許導向器從工廠中提取產品的界面。

然而,工廠類顯然需要從某個地方接收數據來構建產品,沒有輸入數據我們沒有輸出產品。 因此,我想知道是否包含工廠查詢數據庫的功能是否合適? 我的理由是,如果工廠的任務是構建特定產品,那么它還應負責檢索構建該產品所需的數據。 但我不能100%確定這是否正確。

或者,是否應該有一個存儲庫類,誰負責從數據庫中檢索有問題的數據,然后可以將其傳遞給工廠以組裝成所需的產品? 在這種情況下,使用存儲庫類似乎有點過分,因為我們有一個類,它將包含大量不同的數據,然后必須將它們運送到工廠類。

如果我們還要記住鮑勃叔叔的教導,即聲明函數和方法絕對不應超過三個參數,那么我們將通過將大量數據傳遞給工廠來破壞這一規則。 如果我們在傳遞給工廠之前首先將數據組裝成一個包含類,那么我們基本上是在存儲庫類中完成工廠的工作。

在這方面我會非常感激一些指導,因為我腦子里的線條很模糊,我不知道該怎么辦。

不應將工廠模式用於從數據庫中提取的對象構建。 此目標有Repository模式Data Mapper模式 這些模式必須封裝數據存儲的所有工作邏輯。 這些模式必須承擔以下責任:

  • 存儲庫必須提供業務邏輯的接口,以便與數據存儲一起工作
  • Data Mapper必須將數據從數據庫轉換為具體對象

對象之間的協作算法可能如下所示:

  • 業務邏輯使用存儲庫來讀取/持久化對象。
  • 存儲庫使用Data Mapper將對象轉換為INSERT或UPDATE查詢,並將數據從數據存儲轉換為對象

此外,您可以在Microsoft的站點上閱讀有關C#中的存儲庫模式的更多詳細信息,您可以看到存儲庫模式的C#示例

使用2個不同的類。

數據訪問對象(DAO)為數據庫提供抽象接口,並隱藏其詳細信息。

工廠提取並隱藏對象創建的詳細信息。 例如,對於單元測試,您可能希望配置工廠,使其根本不使用數據庫。

要減少DAO和工廠之間的參數數量,請將您的許多數據包裝在幾個邏輯相關的類中。

Factory類是否適合包含從數據庫中提取數據的功能

我的理由是,如果工廠的任務是構建特定產品,那么它還應負責檢索構建該產品所需的數據。 但我不能100%確定這是否正確。


從數據庫檢索的產品不是一個簡單的對象,它是一個域模型 域模型(也稱為業務模型,也就是實體(可能指示它的特定實例))屬於您的域層 (也稱為業務層)。 在這方面,你應該至少熟悉一些模式......

活動記錄 )VS( 數據映射器 + 存儲庫 )VS( 表數據網關 +工廠)

活動記錄模式通過引導您在域模型中實現數據庫訪問邏輯並緊密耦合它們來違反單一責任原則

理想情況下,為避免上述缺點導致復雜性稍微增加(僅在短期內),我們將數據庫訪問邏輯分離為補充層,即數據訪問層 該層的主要組成部分之一是數據映射器,它在我們的上下文(READ操作)負責從數據庫檢索數據並將其映射到新的域模型實例,即您的特定產品 (實體)。 更一般地,它將CRUD操作封裝到抽象此數據庫的數據庫中。 它的API輸入和輸出是實體對象,可能還有查詢對象

可選地,特色數據映射器將使用諸如以下的模式:

  • 工作單位
  • 延遲加載
  • 身份地圖
  • 交易
  • 鎖定策略
  • 元數據映射

或者,是否應該有一個存儲庫類,誰負責從數據庫中檢索有問題的數據,然后可以將其傳遞給工廠以組裝成所需的產品? 在這種情況下,使用存儲庫類似乎有點過分,因為我們有一個類,它將包含大量不同的數據,然后必須將它們運送到工廠類。

存儲庫不是數據訪問層的一部分,而是您的域層的一部分。 所以它是您的數據訪問層的客戶端。 它不封裝任何數據庫訪問邏輯,但使用數據映射器。

存儲庫封裝了特定域模型的查詢邏輯以及您之前檢索的內存中實體的集合。 一個非常基本的例子:

class ProductRepository
{
    private $productCollection;

    public function findById($id)
    {
        if (!$this->productCollection->has($id)) {
            $product = $this->dataMapper->get(new Query(Product::class, $id));
            $this->productCollection->add($product);
            return $product;
        }

        return $this->productCollection->get($id);
    }
}

最后,我們可以將數據庫訪問邏輯封裝在表數據網關中,並在工廠中使用它。 這將導致類似於Gonen I的解決方案。 它實現起來很簡單,但與數據映射器解決方案相比可能有所不同。 我從來沒有實現,使用甚至研究過這種方法,所以我說不出多少......


通過嘗試自己實現所有這些,你肯定會學到很多,我鼓勵你,但請記住,如果你需要一個認真的解決方案, ORM可能對你有意義。

如果您希望了解有關這一切的更多信息,請參閱Martin Fowler的企業應用程序架構模式一書,其中總結如下: https//www.martinfowler.com/eaaCatalog/index.html

暫無
暫無

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

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