0

My sample code:

class CitiesListBuilder{ private List<String> cities; public static CitiesListBuilder newBuilder(){ return new CitiesListBuilder(); } private CitiesListBuilder(){ cities = new ArrayList<>(); } public CitiesListBuilder addCity(String city) { cities.add(city); return this; } public CitiesListBuilder apply(Function<List<String>, List<String>> filter) { cities = cities.apply(filter); return this; } public List<String> build(){ return cities; } } 

To use:

CitiesListBuilder.newBuilder .addCity("LA") .addCity("NY") .apply(NorthCitiesFilterFunction) .build(); 

I understand my code maybe a bad sample of using builder pattern, but to me it makes the code shorter and more clear (my own opinions), and I don't see any problem with concurrent issue.

But to your opinions, what will be the arguments if I should/should not do the code likes this?

Thank you.

16
  • 1
    There are easier ways to create a List<String>. No reason to create this builder class. For example - List<String> cities = Arrays.asList("LA","YA") (if it's OK for the List to have a fixed size). Commented May 23, 2016 at 9:14
  • Hmmh I think my sample code was a bad example for what Im trying to do, let me edit it Commented May 23, 2016 at 9:16
  • 1
    I think the addCity isn't part of the builder pattern idea. What seems to be against the builder pattern is that in the build method you are returning something that already exists. You should return a new instance. You've got a builder with the same name as the inner class builder. Also, you don't create an actual instance of something you've defined. You just return an instance of an ArrayList.. Your whole classes seems to serve the only purpose of building an ArrayList. It's quite an overkill implementation. Also the use of a filter immediately after creation seems be redundant. Commented May 23, 2016 at 9:21
  • 2
    I am a bit reluctant to call this "Builder" pattern. It is not quite what the GoF Builder Pattern is doing. You may call it a Fluent Builder instead. But there is never a concrete definition on what a Fluent Builder is (except it provides a fluent interface and assist you to create an object) Commented May 23, 2016 at 9:29
  • 1
    This is not the builder pattern. It is just a wrapper to ArrayList. Naming a class Builder does not make it a builder. Commented May 23, 2016 at 9:34

4 Answers 4

1

I am a bit reluctant to call this "Builder" pattern. It is not quite what the GoF Builder Pattern is doing. So, if you are asking for GoF Builder pattern, then almost everything you wrote does not align to Builder pattern, as what you wrote is simply not relevant.

However, we usually call what you are doing the "Fluent Builder" (or Fluent Interface) instead. There is never a clear definition on what a Fluent Builder is, except it provides a fluent interface and assist you to create something. An interesting example is, in Apache Commons Lang, you will find things like EqualsBuilder, HashCodeBuilder and CompareToBuilder, which provide fluent interface to let you provide the data to come up with the final result. Given there is no clear definition for meaning of "Fluent Builder", there is nothing we can comment whether it is "against" the pattern.

Sign up to request clarification or add additional context in comments.

2 Comments

You made the point! I think "build" & "builder" made it confusing. For now, I will just call it Customizer. Thank you @Adrian
By convention people usually name this ~Builder. I don't think it is a problem keep calling that, as long as you know it is something other than the GoF Builder pattern
1

It doesn't matter whether it's "against" the builder pattern.

but to me it makes the code shorter and more clear

That's what matters. If you're writing the code for yourself, then it's the only thing that matters. If you're hoping to collaborate with others, then it helps if it also make the code more clear to your peers.

Your class is a tool that you find useful for building a list of cities. CitiesListBuilder sounds like a good name for that. It would be more builder-y if it built a class named CitiesList, but maybe you don't need that...

...yet.

Comments

0

The aim of the builder pattern is to offer an abstraction for several builders with the same interface, in order to create product objects the same way, even if they are different in type (product objects could implement the same interface or have a common ancestor) and parameters. If your need is only to create one type of object using only one type of builder, you are only over-complicating things.

2 Comments

So if we take builder pattern out of the context, and forgetting about builder and build, would there be a better way to archive what Im trying to do ?
I don't know what your NorthCitiesFilterFunction does, but what's wrong with List<String> cities = new ArrayList<String>(); cities.add("LA");?
0

This is definitely not canonical builder. Your class seems to be populating list with strings, filtering them and then returning that list. Plus builder should always use 'return this' which your does not. Plus your builder initializes itself at the beginning, which is also bad practice and confusing

2 Comments

well... I can see return this in all meaningful spot. Where are you referring to that should return this but is not doing so now? And, I don't know what your "canonical builder" is referring to, and it is not uncommon to have initialization of fluent builder happening in the "beginning"
@AdrianShum public List<String> build() seems completely redundant, since it does not "build" anything, it returns the list with cities.I mho, "fluent builder" is a crutch devs sometimes use for readability,but I would say it is better to not use builder at all if you cannot follow the builder pattern completely,just hack itThe method addCity() is indeed correct form of builder if you so wish to create list through builder,but the apply() method has no place in the builder,since it directly manipulates the state of built object,which is asking for trouble and introduction of side-effects

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.