- something is done to object when some props is set or validation, such as .withStuffedCrust("cheese"), it'll set the internal props as crust="stuffed" and stuffContent="cheese"
- it's branching. So rather than making user looking for the components or configuration themselves, library author can guide them with builder. Such as:
In this case withTrailerAttachment (and possibly withOpenBack or withBox) won't show up if you call withTwoTires(), and attach won't show up if you don't call withTrailerAttachment().
In my example the could matter, or not. I see this all the times. In your example, can you make the order matter? In my example, after each selection, you can limit or expand the further options.
Nothing to stop you from doing the same within the code of the multi-parameterized single function, is there?
if Shrimp in Fillings then begin
Add(Shrimp);
Add(ShrimpOil); // So yummy together
Fillings.Remove(Jalapenos); // Don't go together
end;
if Jalapenos in Fillings then begin
Add(Jalapenos);
end;
In your case you would end up calling your function like this: DoToppings(true, false, true, true);
Whereas in my case you would call the builder directly with (only) the params you want different than the defaults.
You could use named arguments, but that doesn't solve the problem completely. You will still have a large method signature, hard to use, harder to refactor, harder to test, error prone.
It also causes a lot of redundant code: the called usually only cares about one or 2 arguments, it's rare that you *need* to pass more. The rest of the args are filled in by defaults in the implementation. There could be elegant ways to handle the defaults, like overloading methods or just passing in defaults in the method signature. Default value are pretty bad IMO, for all the reasons above. Btw, if you *need* to pass that many arguments to a function, that is another code smell worth it's own discussion.
Multiple overloaded methods could have about the same amount of code int he implementation like the builder pattern, but they have a huge drawback: the caller cannot mix and match which arguments they want to pass in. If you have 4 arguments, there would be quite a high combination of parameters (18 possibilities? - 18 functions); Using the builder pattern you have to implement 4 methods only, and you're covering all the possible combinations the client might want. You can also limit some combinations in elegant ways right in the IDE while the developer is writing the code.
Think of FluentAssertions https://fluentassertions.com/introduction They have literally hundreds of possible assertions that are represented by object instances. You can combine them in an almost infinite number of possibilities.
Sure, there is no black and white, and depends on the language, the builder pattern is a good tool to have in the toolbox.
> You just moved the problem to a different layer.
No, I think you're misunderstanding. Weird... Aha: My fault, sorry.
> In your case you would end up calling your function like this: DoToppings(true, false, true, true);
What?!? Heck no, that wasn't what I meant, why would you think that? [Goes repeatedly clicking "parent"] Aha, I see: Sorry, the threads and sub-threads have branched so I got confused as to where we are.
No, that wasn't what I meant at all. I got this sub-thread mixed up with sibling ones, and was talking in the context of languages with native enums and sets (roughly, Pascal and its descendants), where you do:
type PizzaFilling: (tuna, shrimp, peperoni, ham, gorgonzola, jalapeno) ; // Etc, etc...
PizzaFillings: set of PizzaFilling ;
function MakePizza(PizzaFillings);
And then the body of function MakePizza uses that set as per my GP comment.
It's called not with a bunch of anonymous booleans like you wrote, but with a set of enumerated descriptively-named fillings as a parameter; say, a TakeOrder function builds this set by starting from an empty one (or perhaps tomato and cheese already in as defaults?) by the customer's specifications, and then calls
MakePizza(OrderedFillings);
> Sure, there is no black and white, and depends on the language,
Yeah, I was attempting to show how the problem you mentioned doesn't exist in languages with better / saner types. Again, sorry for getting the contexts mixed up; I though that was what you were talking about too, and just didn't get.
> the builder pattern is a good tool to have in the toolbox.
Urgh, yeah, I suppose so... At least in languages where you need it, because they lack other more basic (Heh!) amenities.
function pizza(boolean pepperoni, boolean bacon, boolean mushroom, boolean artichoke)
breaks down when you want to add ham, potatoes and sausages to the pizza.
Secondly, you can optimize for the common case:
fn pizza() # -> default pizza e.g. margherita
fn pizza(list_of_ingredients) # -> your custom pizza
if you we are talking of simple functions and not more complex patterns, such as piping, in Elixir I would do
pizza |> add_ham |> add_mushroom |> well_done
when using boolean parameters you are also passing down a lot of useless informations (a pizza with pepperoni would include 3 false just to remove the ingredients from the pizza and only one true) and confining yourself to a fixed set of options, that could possibly also represent an impossible state.
> I don't care who invented it. It sounds fucking terrible.
Sorry, but why should people care about what sounds terrible to you?
> put some mashed potatoes in your rice and some pasta in a sandwich while you're at it
If you weren't too obsessed with yourself, you'll know that that pasta actually exists, it's called "pasta e patate" and someone has put it in a sandwich for sure...
there is also a very popular variant made of pasta, potatoes and mussels.
> It's like someone said "what type of carbs would you like with this meal" and the answer was "yes".
It's like someone asked you "what are you first World problems" and your answer was "yes"
The recipe I'm talking about come from Italian rural tradition, when people were poor and carbs were the only thing they could afford to eat to keep being alive, not a privileged people's self inflicted fictional problem.
Sorry for the brutal honesty.
But you anglophones are not qualified to judge other culture's food. Your food is usually terrible.
> Sorry, but why should people care about what sounds terrible to you?
I never asked you to care what sounds terrible to me.
Opinions are like assholes. Everyone has one, most are full of shit, and I don't really care if you don't like mine.
If you supposedly don't care what I think, why bother trying to tell me my opinion is wrong? You can't have it both ways.
> you weren't too obsessed with yourself, you'll know that that pasta actually exists
Ok sure buddy. It's totally on me that a meal that may consist of entirely carbs is not common/popular outside of Italy. Totally my fault.
> It's like someone asked you "what are you first World problems" and your answer was "yes"
Eating a diet of just carbs is literally not a first world problem, it's a 3rd world problem because people can't afford (or can't adequately store) proteins, fresh vegetables etc.
> when people were poor and carbs were the only thing they could afford to eat to keep being alive, not a privileged people's self inflicted fictional problem.
People have eaten much worse sounding things than your double-carb special, no doubt. The difference is - you're bollocking on like it's a perfect meal, and the idea that it doesn't sound appealing is apparently insulting to you.
Who could have possibly ever foreseen that a dish made out of necessity because people literally had nothing more than two kinds of otherwise bland starchy carbohydrates, would not seem appealing when other options are available?
An opinion isn't brutal honesty bub. You have one, I have one. The difference is I am well aware that mine is an opinion.
Good job on the generalisations though. "the food of half a billion people is usually terrible, here come try some carbs on carbs.".
I love potatoes on pizza and order it at multiple pizza places. They add flavor and creaminess. The secret is to cook the potatoes properly and not just throw some french fries on the pizza.