Click here to Land Your Dream Job! Become a Microservice Expert With This Hands-On Golang Course 👉 kantancoding.io
@fsharpfan2 ай бұрын
A builder to create a simple object? No! Just use named arguments instead of positioned arguments. If your language does not support them, then maybe you need a builder. Creating a builder takes time!
@spicynoodle74192 ай бұрын
Creating procedures also takes time. Let's write everything in main
@TeverRus2 ай бұрын
Named arguments are the best! Seriously, why write more code if you can write less code?
@trwn872 ай бұрын
Not all languages have named arguments though!
@TeverRus2 ай бұрын
@@trwn87 Screw those languages that don't have named arguments! (jk)
@trwn872 ай бұрын
@@TeverRus To be honest, kind of true... Except there is a good alternative, of course!
@fakharraza923523 күн бұрын
1. Write self-documenting code 2. Avoid magic numbers (assign variables to numbers for a dynamic approach) 3. Avoid too many function parameters (if confusing)
@i_isak14512 ай бұрын
for anyone worried that using const variables will be worse for performance since you need to create variables for values now. First of all most compilers will substitute const variables for a set value anyways and is used exactly as if you just typed the number instead. Its a win win. Secondly, you should not do premature optimization anyways since it will make your code way harder to read, maintain, refactor and change later down. Only optimize when needed, prioritize more readable code before that.
@kantancoding2 ай бұрын
Good point. Also should mention that in most cases, people won’t be needing to min max performance like this in modern applications anyways. There are many situations where readability is more important.
@halvarfАй бұрын
Context is important for that general rule. It's clearly true for your standard business and web applications, but if you are on a microcontroller or in your main game loop, you have to think about what you're doing to the compiled code. Constants are no problem anywhere of course.
@Kebabrulle48692 ай бұрын
For the last example, I would use keyword arguments (python) instead. Like createUser(name="Alice", age=30, ...). Less bloated and just as clear, and on top of that the order of the arguments doesn't matter.
@ktz1185Ай бұрын
That's exactly what I was thinking!
@kantancodingАй бұрын
Yeah, would be great if all languages had that 💯
@FlailingWildlyАй бұрын
Excellent advice. I disagree with the people who say that “self documenting code is a fallacy“. Code (small bits of functionality) can definitely be made self documenting - meaning that you should be able to understand what the function is doing by writing the code in ways that are clearer and more descriptive. However, this is not the same thing as saying “comments are bad.“ It’s not that the comments are bad, but rather that since comments are nonfunctional, it can be easy for them to fall out of step with the actual code. Comments are helpful, but they also have a built-in maintenance cost. There is definitely a place for both. If the function is complex, and cannot be easily subdivided into multiple smaller functions that are easier to understand, then yes, definitely provide well written comments for future developers. “Self documenting projects” are definitely a fallacy. README and CONTRIBUTING are critical documents for every repository.
@kantancodingАй бұрын
Couldn’t have said it better myself. I finally found the time to respond in that thread where the person said the thing about it being a “fallacy” but not sure if it will do any good
@darrennew8211Ай бұрын
I instituted a rule in my team that every directory's first check-in has to be a README file. Some of them were pretty stupid, but most of them came out pretty well, and I got kudos from a couple of co-workers for slowing them down and making them think for five seconds what they were doing before jumping into a new part of the project.
@JProgrammingTech2 ай бұрын
Thanks man, sometimes my codebases get very chaotic, these really help
@kantancoding2 ай бұрын
Yeah man, me too! Thanks for watching 😊
@leocarmopereiraАй бұрын
Just come across your channel. I love the visual effects!
@ego-lay_atman-bayАй бұрын
3:23 Except python allows named parameters, allowing you to pass in parameters in any order, just by using it's name. I'm just saying, if you're writing in python, you can use named parameters instead. Oh, and you can also force parameters to be named or positional.
@kantancodingАй бұрын
Yeah! That’s a good observation. Python is great 😊
@steampunkWizardStudiosАй бұрын
Use "Keyword arguments" or "destructuring" for the last one. If you use something like TS make the parameter a type interface.
@kopshaАй бұрын
These coding rules are great, and they could easily work across most languages. Ah, that builder pattern... It’s like a never-ending checklist: set...().set...().set...() - and just when you think you’re done, it’s like, “Surprise! .build()!” As if we haven’t been constructing it piece by piece already. Really, .build(), was that necessary?
@darrennew8211Ай бұрын
It also makes refactoring harder because any new required thing you add, you have to find all the callers and make sure they're setting it. And the build() is only needed if you're going to return a different type than the builder, which is again unnecessary in OOP.
@BiriadanАй бұрын
Not a fan of all that mutation with the builder. I’d just create the structure literal as an argument and pass that. No need for the user variable or any setter functions.
@kantancodingАй бұрын
Good point but it depends on the langauge. In many languages you'll run into the same issue with lots of constructor params.
@eturnerxАй бұрын
In Typescript, I'd use a or a type that enforced mandatory properties and made anything with a sensible default optional.
@oli_devАй бұрын
I was looking for this exact comment. This is what I do all the time, its super nice
@mra0ulАй бұрын
Love the tips. Thank you. On the last example, how would you call the create user function?
@bigboland6160Ай бұрын
first rule is so important. Im almost done my cs degree and ive worked as a grader for many computer classes. so many students hear they need to write comments, and write the most useless redundant comments ever. like legit they will write i = 0; // initializing the variable i to 0
@kantancodingАй бұрын
Yeah, I get a lot of people advocating for comments in the comments sections of many of my videos. Many of them do indeed seem like students or juniors. I’m not opposed to ALL comments but as you mentioned, many people just write useless redundant comments. I’m just trying to explain that there’s a time and a place. And usually you can avoid them.
@NickBrown79Ай бұрын
These are GREAT!!! keep em coming!!
@kantancodingАй бұрын
Thanks for the feedback! Will do!
@derechtepilzАй бұрын
The last point is a non-issue if you use a proper IDE. For example, I mainly code in Java using IntelliJ and if I encounter a function requiring many parameters I can press Ctrl+P and I get a tooltip displaying which arguments to pass and where.
@NickCombsАй бұрын
Best practice not to assume the next person is using the same or similar tool.
@derechtepilzАй бұрын
@@NickCombs In no sentence have I said that I do it or that you should just not care about it. I just said how I'd deal with it.
@NickCombsАй бұрын
If it's working, more power to you. I'm just chiming in in case someone else is thinking about leaning on the IDE in a more typical situation.
@darrennew8211Ай бұрын
@@NickCombs The likelihood you're writing a function like "createUser" and not using an IDE is vanishingly small.
@NickCombsАй бұрын
@@darrennew8211 No it's not. Text editors, CLIs, remote servers, and deployed apps exist.
@Naveh_OАй бұрын
I would argue that the second example needs some readable function for the logic of the tax ratio - that way the two bits of logic are separate. There's the calculation of the tax percentage, and there's the calculation of the tax value itself: func calculateTax(price float64) float64 { float64 taxRatio = calculateTaxRatio(price); return price * taxRatio; } func calculateTaxRatio(price float64) float64 { if price > priceThreshold return highValueItemTax; return lowValueItemTax; }
@timgerk3262Ай бұрын
Being literal, calculation of tax is what the greybeards call a Business Rule. The logic comes directly from real life, and should be unitary (not broken up.) Because we know that taxes go up periodically and vary from place to place, also take care that extrinsic business rules are somehow externalized, such as by dependency injection or service discovery.
@madbanana22Ай бұрын
but how do you use the classBuilder without a classBuilderBuilder??
@acrosstheocean25Ай бұрын
That's the neat part, you don't
@ygstuff489824 күн бұрын
With respect to parameters in a function, using an intelligent IDE (Eclipse, IntelliJ), if the function/subroutine/method is commented to describe the parameters, when writing the code to call the function, the IDE provides prompts for each argument: name/purpose, data type, and parameter position. (in Java, this is the power of JavaDoc-style comments) Very useful, to a point that programmer's expect to see that, and when they don't....who didn't document/comment correctly?!
@erichlfАй бұрын
Missing doc strings... I get that you don't want too many comments, but I shouldn't have to read the code to know what a function's effects, return types, or exceptions are.
@chillie_dudeАй бұрын
Depends. On library always document functions. For applications don't because the cost is high to maintain such comments and they very often get out of date. Any modern IDEs can show the input/output automatically. And yes it's less detailed than comments but again for apps it's not worth and get out of date often.
@erichlfАй бұрын
@@chillie_dude I'm used to developing with plenty of people that don't have a clue why a function exists, so documentation makes it where I'm answering less questions.
@vlc-cosplayerАй бұрын
"All my functions are less than 10 lines bro, just read them bro" 💀
@chillie_dudeАй бұрын
@@erichlf well it's an interesting problem but I'm not convinced just commenting every function is the only solution. if a function is tricky then yeah great go ahead. Are the people not used to read code ? It's a skill to learn and an important one, you should ask them to try more. Is your code itself clear enough. Removing magical variables, better function name, explicit variable names, smaller (but not too small!) functions etc. Can help a lot too. So a mix of some comments, more reading and cleaner code might help. Just adding comments, which increase cost of maintainance and likelihood of being wrong, might not be the only solgion
@erichlfАй бұрын
@@chillie_dude i would say not updating comments is a problem. And should be addressed. Also docstrings shouldn't be so specific that they need to be updated, since they shouldn't explain the code. If you're changing a function in such a way that the doc string is changing you're probably doing something you shouldn't do.
@coderwolfie22012 ай бұрын
Useful advice. the awkward silence at the end though.
@yvan256316 күн бұрын
Probably done on purpose because KZbin covers the last 12 seconds of a video with thumbnails for other videos.
@Rand0081Ай бұрын
The first rule is already thousands of light years away from the grasp of most developers. We are doomed.
@kenye3057Ай бұрын
When I read the legacy code , developers always give bad long name to the magic numbers, making the code more difficult to read.
@kantancodingАй бұрын
🫠 yeah naming can be difficult!
@halvarfАй бұрын
OTOH, developers who have trouble naming things tend to not be better at writing clear comments either. In the cases where the variables are only for documentation of otherwise magic numbersin the code, it can also help to put the definition and value assignment near to the point there the variable is used so you don't have to scroll around when reading.
@pepperdayjackpac4521Ай бұрын
can u give an example of a bad long name of a magic number?
@Grif_on96Ай бұрын
@@pepperdayjackpac4521 MONSTER_LANTERN_BURN_RAYCAST_LENGTH (constant) and concat_struct_of_structs_in_to_underline_separated_string (function) are some examples of my lengthy namings . And yes , this is from my code in commeriacl game :)
@jfftckАй бұрын
I would expect no better when writing comments, so what is your point? It is the whole point of code review, if the reviewer has to be told what the magic number is, or they figure it out by reading the code, it means that it should be pointed out to be renamed. This is the failure in your team, you must look out for the next developer and not rely on current knowledge.
@wsf-t7xАй бұрын
Another approach is to just ask for a struct with the required fields. The caller can instantiate the struct before calling, or on call, and (AFAIK) unless you instantiate a struct with all fields in order, then the compiler will have you specify field names. So it ends up being like a builder object, but built into the language and with no bloat shenanigans.
@kantancodingАй бұрын
Great point! Yes, Go allows us to be explicit when creating struct literals so you are 100 percent correct. This tip is more geared towards non Go devs. For example in Java you’d need a class constructor with a bunch of params same as the createUser method.
@wsf-t7xАй бұрын
@@kantancoding What the Java! lol jokes aside, i'm of the opinion that the java person should learn the go way, not the other way around. 🤣
@kantancodingАй бұрын
I’m of a similar opinion bro. The Java person should quit their job and learn Go.
@TheScottShepardАй бұрын
Spot on!
@NickCombsАй бұрын
Many times, a fn with lots of params is built in and not worth making a wrapper just to key the values with an object. In that case, I will give each passed in value a descriptive variable. Even comments are fine there.
@kantancodingАй бұрын
Good point. Sometimes it can’t be helped.
@tkenbenАй бұрын
I suppose if we were to be picky, we would need to say that function is called something even more descriptive - especially considering your updating example with diameter - like "circleAreaByRadius", literally locking in the description of the function and thoroughly documenting it. I guess my point with saying that is, there will always be a line drawn in how self-documenting the code actually needs to be.
@vrmeupАй бұрын
Great advice, thanks 😃
@kantancodingАй бұрын
Glad it was helpful!
@MandeepSingh-td2icАй бұрын
Understanding coding can be daunting in the beginning but becomes little understandable later.
@kantancodingАй бұрын
That’s kind of missing the point imo. I’m not talking about a skill issue of not understanding code here. I’m talking about when experienced devs read code, what code is more annoying to read for example 😂 You can write code such that the person reading it experiences buttery smooth nirvana 🧈
@kevintanudjaja75972 ай бұрын
so function createUser will create a user with a user that is already created?
@kantancoding2 ай бұрын
Hmm, no. By create user I mean actually persist the user. You’ll have to use your imagination for the logic in the function since I didn’t want to convolute the example with implementation details. An easy way to imagine it is that the user object in our code is different from what’s in the db. So maybe in the logic some ORM is used
@kevintanudjaja7597Ай бұрын
Ah I get it now. So this createUser func is an interface of SQL insert to a database. I thought it's a constructor for user struct in memory, so that's looks like inception to me. The builder itself is the one that will replace user "constructor" (Need to create it manually in go, because go don't have classes) of having too much parameter. Thanks for sharing
@kantancodingАй бұрын
@@kevintanudjaja7597 yes you've got it! And thanks for always supporting :)
@vlc-cosplayerАй бұрын
Django ORM has both "create" and "save", and they almost do the same thing 💀 It may be better to name it insert() (maybe with a bool "update" parameter that turns it into an upsert), so the intent is clearer.
@JeffersonPires90Ай бұрын
I've finally found someone else using Agave font face :)
@jfftck2 ай бұрын
The last example could be solved with having multiple objects that represent the type of each and passing those in, no need for a builder. The added value of this, when a new requirement to add more values, you can add to an existing object or create a new one, depending on how that value is related to existing ones. For example, take the address value, what happens when you get a new requirement that states that the house number should be separate from the through way name? If you have an object represent the value, then you can just split them and add a method to return the full address.
@BetadeskАй бұрын
So create 5 classes just to wrap primitive values instead of 1 builder class? That seems like a lot of overhead
@jfftckАй бұрын
@@Betadesk I didn’t say to make classes, structs are smaller and many languages can add methods to them and, if you’re using a language that doesn’t, you can use a function that you pass the struct into. It would add a type to a primitive and also add context.
@kantancodingАй бұрын
These are very good points and it is a good alternative but it depends on the context in my opinion. Like @Betadesk mentioned, creating 5 structs to wrap primitive types might be cumbersome. It really depends on if that type of design would benefit the overall architecture which can’t really be determined in the small example I provided.
@jfftckАй бұрын
@@gearboxworks If you don't understand the power of types, then you need to research how newer languages are using them. This is a way to avoid hidden bugs from getting into your system. I agree, in a perfect world, we would not need all of this, but I have seen multiple times where null pointers cause an error due to incorrect values are passed due to not utilizing types. One thing to keep in mind is not all languages have powerful typing systems, and anything that can help that is good.
@acrosstheocean25Ай бұрын
@@jfftck Using wrapper types is certainly very useful and robust, but wouldn't a builder object be a good balance between robustness and convenience in more trivial cases?
@sad_man_no_talentАй бұрын
3rd one recommendation use typescript interface
@SmoMo_Ай бұрын
Nice video, and I know this isn’t at all relevant to the coding points you were making..,, ,,,but that’s not how tax thresholds normally work. You would you the lower tax until the threshold is met and then the higher tax rate on what is left. Otherwise you could increase the price of an item by 1 cent and end up paying massively more in tax suddenly .
@tobeqz7065Ай бұрын
Clicked on the video just because i knew the comments would be spicy lol
@kantancodingАй бұрын
😂you’ve come to the right place
@LBCreateSpace2 ай бұрын
Great advice Ty!
@kantancodingАй бұрын
You bet!
@danielmiller8223Ай бұрын
Issue with your Magic Numbers example. Although I agree with avoiding using magic numbers and even placing the data together in a structure, the problem with your approach is that it created a side effect. My suggestion would be to send in this data to the function or to create the data structure inside the function.
@kantancodingАй бұрын
Hey thanks for the input! There is no side effect. They are constants.
@champx5Ай бұрын
could you make a tutorial on how to make a builder? you've got me curious on how to make those
@kantancodingАй бұрын
I already have one somewhere :) I think you can just search in my videos for builder design pattern
@champx5Ай бұрын
@@kantancoding Alright! I shall have a look.
@champx5Ай бұрын
@@kantancoding the funny thing is... I actually searched up builder patterns after watching this video. The first that got recommended was yours. Without realizing it I watched and when I checked your videos right now I saw the same video 😂
@yuralis123Ай бұрын
Something I don't see addressed and I am really curious about is the UserBuilder allowing developers to write bugs. What if the email should not be null. I don't think there is a way to enforce the SetEmail method being called, which could cause weird bugs down the line. A constructor lets you explicitly set if something can be null, and if it shouldn't be null you'll get an error if you don't give a value. And for those saying python and javascript doesn't throw an error so it's not always true. There are ways to allow python and javascript to be typed, which will help you find bugs like this, so please use those
@kantancodingАй бұрын
Hey thanks for the input. As to your concerns, you can simply add validation for required fields in the build() method. Same thing will have to be done with a constructor. There’s no avoiding validation in that case.
@sealsharpАй бұрын
I really dislike the common wisdom about "self-documenting code" as it is proven again and again by examples that are the simplest of simple code. I think it all starts somewhere different. And that's the distribution of logic into multiple methods when it does not need to be that way. When ever something gets so big that you might add in a comment, someone will say "just split it into descriptive methods", and yes, in the spirit of uncle bob you can split that 30 lines method into 10 simple methods. And instead of reading the code from lines 30 to line 60, the dev now has to scroll around trying to memorize 10 methods and what they do and build a mental model of how they are called. And after splitting one method into 10 methods, it's suddenly too much work to put a doc header of them, so we don't do it because we don't like tying shit after we just split that shit up for no reason. Three steps back. Lets not split up code if there's no reusing of the methods. Let's keep the code local, in context. Complex code exists, because complicated tasks exist. So you got complex code. Your coworker asks "what dos that do?" What do say? Do you go line by line saying things like "so this line checks if the first parameter is null" and so on? Of course not. Your coworker can read. Human language can is great to explain the concept of something. You will probably be able to formulate one sentence that can explain a complex block of code. Well, if you understand that code you should. And that's a good comment. Because three years later, someone will search for a bug and will find that block of code and ONE GOOD LINE may explain it better than anything else. "So what if the comments lie?" Comments are written with the assumption that code does what it is meant to do. Comments may "lie" when the code does not what it is meant to do, but in that case, the bug is the discrepancy between intended and actual behavior. You got two versions now, one telling you what it does, and one what it is supposed to do. You can now check if the assumptions where wrong from the beginning or if it's an implementation error and the fix is going to make the code do what the comment tells. That's my experience in working with complicated code.
@kantancodingАй бұрын
Yeah, you make some good points but like with everything there is a balance to be found. When I say to write self documenting code.. it doesn't implicitly mean that you should NEVER write comments.
@genechristiansomoza4931Ай бұрын
Comments should be used to tell why a certain code is there, especially for complicated logic, not what the code does. It does not hurt to have a private method that is not reused. It's pupose is to only split logic at this point.
@jfftckАй бұрын
If you can't write a simple name for what your code is doing, then it is more than likely hard to test, and that is the biggest code smell. I have been coding for over 15 years professionally, and have seen requirements change and comments still reflect the original intent, so in those cases, it is a lie on what is expected. I think it is more important to comment external APIs so you don't need to go back to the service provider's website, or you would be able to refer to older implementations when a provider breaks the contract that was given when you started using the service and would have legal grounds to ask for compensation for any losses due to service failures.
@jfftckАй бұрын
@@gearboxworks If you think comments are good, that is fine, but to say that comments are going to lead to better understanding of the code is being hopeful that the person who wrote it is able to express themselves in a completely understandable manner. My experience is that those same people write bad comments. Have you worked for a foreign company? You will quickly abandon comments and read the code to understand what is happening. It would be great if everyone could write comments that are perfect for every function, but I have experienced the exact opposite and have learned to distrust them.
@mrwensveenАй бұрын
Splitting up long and complex methods works best when you can create simple and functions that make sense on their own. Preferably these functions are pure/static, i.e. they don't change anything of importance for the calling method. Now, you don't have to scroll around anymore because the main method remains in control of the method's flow and of the object's state (if any).
@mumcarpet1092 ай бұрын
Amazing 🎉
@kantancoding2 ай бұрын
Thanks for watching!
@donnewmancanadaАй бұрын
I used to agree with the last one, but have gone back to separate arguments. Developers tend to be lazy so they would re-use existing generic classes and just keep adding properties they needed instead of passing an object with only the parameters needed for the method call. It also prevents overloading resulting in a method full of if statements. Lastly, in a well-architected n-tier application a layer should decouple its dependencies which results in the need for mapping objects between layers.
@kantancodingАй бұрын
Hmm, some good points here but in an n-tier architecture it’s imo much easier to map objects between layers as opposed to trying to aggregate params between layers. You can also have common classes between layers depending on the overall design. Either way there’s going to be some decisions that need to be made based on the business requirements. I’d also argue that this type of architecture shouldn’t be referred to as inherently “well-architectured.” I’ve seen architectures like hex arch/ports and adapters as well as onion bloat simple applications with infrastructure that added no benefit. Just made the project more difficult to maintain and made it harder for devs to onboard. Anyways, I love your comment. Thank you
@apmcd47Ай бұрын
Well, you should be using a docstring of some sort to document your code (javadoc, python docstrings, doxygen). Code reviews should pick up unaltered docstrings. Personally I don't want to read a function to find out what it does, that is what the docstring is for. I want to read it to find out how it does what it does. Too many parameters? As other have said, if your language has named arguments, use those. If not, and it has dicts/hashes, use them instead, although I suppose that is a sort of a builder. But even when using named arguments, a style-guide enforcer could complain of too many arguments.
@Vlad19989962 ай бұрын
these are very good videos :)
@kantancodingАй бұрын
Glad you like them! Thanks for watching!
@ErikBongersАй бұрын
A builder likely comes at a runtime cost. Use with care.
@Maiuna-yc2ukАй бұрын
There is no need for builder in the last case. Use struct literals, it's better, or if your language support named arguments, just use that. A better approach than these two is to use different types (might be overkill though).
@kucingoyen1Ай бұрын
Creating a new object for User is good, but I calling that using Builder is just ugly. You can miss some variables to be updated when we alter the object even if we have default value (in most cases).
@kantancodingАй бұрын
I see where you’re coming from but depends on the builder. You can add some validation for required fields.
@ericmintz8305Ай бұрын
Floating point cannot represent money accurately because you cannot represent 1/10 as a finite sum of powers of 2. Use an accurate representations like an integer containing the smallest unit (e.g. cents, pence) or a fixed point decimal type. Uncontrolled round-off errors are almighty difficult to diagnose and even harder to fix.
@kantancodingАй бұрын
Yeah you’re right but It is not a real application. Don’t have time to explain that 10000 cents is 100 dollars and doing so would convolute the actual point I’m trying to explain.
@TizzyT455Ай бұрын
That last example didn't make any sense to me. If the original createUser function was used to create a user, and you instead put a builder in its place, whats the point of passing in an already created user into a createUser function?
@kantancodingАй бұрын
Yeah, lots of people confused about this. The createUser function creates the user in the database
@ФедорУсов-м9ш2 ай бұрын
3rd rule -> You are clearly breaking 1 entity (method call) between two lines. Never seen code style like this before: a(). b(). c()
@DaKeypunchAr2 ай бұрын
You'll return the object at Every call lol
@kantancoding2 ай бұрын
Not really sure what the question is here 😂
@kevintanudjaja7597Ай бұрын
It's called fluent interface, or method chaining
@DaKeypunchArАй бұрын
@@kantancoding he's like how are you calling a method to void but you're surely not
@asagiai49652 ай бұрын
1st of all in the first question yes. Remember guys these are two different developers. So the validity of the code still true as long as the next developer is giving the val8d code.
@kantancoding2 ай бұрын
😂 bro
@shanewolff94Ай бұрын
What is the font used in the video?
@kantancodingАй бұрын
Agave nerd font usually
@saiuan4562Ай бұрын
Wait what? A method that builds a user, but its signature requires a user? The heck?
@kantancodingАй бұрын
The method doesn’t build a user. It creates a user in the database.
@KokurorokukoАй бұрын
Why would a function called createUser accept an instance of User?
@kantancodingАй бұрын
The instance of user is in the application memory. when calling createUser the user is persisted to disk e.g. a database
@skelawАй бұрын
Last point is useles eg for js/ts. Just pass an object.
@kantancodingАй бұрын
You still have to create the instance of the object using the class constructor with the same amount of params. So you’d just move the problem to the constructor. Unless I’m mistaken (it’s been a while) JS/TS doesn’t support named params.
@atabacАй бұрын
as long as its english, code is readable to me😂 assembly is very readable
@el_niño_maka2 ай бұрын
That s come clean code rules to keep your code elegant, good job*
@KlausBayer3902 ай бұрын
Which programming language is this? go?
@ραυ-ω7ν2 ай бұрын
yes
@ungrim97Ай бұрын
I am not ensure constructing a User struct to....construct a user object is great coding practice.
@kantancodingАй бұрын
🤔
@duythanh90Ай бұрын
Nowaday, just write your code then use gpt to enhance that
@kantancodingАй бұрын
Better off asking a 6th grader…
@matthewrosseeАй бұрын
While I'm a big fan of the builder pattern, I think that the example in your video is bad. The builder pattern shines when one's dealing with creating an object that has many optional parameters, but the User structure most likely requires majority of its properties to create a valid object. So, you're moving compile time checks to run time checks. You could say that you have to check if an email or a phone number is in valid format either way - ok, but then I still think it's not a responsibility of the createUser function. A dedicated Email value object that encapsulates the validation logic in a something like a factory function would be a better fit.
@kantancodingАй бұрын
I disagree. I think that the builder pattern shines when creating complex objects with many fields, even if there aren’t so many optional fields. Although, the benefits of using the pattern do increase if there are optional fields, that doesn’t negate the benefits in the cases where there aren’t optional fields. Actually, your argument about a dedicated Email object that encapsulates validation is in support of the use of a builder in this case. Not against it. That’s because in many cases, when creating an object with lots of fields like the user object, there is a series of steps like assembling parts and performing validations. A builder allows us to handle these steps at different stages prior to calling build(). This is especially useful when we are creating immutable objects.
@LinuxdirkАй бұрын
Thje formula used in the first example actually is pi * r * r and not pi * r^2. While the result is the same, those are two different formulas.
@kantancodingАй бұрын
@@Linuxdirk 😂 what?
@MiReiGi1984Ай бұрын
Rather than a builder or even a struct to hold a set of values, instead create types for each domain concept to get rid of primitive-type-obsession.
@kantancodingАй бұрын
I see your point but it doesn’t really solve the problem. For example if you have an Email type, createUser could take in fields primaryEmail and recoveryEmail both of type Email. They could still accidentally be swapped. With the builder you need to be explicit. setPrimaryEmail/setRecoveryEmail
@MiReiGi1984Ай бұрын
@@kantancoding For such cases, yes, completely agree. Though even then I will still recommend domain types over primitives to be used with the builder. That way a PrimaryEmail or RecoveryEmail field will still hold a valid Email value, and not e.g. a street address.
@MrMassarakshАй бұрын
Read code, not comments. That’s all
@akam9919Ай бұрын
Readable code, schmedable code. Make updated comments a requirement before code gets merged. Yes, comments can lie, but so can variable names, which objectively are just memory addresses with built-in comments. Their names are not for the computer, they are for you the developer. Make comment changes part of code review. You could create a function just like the one at the beginning, but if there is no circle that needs it's area calculated but some thing else that has a virtually identical formula, is the code really self-documenting? If we are okay with updating variable and function names, updating comments should be no different. Ontop of that, If I have a game that has 30 enemy types, and each attack pattern is created by a function, should I change each function name to "consecutiveNormalPunchesAttack" or "falconSmashAttack"? What if each has to conform to an interface? Should I make a private function that has the sole purpose of documenting what the attack is supposed to be like? Perhaps if there is some extra special logic, such as randomly chosen attacks that each have their own complex logic, but if I have a 20 simple enemies that basically have only simple but unique attack function, I think making extra and redundant functions is only going to make a file longer, bloated, and harder to follow. I'd rather have a clear comment that explains what the code is supposed to do, which is what the real purpose of comments is. It isn't about what the code does, it's why it's there.
@alexaneals8194Ай бұрын
Commenting is essential to code maintenance and yes they should be updated; however, comments should never describe what the code already does. Comments should include why the code was written or to encapsulate the code so the developer does not need to look at the code to use it. A comment like "x + y = z" is useless and redundant; however, a comment stating that we need to add such a such function to comply with a business or regulatory requirement warns the dev to not change the code unless that business or regulatory requirement is changed or there is an error in complying with that requirement as the code is currently written.
@gariannobinger9933Ай бұрын
These posts are good advice.
@leerothman2715Ай бұрын
@@alexaneals8194That just sounds like putting the requirements as comments in the code to me? We have better tools to capture this data.
@alexaneals8194Ай бұрын
@@leerothman2715 The problem is when the requirements are not kept with the code then bugs creep in with each release. Devs are not going to go looking through all of the requirements docs every time they change the code nor will they look at the commit statements in git or any other code repository. In reality the only time anyone looks at those statements is after everyone's hair has been set on fire with a sev 1 or 2 bug.
@leerothman2715Ай бұрын
@@alexaneals8194 Well that might be your reality, but it certainly isn’t mine. Writing & reading comments isn’t going to stop bugs, automated testing will do a much better job (especially if you practice TDD). Those tests will also let all developers know why the functionality is there. If comments are so important then why do IDE’s grey them out by default, they deliberately make them fade into the background for a reason. The application requirements are not just for developers they are for the whole team to discuss along with the stakeholders, how do you do that if is distributed all over many code files?
@igboman2860Ай бұрын
I mean go isnt really design for the user business. Why not create a struct without the abstraction
@kantancodingАй бұрын
It depends on the language. In Go you can create a struct literal and be explicit when setting the fields but this video isn’t Go specific. In Java for example, to create an instance of the user you’d need to use the class constructor which would have the same problem with the params as the create user function.
@gariannobinger9933Ай бұрын
"self documenting code" is a fallacy. Comments are not bad, they are necessary. Are they redundant with the code? They can be, but that's a good thing. Why? Because they provide a layer of confirmation, whereas code all by itself may be correct or may be wrong. Without the comments, there's no way to compare what a function was _intending_ to do (the comments), verses what it _actually_ does (the code). The problem in this video's example isn't that there were comments, its that the later developer was lazy and didn't update the comments, which is a bad developer.
@kantancodingАй бұрын
Tests should provide your layer of confirmation. Not comments. Otherwise there’s so way of knowing which is wrong, the comment or the code. Also, I’m not arguing that all comments are bad/wrong. I’m arguing that self documenting code can eliminate the need for most comments which means that when you do actually need to write comments, they are actually useful as opposed to just being redundant noise. Also, I don’t think that the dev that didn’t update the comment is necessarily bad. Many factors go into why a dev might not update comments. I’ve seen comments written so poorly that I couldn’t even understand what they were trying to explain therefore updating them was impossible.
@gariannobinger9933Ай бұрын
@@kantancoding What I was saying is that comments provide "a" layer of guidance and confirmation, not "the" confirmation. Yes certainly, there should be test cases. But in practical terms, the struggles around not knowing which is wrong, the code or the comments/tests is still valid in both paradigms, whether you're taking about comments or tests cases. Either way, when the bug report comes in, someone has to find the bug. When reading that code and wondering "hmm is this < supposed to be a
@kantancodingАй бұрын
The struggle around not knowing which is wrong 「the comments or the code」 or 「the tests or the code」 is certainly not equally valid in both paradigms. The most obvious reason being that comments are far easier to overlook than tests. In most cases, if tests are wrong, your ci/cd pipeline breaks. In the rare cases that a unit test is written in such a way that it’s wrong but still able to pass, it’s still part of a test suite and some integration test will likely break even if that unit test is somehow passing. So the odds that multiple tests that depend on some core business logic are all able to somehow pass even if the tests are wrong are far lower than the odds that some random fragile comment is neglected or simply incorrect. There are really no checks and balances in place for comments other than the reviewers eyes.. and your whole argument is that good devs don’t miss these types of things but that, my friend, is the REAL “fallacy”
@FINALLYQQQQAVAILABLEАй бұрын
Commenting and documenting are two separate things. Documenting modules, classes, methods, functions is absolutely a good way to provide information of what a module, a class, a method or a function is supposed to do. Most modern languages offer tools to write proper API documentation right in the code. Commenting lines is seldom helpful IMHO. I use to line comments only to explain unconventional bits of code that can't be cleaned up for some good reason. The reason goes into the comment. Call me a bad developer, but the only way I'm going to "update" a redundant line comment is to remove it altogether.
@cryptonative2 ай бұрын
hate comments in general, only reasons I comment is about a strange edge case or to separate code blocks in sections given a larger function not sure I agree on the 3rd one, a proper lsp can help demostrate what each argument represents
@МаксимГорюнов-м7и2 ай бұрын
What do you mean by lsp?
@romanpolishchuk45172 ай бұрын
@@МаксимГорюнов-м7иcode suggestions
@cryptonative2 ай бұрын
@@МаксимГорюнов-м7и “language server protocol”, more specifically about something called “inlay hints” which shows the types and names of function arguments
@МаксимГорюнов-м7и2 ай бұрын
@@cryptonative this is probably a level I haven't gotten to yet, thank you, I will look into it deeper
@suiboraАй бұрын
@@МаксимГорюнов-м7и LSP is already standard in most code editors. When you try to call a function in VS code or nvim, it will show you a preview, or 'hint' of the arguments and types that the function takes
@JProgrammingTech2 ай бұрын
How do you edit your videos? I wisg mine looked so clean
@kantancoding2 ай бұрын
Have you tried manim?
@venusearth66822 ай бұрын
🙌🏽🙌🏽❣️
@kantancoding2 ай бұрын
❤️
@StephanHoyerАй бұрын
example of rule two is violating first rule, priceThreshold is not a good name. higherTaxPriceThreshold would be better.
@kantancodingАй бұрын
Imo the “higher tax” part is redundant. Especially when you look at the whole statement, it’s already clear that the threshold being exceeded results in higher tax.
@StephanHoyerАй бұрын
@kantancoding surely depends on what other constants you define in that file. If only this one I'm fine
@lashlarue7924Ай бұрын
I don't really agree that code needs to be self-documented. If you have to comment it in longhand English to reduce cognitive load then you should have just written it more clearly from the outset.
@AlfredLotsuАй бұрын
the devops playlist is gone
@kantancodingАй бұрын
Hey bro. There's good news and bad news about that playlist. If you want more information feel free to DM me on Discord.
@lucemiserlohnАй бұрын
Method chaining, really? I thought Java demonstrated very well why NOT to use that crap.
@coder_one2 ай бұрын
The slogan "Write self documenting code" stands in contrast to the fact that for some reason, most Go programmers (including the language's creators) write code in such a way that most variables are meaningless, unreadable 1-3 letter "words"; functions are also exaggeratedly called abbreviations as if Go programmers were deducted from their paycheck for every letter in the code. Therefore, it should be made clear - idiomatic Go is often a contradiction of "self documenting code."
@alexaneals8194Ай бұрын
Self-documenting code is impossible. Code can only tell you what it is doing not why it was written. Most cases that I have run into where a dev has really screwed something up is not because they could not understand what the code was doing, but rather they didn't realize why the code written that way. A function returns null and the dev assumes that the function has a bug and changes the function to not return null and crashes a completely unrelated system. An address space is not initialized and a dev assumes that it's a bug and makes sure to initialize the space only to compromise the encryption algorithm (this occurred in a linux router software update that created an exploit).
@madbanana22Ай бұрын
2:25 THATS THE SAME THING AS USING COMMENTS???
@m56wr4t617 күн бұрын
no because these variables can be used elsewhere in the code, and if you need to change the values in the future, you just change them in the variable declarations
@user-tk2jy8xr8b2 ай бұрын
The last problem is easily solved by typing. Instead of practicing primitive obsession and using raw strings, wrap them. This way it'll be impossible to accidentally swap the arguments and have the code still compiling after that.
@LittleLily_Ай бұрын
Having different types would definitely help in the case shown in the video and most other cases, but there are situations where a function does actually accept multiple values of the same semantic type, such as multiple names, or multiple ages (such as to calculate who is older), etc. In those situations you usually only have two values of the same type though so it's not too bad, and if your language supports named arguments then that would be the best solution in those specific cases.
@djteejay87Ай бұрын
Creating a user struct to create a user 😂 Brilliant. Almost all modern languages support named parameters, this approach would be way clearer than the one explained. The other two pieces of advice are good ones though.
@kantancodingАй бұрын
I think you’re confusing persisting a user and creating a user object in the application as being the same thing. Hope it helps! 😊
@djteejay87Ай бұрын
@@kantancoding I understood what you were doing there, for me it's not worth to create that User class/struct. If you are working with an ORM, maybe you can use a mapped entity of the Users table.
@djteejay87Ай бұрын
@@gearboxworks I would not create an object with a builder anyway. I'd rather create a lightweight structure/class just for the sake of passing around those params. And I would only create it if the context you described applies.
@whydoyouneedmyname_Ай бұрын
I agree he should have mentioned named parameters, but we're using Golang as an example which doesn't have them, almost every startup nowadays uses a Go backend so thats perfectly reasonable
@DaSquydАй бұрын
Whether the language supports named arguments or not is irrelevant. It will always be cleaner and easier to see what the values are by a params struct. Otherwise, you'd have to check in the function itself to figure out what the arguments are. It still doesn't solve the problem of accidentally switching arguments around either. Regardless, if you find your function is taking in enough arguments to push it to the next line... you might want to reevaluate what it is you’re even doing...
@МаксимГорюнов-м7и2 ай бұрын
The last one can be avoided if different fields have different types. Overkill? NO! Useful type system