【问题标题】:Is it suitable if Builder Pattern construct object from database value instead of parameter input如果Builder Pattern从数据库值而不是参数输入构造对象是否合适
【发布时间】:2019-02-24 05:11:54
【问题描述】:

计划使用构建器模式,但我不确定它的正确使用方式。 这里, 1) 从数据库或 API 中提取数据并构造对象 2) 发布到 API

所以,看起来,这个 Builder 设计模式套件如下:

我没有看到使用构建器模式通过从数据库读取数据来构造对象的示例。从数据库或 API 检索数据中限制对象时是否合适的模式,或者,它的错误设计? 示例:

public class ResultBuilder
{

    private IList<Parts> _parts; 
    private IList<Dealers> _dealers;

private int resultSetId;
    public ResultBuilder(int resultSetId)
    {
        this.resultSetId = resultSetId;
    }

    public ResultBuilder PrepareParts()
    {
        //call to PartsService and pull from database based on resultSetId and prepare List<Parts>.

    }
public ResultBuilder PrepareDealer()
    {
        //call to DealerService and pull from database and prepare List<Dealer>.

    }

    public IList<Dealers> Build()
    {
        //Build Dealers and Parts mapping for Dealer.Parts and return;
        //submit to another service.
    }
}

客户:ResultBuilder.PrepareParts().PrepareDealer().Build();

【问题讨论】:

    标签: c# design-patterns builder fluent facade


    【解决方案1】:

    使构建器以这种方式填充对象的主要问题是您的构建器将能够以这种方式创建事物。

    例如,下个月,您可能会发现需要使用从其他地方获取的类似数据构建其中一个对象。

    保持separation of concerns(或“单一责任原则”SOLID 中的 S)会更灵活,方法是将构建器保持为构建器,并使用不同的类协调获取数据并将其传递给构建器。

    “错误的设计”是按照你描述的方式做的吗?设计决策是非常主观的,应该基于当时已知和预期的需求。例如,反对我建议的设计原则是YAGNIRule of Three

    换句话说,你必须平衡灵活性的增加和代码数量的增加。

    【讨论】:

    • 在这里,在客户端方法上,首先拉取resultSetId,然后传递给resultBuilder 以构建零件、经销商和构建对象(提交并返回响应)。在内部,PrepareParts 将调用 PartsService 与存储库交互并为 PrepareDealers 提取数据。但是,客户端方法 (Main[]) 只会传递 resultSetId 并且没有任何参数进一步构造对象。这是现实的场景还是我必须从客户端方法(Main [])本身调用partsService或dealerService而不是与builder Pattern一起使用?
    • 另外,基本上,这里是通过调用不同的serviceRepository 来构建和准备的一个对象。
    【解决方案2】:

    不确定您是否可以“建立”经销商,除非这是一家商店。相反,将 Dealer 作为 Director 对象调用自己的 Construct 方法,该方法接受 Builder 对象作为参数。

    构建器模式需要一个由 1 个或多个构建器类组成的 Director 类。生成器类生成零件。

    您可以创建一个抽象的 Builder 类,并为摩托车、汽车或船舶零件创建具体的构建器。这些构建器提供了一种方法来返回他们托管的产品,这些产品是此实例中的部件。

    【讨论】:

      【解决方案3】:

      您应该考虑步骤PrepareParts().PrepareDealer()是否是强制性的,以及它们是否可以省略。而且,就此而言,操作顺序是否重要。

      如果所有步骤都是强制性的,并且您必须按顺序执行,那么构建器不是一个好方法。

      接下来您应该考虑的是是否要更改步骤的数据提供者。然后你需要某种依赖注入到你的构建器中。例如,您可能希望从数据库、磁盘或 Web 服务中获取数据。

      最后你应该考虑这段代码应该做什么:

      var rb1 = ResultBuilder.PrepareParts()
      var rb2 = rb1.PrepareDealer();
      var rb1Built = rb1.Build();
      var rb2Built = rb2.Build();
      

      您经常会在流畅的设计中看到很多return this;。这会导致意想不到的行为。如果您创建了一个在您调用 Build() 时执行的操作管道,并且您总是执行 return new ResultBuilder(...);,那么您可以构建一个可靠的流式设计。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-12-18
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多