Design Pattern: Builder

╄→尐↘猪︶ㄣ 提交于 2019-11-28 20:23:31
RS Conley

I am going refer to the C# example in the Wikipedia Article here.

First problem is most examples hard code property values in to the concrete parts, which I really think should come from a database. I thought the idea was to send my choices to the Director (from a data source) and have the builder create a customized product based on my data.

In this case you would have class implementing PizzaBuilder that knows how to retrieve data from a database. You can do it several ways.

One would be make a HawaiianPizzaBuilder. When the class initializes it queries the database for a Hawaiian Pizza and retrieves the row. Then when the various Build(x) methods are called it would set the properties to the corresponding field of the retrieved database row.

Another would be just makes a PizzaDatabaseBuilder and make sure that when you initialize the class you pass it the ID of the row you need for that type of pizza. For example instead of

waiter.PizzaBuilder = new HawaiianPizzaBuilder();

You use

waiter.PizzaBuilder = new PizzaDatabaseBuilder("Hawaiian");

Second problem is I want the builder methods to actually create the parts then assign them to the product, not pass strings but real strongly typed product parts.

Should not be an issue. What you need is an other Factory/Builder type pattern to initialize the fields of the Pizza. For example

instead of

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

you would do something like

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

or

 public override void BuildDough()   { pizza.Dough   = new PanBakedDoughBuilder(); }

DoughBuilder can go to another table in your database to properly fill out a PizzaDough Class.

Mostly the call of a BuilderPattern looks like this:

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

I've never thought about it this way, but LINQ (the pattern, not the syntax) is actually a builder, right?

It's a fluent interface that builds a query and can create queries in different representations (SQL, in-memory object queries, webservice queries, Bart de Smet even wrote an implementation of Linq-to-Excel).

I would say that you cannot avoid either of these - having few overloads for your parts and having a case/if statement somewhere down the stack. Also having to modify your code when adding new class might be your only option.

That being said you can get help with some other patters - namely Factory that could aid you in the building process. Also sensible use of polymorphism (e.g. all parts inherit from the some type be it class or interface) can reduce the amount of ifs/cases and overloads.

Hope this helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!