Bulletproof Builder Pattern in TS

Поделиться
HTML-код
  • Опубликовано: 19 янв 2025

Комментарии • 37

  • @JoshuaHernandez8a
    @JoshuaHernandez8a День назад +27

    Holy cow! I didn't know that trick to type "this" as a parameter

    • @Nicholas-qy5bu
      @Nicholas-qy5bu День назад +1

      damn same, i used to validate it with zod, but i like this approach better.

    • @wlockuz4467
      @wlockuz4467 День назад

      ​@@Nicholas-qy5bu validation + type check is the way to go.

    • @Nicholas-qy5bu
      @Nicholas-qy5bu День назад +2

      @ why would you validate ? If you are in strict mode there should be no need right ?

  • @nicgeorge6126
    @nicgeorge6126 День назад +12

    Wouldn’t this be memory inefficient because you’re returning a new object through every builder method instead of modifying the existing builder using the "this" keyword?

    • @azizsafudin
      @azizsafudin День назад +6

      It is, but in the grand scheme of how bad JavaScript is with memory management, it doesn’t really matter

    • @Guergeiro
      @Guergeiro День назад +6

      ​@@azizsafudin what a little man thought... "Let's not strive to do the best code possible simply because the language has bad memory management." It's as if JavaScript's memory management issues come from developers writing inefficient code, forcing engine developers to patch the problem at the engine level. Imagine if the engine guys could dedicate their efforts solely to addressing genuine memory problems instead of compensating for inefficient coding practices. Jesus...

    • @realhamziniii
      @realhamziniii 20 часов назад +2

      If there are no references to the object that is being copied then it should be garbage collected. The cost of copying is negligible, assuming you aren't using a deeply nested object or have properties that have a lot of memory associated with it (might be an indicator of bad design!). If you are still concerned about memory inefficiency, I'd suggest researching more into immutability, copy-on-write, garbage collection, and memory optimizations done by javascript engines like V8.

    • @uidhtndht
      @uidhtndht 19 часов назад +3

      I've encountered many bugs caused by fluent interfaces that mutate the original object, where some other code is holding a reference to the original and it is unexpectedly changed.
      I have never encountered a memory problem due to fluent interfaces that create a new object on every change.
      I'll take "eliminate an entire class of bugs" over "eliminate some potential inefficiencies that have never been a real problem".

    • @HowDoYouUseSpaceBar
      @HowDoYouUseSpaceBar 19 часов назад +2

      @@Guergeiro what a little man comment... if you have memory constraints, don't use javascript!

  • @PaulSebastianM
    @PaulSebastianM День назад +4

    You could make the build fn return an Option or an Either and manually check that the object has been constructed correctly. Thought this requires more code and thus is more work, it's a better alternative when there are business rules that control the build output and you want to return a Left value with one or more appropriate errors resulting from business rules validations. This is important in situations where users must be given feedback on the results of their exact actions so that they can correct or adjust, but most importantly understand what they have to do. This is also the only way to do the build fn correctly when the actual building is dynamic and can't be hard coded, such as when the instructions (build recipe) are let's say received over the wire, or from user input.

  • @ericzorn3735
    @ericzorn3735 8 часов назад

    Unlike rust comma, we don’t have access to the build state pattern with compile safety as strong, but I think that is my favorite builder pattern

  • @matthewvaccaro8877
    @matthewvaccaro8877 17 минут назад

    I wonder how you feel about Luster (Frontend Framework using Gleam)?

  • @anthonylee1309
    @anthonylee1309 День назад

    Thanks for the great video!
    Always looking forward to your contents

  • @brayanyevenes5954
    @brayanyevenes5954 День назад +1

    Hi Andrew, I love to see strategy patterns in TS using a real working example.

  • @yairvogel6282
    @yairvogel6282 3 часа назад

    The issue here is that the pattern doesn't fit the usecase, because the type allows for the missing fields to not be populated. If you have missing properties then build should not even be defined. You can fix this by using a different type that defines build and return it only hen the minimum requirements to prduce an invoice are set

  • @wlockuz4467
    @wlockuz4467 День назад

    I used to throw errors from build method if something wasn't right. But seeing it right at the type level is a very nice convenience.
    One question I have is, why return a new object from each method? Wouldn't it be a problem if something relied on the builder's reference being stable?

  • @clingyking2774
    @clingyking2774 День назад +1

    which font is this please?

  • @markcampbell2491
    @markcampbell2491 День назад

    Great video! Could you not initialise actual with default arguments (0 for tax rate) and leave the responsibility of validating the result of the build function to the caller if the appropriate setters aren't called?

    • @Nicholas-qy5bu
      @Nicholas-qy5bu День назад +1

      you can, but it is worse for DX, you wont know until you run your code and it throws an error when building. I used to do exactly that because i didnt know you could use this as parameters.

  • @Danielo515
    @Danielo515 День назад

    Is that first argument required to be named this? That trick is neat

  • @phene-449
    @phene-449 День назад

    i love the builder pattern from java and rust, but it's pretty painful with javascript. a lot of things are painful with javascript.

  • @rodrigonovais9624
    @rodrigonovais9624 20 часов назад

    You should link your blog posts when u mention it

    • @andrew-burgess
      @andrew-burgess  19 часов назад +1

      Ah good call! I usually do, but forgot this time. Updated the description with the link, thanks!

  • @soviut303
    @soviut303 16 часов назад

    I feel like a builder should never be able to be put into a state where it can't build. For example, JQuery required you at least provide a selector to the first element in the chain. Having mandator links in the chain sort of defeats most of the benefits of chaining.

  • @Scapben
    @Scapben День назад

    great video!

  • @Greemjou23
    @Greemjou23 День назад

    Honestly I would rather have a function that takes an object that has all of these fields.
    Probably a query builder is a better use case, but generally this seems unnecessary.

  • @alex_everget
    @alex_everget День назад

    1:52 It reminds a monad

  • @thoriqadillah7780
    @thoriqadillah7780 23 часа назад

    Why creating another builder object instead of something like this
    ```
    setFoo(foo: string) {
    this.#actual = {
    ...this.#actual,
    foo
    }
    return this
    }
    ```
    Or maybe simply like the following. Much more efficient i guess
    ```
    this.#actual['foo'] = foo
    return this
    ```

  • @glazevolda823
    @glazevolda823 День назад

    🔥🔥🔥

  • @hyperprotagonist
    @hyperprotagonist День назад

    Nice, but I’m just here to track the progress of your facial hair. 😅