一种创建多个对象的方法还是几种创建单个对象的方法?

时间:2020-03-05 18:55:44  来源:igfitidea点击:

如果我有以下情况:

Public Class Product
    Public Id As Integer
    Public Name As String
    Public AvailableColours As List(Of Colour)
    Public AvailableSizes As List(Of Size)
End Class

我想从数据库中获取产品列表,并将它们及其可用的尺寸和颜色显示在页面上,

  • 有一个方法(GetProducts()),该方法利用连接相关表的单个视图,然后循环浏览每一行并根据需要创建对象?或者
  • 有几种方法仅各自负责创建一个对象?例如。 GetProducts(),GetAvailableColoursForProduct(id)等

我目前正在做a),但是当我添加其他属性(多个图像,可选的流苏等)时,代码变得非常混乱(必须检查与上一行产品是否相同,该颜色已经已添加等),所以我很想与b)一起使用,但是,这确实会增加到数据库的往返次数。

解决方案

回答

就个人而言,我将通过较少的方法从数据库中获取更多数据,然后将UI仅与当前要显示的数据集部分绑定。管理大量用于提取特定数据块的小型方法比获取大型块并仅使用所需的部分要困难得多。

回答

你说对了。解决方案b不会扩大规模,因此就性能而言,解决方案a是关键。同时,为什么还要限制GetProductDetails()方法来在单个请求中获取每个数据(因此采用SQL视图方法)?为什么不让此方法执行3个请求并告别混乱逻辑:

  • 一种用于ID和名称检索
  • 一个用于颜色列表
  • 一份尺码表

根据我们使用的SQL引擎,这3个请求可以组合在一个批处理查询中(一次往返),或者需要3次往返。在向类添加其他属性时,我们将不得不决定是增强第一个请求还是添加一个新请求。

回答

在上述情况下,我可能只有一个静态加载方法,尤其是在通常需要全部或者大多数属性的情况下:

Public static function Load(Id as integer) as Product

Product.Load(Id)

如果说color属性很少使用且加载起来相当昂贵,那么我们可能仍要使用上面的内容,而不是从那里加载color属性,而是从getter中动态加载它,如下所示:

private _Colors as list(Of Color)
public property Colors() as List(Of Color)
    get
        if _Colors is nothing 
            . .. . load colors here
        end if
    end get. . . . .

回答

选择选项b),它使属性独立于数据的表示方式(例如表格)

我认为我们将从了解有关MVC体系结构的更多知识中受益。它代表模型(数据->产品),视图(演示->表)和控制器(一个新的类,它将从模型中收集数据并对其进行处理以产生View输出)

使困惑?没那么复杂。代码段来自哪种语言?诸如Ruby on Rails,Java Struts或者CakePHP之类的许多框架都在实现程序层的这种分离。

回答

b在读取设置时会更快(从性能角度考虑),但在更新类(更新每个功能)时将需要更多维护代码。

现在,如果性能是真正目标,则只需对其进行基准测试。编写a和b,用数以百计的数千条记录加载和测试数据库。然后选择最佳解决方案。 :)

/维

回答

如果我们在编码实践中使用任何敏捷租户,那么" a"暂时适用,但是随着查询复杂性的增加,我们应考虑进行重构,即根据我们现在所知道的内容构建代码,并在必要时进行重构。

如果我们要重构,建议我们将工厂模式引入代码中。工厂模式管理复杂对象的创建,并允许我们从使用该对象的代码(在本例中为UI)中隐藏对象构造的详细信息。这也意味着,随着对象变得越来越复杂,将保护使用者免受我们为管理复杂性而可能需要进行的更改。

回答

我们可能最好同时进行基准测试和找出答案。我见过这样的情况:仅执行多个查询(MySQL就是这样)比JOIN和一个大的慢查询要花很多内存并导致DB服务器崩溃的情况。我说基准是因为它将取决于数据库服务器,它具有多少内存和并发连接,表的大小,如何优化索引以及典型记录集的大小。大的未索引列上的JOIN非常昂贵(因此,我们不应该这样做或者添加索引)。

如果我们至少编写了两种实现方式(我们无需编写方法,只需编写一堆测试查询),然后再进行基准测试,则可能会学到更多/更满意的结果与一个或者另一个一起去。测试中最棘手(但很重要)的部分是模拟并发用户同时访问数据库-实际的生产内存和cpu负载。

请记住,我们要处理两个问题:一个是DBA问题,如何使它最快,最有效。第二个是想要漂亮,可维护的代码的程序员。 (b)使代码更具可读性和可扩展性,而不仅仅是具有复杂的JOIN的大型查询,因此,只要它的运行速度不会大大降低,我们可能会决定优先于(a)。

回答

我们应该查看Castle的ActiveRecord ORM,它在NHibernate之上运行。我们将开发一个数据模型(就像我们对" Product"所做的一样),该模型继承自AR的基类,并提供了强大的查询功能。 AR / NHibernate提供了积极的查询优化和缓存。性能和可伸缩性问题可能会消失。至少我们有一个不错的框架可以在其中进行调整。我们可以轻松拆分数据模型以测试B。