3

Two popular patterns for configuration in JavaScript are the builder pattern and the options object pattern:

Builder

var importer = new LeadImporter()
    .assignLeads(true)
    .source("source")
    .organization(organization)
    .setLeads(leads)

importer.processP().then(function() {
    ...
})

Options Object

var importer = new LeadImporter({
    assignLeads: true,
    source: "source",
    organization: organization
})

importer.processP(leads).then(function() {
    ...
})

Are there best-practices guidelines which dictate which pattern to adopt? Is one pattern more performant than the other? Under what circumstances should one pattern be adopted over the other?

moismailzai
  • 233
  • 2
  • 10
Tyler Brock
  • 28,818
  • 15
  • 75
  • 77
  • 1
    Really? I think this is a good question. Not much information about when to choose either pattern out there. – Tyler Brock Sep 09 '15 at 18:40
  • 1
    I don't believe I've ever seen the builder pattern in JavaScript. FWIW, the __Java__ answer in the sidebar is pretty clear on when to use each (and was also closed.) – Mathletics Sep 09 '15 at 18:42
  • 1
    I'm not interested in why for Java a particular pattern makes sense. I'm interested in the a JavaScript programmer's approach to this. Javscript doesn't require thread safety and I'm not comparing it to the Factory pattern. Both approaches are very common. – Tyler Brock Sep 09 '15 at 18:44
  • 3
    Why would the underlying language matter in the case of a design pattern? I'm a JS developer, and the Java answers make perfect sense to me as applied to JS. Regarding _a JavaScript programmer's approach_, as I said, I've never seen the builder pattern in JS. I use options hash every single day. Either way, this is a 100% opinion based question; it doesn't matter, technically speaking. – Mathletics Sep 09 '15 at 18:45
  • Ok can you link me to the one you are looking at? – Tyler Brock Sep 09 '15 at 18:47
  • http://stackoverflow.com/questions/328496/when-would-you-use-the-builder-pattern – Mathletics Sep 09 '15 at 18:47
  • I would add, snidely, that if you're using constructors, you _are_ interested in the Java approach. :-p – Mathletics Sep 09 '15 at 18:48
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/89194/discussion-between-tyler-brock-and-mathletics). – Tyler Brock Sep 09 '15 at 18:51
  • @Mathletics There are definitely idiomatic ways of doing things depending on the language being used... it's not all a question of preference. – plalx Sep 09 '15 at 20:03

1 Answers1

3

Just a side note about your builder pattern example:

Your example does not really fit into the builder pattern: A "builder" should have a function build() (sometimes called get() or construct()) which returns a new object of the target class.

In your example, the instance itself appears to provide builder functions (source("source") etc.). This has many drawbacks: The object can be in an arbitrary state during execution and you need to put a lot of effort into checking the state of the object whenever another part of the program calls a function of that instance. Furthermore, this defaces the public API of your class by mixing instance and builder functions. It makes debugging harder and your code less readable.

If you have a class LeadImporter, you could create a LeadImporterBuilder which provides functions to actually build an instance of LeadImporter (that's why we call it the builder pattern). The LeadImporter should therefore be created

In modern JavaScript, options objects are far more popular. In JAVA, the builder pattern is great, but JavaScript is dynamic enough not to enforce such verbosity. In fact, I can remember very few to none actual uses of the builder pattern in JavaScript.

In JAVA, the builder pattern is very common and a great idea. If you need to configure many properties of an instance, it is much better than invoking a constructor with a lot of unnamed parameters. It is also more flexible by providing the possibility to use multiple varargs arguments in different builder methods. Additionally, the values can still be final within the instance of the resulting class. Another advantage is that some parameters might be optional and it is much more convenient not to call the according builder functions instead of passing null to the constructor of the class itself or creating multiple constructors, depending on the arguments you might want to pass.

Let's look at those four arguments in JavaScript and the alternative options object:

  1. There are no unnamed parameters. In an options object, every parameter gets a name. Instead of .source("abc"), you can simply use source: "abc".
  2. Varargs in JavaScript are something totally simple. But they are unnecessary with an options object because you can just pass an array within the options object. Use files: [ 'a', 'b', 'c' ] instead of files('a', 'b', 'c').
  3. You can still make properties "final" with the options object, just configure them not to be writable. However, the concept of "final fields" does not exist in JavaScript. Does not really matter, it is still possible to create immutable objects, even using the options object.
  4. Simple: Instead of not calling a function, don't pass an option through the options object.

In my opinion, the builder pattern has no advantages over an options object -- at least in modern in JavaScript.

Community
  • 1
  • 1
Tobias
  • 7,603
  • 1
  • 26
  • 43