Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 设计模式:生成器_C#_Design Patterns_Interface Builder_Builder - Fatal编程技术网

C# 设计模式:生成器

C# 设计模式:生成器,c#,design-patterns,interface-builder,builder,C#,Design Patterns,Interface Builder,Builder,我已经寻找了一个好的构建器模式的示例(在C#中),但是找不到一个,因为我不理解构建器模式,或者我正在尝试做一些从未打算过的事情。例如,如果我有一个抽象的汽车和抽象的生成器方法来创建汽车零件,我应该能够将我所有的30个选择发送给主管,让它构建我需要的零件,然后构建我的汽车。无论生产哪种汽车、卡车、半成品车等,我都应该能够以完全相同的方式“驾驶”它 第一个问题是大多数示例将属性值硬编码到具体部分,我真的认为它们应该来自数据库。我认为这个想法是将我的选择发送给主管(从数据源),让建设者根据我的数据创建

我已经寻找了一个好的构建器模式的示例(在C#中),但是找不到一个,因为我不理解构建器模式,或者我正在尝试做一些从未打算过的事情。例如,如果我有一个抽象的汽车和抽象的生成器方法来创建汽车零件,我应该能够将我所有的30个选择发送给主管,让它构建我需要的零件,然后构建我的汽车。无论生产哪种汽车、卡车、半成品车等,我都应该能够以完全相同的方式“驾驶”它

第一个问题是大多数示例将属性值硬编码到具体部分,我真的认为它们应该来自数据库。我认为这个想法是将我的选择发送给主管(从数据源),让建设者根据我的数据创建定制产品

第二个问题是,我希望生成器方法实际创建零件,然后将它们分配给产品,而不是传递字符串,而是真正的强类型产品零件

例如,我想通过让生成器为我创建表单字段来动态创建表单,包括标签、输入部分、验证等。通过这种方式,我可以从我的ORM中读取对象,签出对象的元数据,将其传递给生成器,并将新创建的用户控件结果添加到我的web表单中

然而,我发现的每个构建器示例都只有硬编码的数据,而不是将选择从主代码传递给构建器,然后推出定制的产品。一切似乎都是一个巨大的静态案例陈述。例如,如果我有三个参数,每个参数有10个选项,我不想构建30个混凝土构建器方法,我只想创建足够的参数来制造我的产品所需的属性,可能只有三个


我很想让导演只存在于主代码中。应该有一种方法可以自动确定调用哪个具体的构建器方法,类似于多态性和方法重载(尽管这是一个非常糟糕的示例),而不是在模式中使用case语句。(每次我需要添加新的产品类型时,我都需要修改现有的控制器,这是不好的)。

我想说的是,您无法避免这两种情况中的任何一种——您的部件几乎没有重载,并且在堆栈的某个地方有一个case/if语句。在添加新类时还必须修改代码可能是您唯一的选择

这就是说,你可以通过其他一些模式获得帮助——即在建造过程中帮助你的工厂。此外,合理使用多态性(例如,所有部分都继承自某个类型,无论是类还是接口),可以减少ifs/案例和重载的数量


希望这能有所帮助。

大多数情况下,对builder模式的调用如下所示:

Car car = new CarBuilder().withDoors(4).withColor("red").withABS(true).build();

我从来没有这样想过,但是LINQ(模式,而不是语法)实际上是一个构建器,对吗

它是一个流畅的界面,可以构建查询并以不同的表示形式创建查询(SQL、内存中的对象查询、webservice查询、Bart de Smet甚至编写了一个Linq到Excel的实现)。

我将参考维基百科文章中的C#示例

第一个问题是大多数示例将属性值硬编码到具体部分,我真的认为它们应该来自数据库。我认为这个想法是将我的选择发送给主管(从数据源),让建设者根据我的数据创建定制产品

在本例中,您将拥有一个实现PizzaBuilder的类,该类知道如何从数据库检索数据。你可以用几种方法来做

一个是做一个夏威夷的比扎布造船厂。当类初始化时,它查询数据库中的夏威夷比萨饼并检索该行。然后,当调用各种构建(x)方法时,它会将属性设置为检索到的数据库行的相应字段

另一种方法是创建一个PizzaDatabaseBuilder,并确保在初始化类时传递该类型pizza所需的行ID。例如,而不是

waiter.PizzaBuilder = new HawaiianPizzaBuilder();
你用

waiter.PizzaBuilder = new PizzaDatabaseBuilder("Hawaiian");
第二个问题是,我希望生成器方法实际创建零件,然后将它们分配给产品,而不是传递字符串,而是真正的强类型产品零件

这不应该是一个问题。您需要的是另一个Factory/Builder类型的模式来初始化批萨的字段。比如说

而不是

 public override void BuildDough()   { pizza.Dough   = "pan baked"; }
你会这样做

 public override void BuildDough()   { pizza.Dough   = new DoughBuilder("pan baked"); }


DoughBuilder可以转到数据库中的另一个表以正确填写Pizzarough类

也许,构建器模式中缺少的是,对象在最后没有被销毁,因此我建议以后如果您取消了模式,可以添加这些内容……这不是您真正想要的,但是请查看以下文章:


希望这有帮助。回答得好。如果我们使用静态声明的工厂类,就不需要新的操作符。Tobiask的生成器调用也很神奇,就像jQuery一样。答案是你不需要导演的地方就是我从这一切中得到的。诀窍是将其编码为真实的。非常感谢。你越了解这个答案,你就越意识到康利知道多少。:)+如果可以的话,这不是设计模式所描述的构建器模式。该模式旨在创建同一源的不同表示。例如,一个编译器使用一个解析器,但对x86、x64和Java字节码有不同的后端。它可能与设计模式的描述不完全相同,但可以确保创建的对象正确设置了所有属性。您还可以使对象生成器使用流畅的界面。。。但这是另一个问题
 public override void BuildDough()   { pizza.Dough   = new PanBakedDoughBuilder(); }