繁体   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