I've implemented a Builder Pattern in a project I'm working on.

I'm using this design pattern to created Fields and Components (div, tables, panel (boostrap)).

So I have a Director Component class. It makes a order for a Builder (in this case InputComponentBuilder)

class @DirectorComponent

    @builder = null

    @make = (args...)->
        @builder.make.apply(@builder, args)
        @setResult(result = @builder.getResult())
        return result

    @makeInput = (name, properties)->
        @builder = new InputComponentBuilder()
        return @make.apply(@, arguments)

Source of InputComponent Builder

class @InputComponentBuilder extends Builder

    constructor : ()->
        @input = new InputComponent()

    make : (name, properties)->
        obj = $("<input />")
        obj.attr("name", name)
        if @input.placeholder
            obj.attr("placeholder", @input.placeholder)
        obj = BuilderHelper.applyProperties(@input, obj)
        obj = BuilderFieldHelper.applyProperties(@input, obj)
        return @input

The InputComponentBuilder is for generic input fields. So if I want to create specific field like (EmailField, ZipCodeField.. etc) I will need to create another builder extended a InputComponetBuilder? or in class Director I will need to create another method makeZipCodeField and change the recipe sent to InputBuilder?

Base Class (Base class of Class Builder's result)

class @Component

    constructor : ()->
        @id = null
        @name = ""
        @obj = null
        @attrs = {}
        @classes = []
        @css = {}

    extend : (data)->
        $.extend(@, data)

    getObject : ()->
        return @obj

    setObject : (obj)->
        @obj = obj

    setName : (name)->
        @name = name

    getName : ()->
        return @name

    getPropertiesFromObjectComponent : (args...)->
        result = []
        console.log(args, arguments)
        for key, arg of args
            console.log key, arg
            result.push(if arg of @ then @[arg] else null)
        return result

Abstract Class for Fields

class @FieldComponentAbstract extends Component
    constructor : ()->
        @label = null
        @placeholder = null
        @onclick = null
        @onchange = null
        @onfocus  = null
        @onkeypressed = null
        @onkeyup = null
        @onkeydown = null
        @oninsertednode = null
        @bootstrap = null
        @onblur = null
        @mask = null

    @validate : ()->
        return true

InputComponent Class

    class @InputComponent extends FieldComponentAbstract

        constructor : ()->
            @type = "text"
            @value = ""

Calling makeInput

@cpf_field = DirectorComponent.makeInput('cpf',
                placeholder: "CPF",
                mask : '999.999.999-99'
                bootstrap: true
  • 1
    Very bad english makes it hard to make sense of the question or improve it. Dec 10, 2014 at 16:08
  • It's Coffescript Dec 10, 2014 at 16:42
  • I am not familiar with Coffescript but from what I can decipher this might not be a proper Builder pattern to begin with. In general, a Builder is used to set a large number of properties that are required to set an object. That is, rather than a constructor with 20 parameters, you make 20 calls to a Builder's methods. You end the chain with a call to a method that returns the constructed object. Is that what your code example is doing?
    – user22815
    Dec 10, 2014 at 16:46
  • I set all argument in @input.extend(properties). it do include properties to object. Dec 10, 2014 at 16:54
  • I added the other classes @Snowman Dec 10, 2014 at 17:00

1 Answer 1


To answer your original question (in title), a Builder is by definition a very stateful object, so after issuing the final "build" and obtaining the constructed object, the Builder is discarded - never re-used.

  • 1
    StringBuilder is reused quite a lot, it's never in a "final"state internally.
    – jmoreno
    Sep 24, 2015 at 4:25
  • True. I should have said: "never re-used in a new context" Sep 25, 2015 at 6:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.