Bulletproof Builder Pattern in TS

แชร์
ฝัง
  • เผยแพร่เมื่อ 19 ม.ค. 2025

ความคิดเห็น • 38

  • @JoshuaHernandez8a
    @JoshuaHernandez8a 2 วันที่ผ่านมา +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 วันที่ผ่านมา +13

    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 วันที่ผ่านมา +7

      ​@@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 วันที่ผ่านมา +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 วันที่ผ่านมา +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 วันที่ผ่านมา +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.

    • @vikingthedude
      @vikingthedude วันที่ผ่านมา +1

      Or just yeet an exception

  • @ericzorn3735
    @ericzorn3735 16 ชั่วโมงที่ผ่านมา

    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

  • @anthonylee1309
    @anthonylee1309 วันที่ผ่านมา

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

  • @matthewvaccaro8877
    @matthewvaccaro8877 7 ชั่วโมงที่ผ่านมา

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

  • @brayanyevenes5954
    @brayanyevenes5954 2 วันที่ผ่านมา +1

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

  • @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?

  • @yairvogel6282
    @yairvogel6282 10 ชั่วโมงที่ผ่านมา

    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

    • @andrew-burgess
      @andrew-burgess  5 ชั่วโมงที่ผ่านมา

      That would be ideal! Do you have an example of doing this well in TS? I'm not sure how you would strongly-type that...

  • @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.

  • @clingyking2774
    @clingyking2774 2 วันที่ผ่านมา +1

    which font is this please?

  • @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 วันที่ผ่านมา

    You should link your blog posts when u mention it

    • @andrew-burgess
      @andrew-burgess  วันที่ผ่านมา +1

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

  • @soviut303
    @soviut303 วันที่ผ่านมา

    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 2 วันที่ผ่านมา

    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.

  • @thoriqadillah7780
    @thoriqadillah7780 วันที่ผ่านมา

    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
    ```

  • @alex_everget
    @alex_everget วันที่ผ่านมา

    1:52 It reminds a monad

  • @glazevolda823
    @glazevolda823 วันที่ผ่านมา

    🔥🔥🔥

  • @hyperprotagonist
    @hyperprotagonist วันที่ผ่านมา

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