Handmade Hero | Private Data & Getters/Setters (Epic rant!)

Поділитися
Вставка
  • Опубліковано 25 гру 2024

КОМЕНТАРІ • 279

  • @debasishraychawdhuri
    @debasishraychawdhuri Рік тому +40

    Java even created a framework to generate getters and setters.

  • @icemojo
    @icemojo 2 роки тому +74

    This video is 7 years old when I stumbled upon it. If my younger self from 6 or 7 years ago saw this, he would have totally frowned upon this rant and label it as unnecessarily defensive, one-way, narrow mind opinion. But at this point today, after about a decade of experience in the software industry (which is not a lot by the way), I totally agree with Casey.
    I saw enough of OO design choices (especially bad ones) that were usually resulted from arbitrary abstractions, which eventually leads to more harm than good down the line. Getters/setters have their own places, but only for very, very specific cases. OO concepts like "encapsulation" tries to denote that hiding data is a good thing to do, and programmers slowly start to take those things like mandates, and hide everything behind getters and setters by default.

    • @CaptainWumbo
      @CaptainWumbo Рік тому +5

      I'd say that's about my experience too. All these rants seemed silly to me when I worked as a contractor and did whatever made sense to me. Having worked in bigger companies now, I see all too clearly how this goes wrong and totally dogmatic crazyland. So many things in projects I maintained that I'd try out, see bad results and throw away are now enforced by linters and other nonsense. It all boils down to the business gets big enough that it doesn't trust its programmers and little by little takes away all opportunities to learn and improve with misguided policies in a vain attempt to prevent programmers from shipping bugs while ironically making the bugs that do get shipped so much nastier and inscrutible. Hidden callbacks and the like, especially in higher level languages.

    • @chrisc7265
      @chrisc7265 Рік тому +1

      @@CaptainWumbo agreed --- these days people are afraid of scaling by delegation of responsibility to team leaders, and instead attempt to control everything by yielding to universal "best practices"
      it's enough to get by so it persists, but it's never going to compete with a team of good people who are given a long enough leash to solve problems efficiently

    • @vytah
      @vytah 10 місяців тому +3

      If the data is behind trivial getters and setters, it's not hidden at all.

    • @leadensage
      @leadensage 5 місяців тому +2

      Nearly 15 years in programming and I disagree with him even more than I would have 7 years ago. His view does seem narrow-minded because it seems to have been shaped specifically by his experience in low-level gamedev in C/C++.
      Making everything public is one of the worst API design decisions I can think of because it increases your API surface area and makes it harder to work with and invites bugs and monkey-patching from people who don't know any better. Perhaps his approach works for in a small team where everyone is as smart as he is but in the real world it doesn't work like that.
      Everything should go private at first unless you're absolutely sure you need a particular field to be a part of the public API of your class. Going the other way around is extremely difficult once your project becomes big enough and lots of places start to depend on all you public stuff.
      Trivial getters and setters do look ugly but that's an issue of the language. In C# for instance it's `public Smth { get; private set; }` for readonly public access or `public Smth { get; set; }` for full public access, which you might as well replace with a plain public field without accessors.

    • @GeorgeTsiros
      @GeorgeTsiros 3 місяці тому

      When you're given a tool but no instructions on how to use it... you get this.

  • @ChrisAthanas
    @ChrisAthanas 3 роки тому +37

    Finally someone says what I think the first time I saw this in Java

  • @paulmartinlopez.
    @paulmartinlopez. Рік тому +6

    Thank you so much for these clips! Please do not delete them 😭😭

  • @doktoracula7017
    @doktoracula7017 3 роки тому +76

    I agree, his stance is pretty much "don't abstract prematurely". Which is a good stance. Often it's really hard to fix wrong abstractions and additional boilerplate that doesn't make it any different than a public field (other than to force you to type more) just destroys readability and intent of code.
    By the way, I don't remember using a setter in last few years. Getters yes, but not setters.
    Firstly, get/set doesn't differ much from public field. And if you need some behaviour when setting something then it shouldn't even be called setVariable, because that doesn't describe the behaviour.
    Most of the time if you need to set something that means you should move this code to the class of that object. Setting value of field responsible for width of rectangle? Create a function rescaleX(double scale) and done. Setting value of field to save it to file? Replace it with constructor injection and call save().
    Truly, I can't find a good reason to write a setter, maybe one case is when you write an ORM, though you could do without setters too, but in some cases it may be worse without them.

    • @vexedev
      @vexedev  3 роки тому +18

      THIS^
      Lot of people below seem miss the point completely.

    • @franciscofarias6385
      @franciscofarias6385 3 роки тому +1

      If you wanna always check the value against some conditions before setting it a setter is perfect

    • @doktoracula7017
      @doktoracula7017 3 роки тому +5

      @@franciscofarias6385 Really depends on a case, usually I don't need to check for anything like that in setter. I check it earlier (for example by creating a simple wrapper class around value that would throw an exception if value isn't valid) or in constructor when injecting the value.
      And by the way, setter has set in name, which makes people think it only sets the value and MAYBE converts it to right format. Checking conditions can usually be done in a better place.

    • @zacharychristy8928
      @zacharychristy8928 3 роки тому

      Simple flags like "isVisible" are about all I use setters for. It's a little simpler than having a "SetVisibility" function that just does the same thing in the background.

    • @zacharychristy8928
      @zacharychristy8928 3 роки тому +3

      Firing an event when the value is changed is a good reason to have a setter. You can take the responsibility of changing/updating all related fields out of the object itself and move it into dependent objects instead. (Unless that's what you meant by ORM)

  • @NostraDavid2
    @NostraDavid2 3 роки тому +21

    Non-pessimization in action!

  • @ChrisAthanas
    @ChrisAthanas Рік тому +28

    Minimal code use is never taught in any college class I’ve ever been in
    I learned it only thru pain and realizations abs going against “best practice”

  • @SMWssaamm
    @SMWssaamm 6 років тому +153

    Single-variable getters and setters are a bastardized version of what they were intended to be, which was simply transforming an internal representation into something usable on the outside. The internal data doesn't even have to be private.

    • @ScibbieGames
      @ScibbieGames 3 роки тому +7

      Exactly this!

    • @ghevisartor6005
      @ghevisartor6005 2 роки тому +3

      In C# having properties with setters is usefull when u deal with UI frameworks, you put OnPropertyChanged() so when the user of another component updates the variable a request for a refresh is sent to the UI. If you need to do multiple variable updates inside the class you update their backing fields and only for the last one you set the public variable.
      public String Name { get => _name; set { _name = value; OnPropertyChanged(); }
      public String Age { get => _age; set { _age = value; OnPropertyChanged(); }
      public String Gender { get => _gender; set { _gender = value; OnPropertyChanged(); }
      public void UpdateUser(String name, Int32 age, String gender)
      {
      _name = name;
      _age = age;
      Gender = gender;
      }

    • @SMWssaamm
      @SMWssaamm 2 роки тому +16

      @@ghevisartor6005 I agree. I should have said:
      "Getters and setters without side effects, which get or set a single variable without transformation, in a context where transformation and side effects would never have to be added in the future."
      But that's a mouthful.

    • @trex511ft
      @trex511ft 10 днів тому

      the problem is, I don't see how not to do this since today's mode of programming is like this in 90% of the cases: web, mobile, gaming, etc. Everything and every company pretty much forces you to do it like this, he doesn't do it like this because he is writing in C and he is his own boss. (if he chose a language that kinda forces you to OOP it would probably drive him nuts).

    • @SMWssaamm
      @SMWssaamm 9 днів тому

      ​@@trex511ft Far from the worst thing that big companies want you to do.

  • @Donutttt_
    @Donutttt_ 2 роки тому +28

    I feel less insane after watching this... people act like you _have_ to use private/getter/setter.... it's nuts!

  • @notiashvili
    @notiashvili 8 місяців тому +8

    The underscore thing is genius.

    • @DJSxd452
      @DJSxd452 3 місяці тому

      he says accessing the struct's member once it has the underscore at the end won't compile, but I've tried it in mingw and that doesn't happen. What am I missing?

    • @Sebastian-eb2ux
      @Sebastian-eb2ux 3 місяці тому +4

      @@DJSxd452 the point is that old code which previously accessed using just the field name will now no longer compile, so it's easy to find all the occurrences that you need to change. not that you can't access a field with an underscore in it if you typed it like that in the first place

    • @DJSxd452
      @DJSxd452 3 місяці тому +1

      @@Sebastian-eb2ux thank you so much

    • @zdspider6778
      @zdspider6778 2 місяці тому

      It doesn't have to be an underscore. You can rename it anything you want and the compiler be like "nope".

    • @zdspider6778
      @zdspider6778 2 місяці тому +1

      @@DJSxd452 Probably because your IDE automatically renamed all the instances of where that variable was used.

  • @kenneth_romero
    @kenneth_romero 7 місяців тому +3

    that increment example got a good chuckle outta me

  • @Y0y0Jester
    @Y0y0Jester 9 місяців тому +4

    An excellent explanation with perfect on-point code samples.

  • @coolsebz
    @coolsebz 9 років тому +47

    hahaha i always like Casey's Rants xD Can't have enough of them!

  • @jimmyjimbo666
    @jimmyjimbo666 9 років тому +86

    haha, always hated writing getters and setters :@

  • @itsacorporatething
    @itsacorporatething 2 роки тому +64

    If you have private members that can be directly accessed by public functions, you’ve completely missed the point of encapsulation.

    • @asdqwe4427
      @asdqwe4427 Рік тому +49

      You just described 99% of all java code 😂

    • @itsacorporatething
      @itsacorporatething Рік тому +4

      *mutated

    • @Modinthalis
      @Modinthalis 11 місяців тому +3

      It's not direct access, it's just a way of getting a copy

  • @stewiegriffin6503
    @stewiegriffin6503 2 роки тому +13

    respect bro, for saying this.
    Now, in times when OOP is like religious cult, not many dare to say that the Emperor is naked.
    Here a heart : ♥

    • @devoiddude
      @devoiddude 2 роки тому

      ANOTHER LAD HERE TALKING SHITE, WELL DONE

  • @asdqwe4427
    @asdqwe4427 Рік тому +28

    I remember asking what the point of private was when there would be getters and setters for each field anyways. I asked my teachers and they gave me some vague spiel about “best practices “ and encapsulation. I never got the point, because there is none. People might say that in some cases you want to react to the fact that a value is being set. But I think that a simple setter communicates that very poorly, in a case like that, I would go fully private and name the method setMyVarAndBroadcast.
    University teachers have often never had a real job, so they should not be trusted on style and best practices

    • @KristjanB
      @KristjanB Рік тому +1

      Yes the reason is encapsulation. Very often at the start of programming project you don't know if you need to update some other state based on that variable or maybe broadcast state changes. If you encapsulate the data you are guaranteed to be able to do make those changes in the future independent of the data. If you have thousands of line of code accessing the data and incrementing this variable and maybe even having references to this variable you may have to rewrite a lot of working code. If you are just a sole programmer working on a small project this isn't a big issue, but when you are working on a gigantic codebase with many other programmers where you don't have control on how this data is accessed this type pf encapsulation becomes a lifesaver.

    • @asdqwe4427
      @asdqwe4427 Рік тому +2

      @@KristjanB I have been programming professionally for 10 years and I can’t remember ever having a setter affect some other state. In fact, setters that only do one think are so common that if they did come with side effects, people would be furious. Methods that cause some side effects should be properly named

    • @chrisc7265
      @chrisc7265 Рік тому +1

      ​@@KristjanB I think the getter/setter problem gets worse at scale, not better
      the key point Casey makes, is that if you implement a setter with one behavior 1000s of times, changing the behavior of that setter is going to be a nightmare no matter how you cut it --- someone will be going through every implementation and making sure the new behavior doesn't break anything
      really there's no reason accessing a variable should automatically do other stuff, especially when people unfamiliar with the code don't expect it to

    • @KristjanB
      @KristjanB Рік тому

      @@chrisc7265 The behavior of the setter/getter should not change however the implementation could change. For example a generic getCount variable could be implemented by summing up two other internal count variables, if that was a change that was needed. A setter could implement some pre allocation of some objects like lists to speed up things internally. There is no need to break anything as long as the setter and the other methods implement the same interface as before, the internal implementation of the object could be written completely different which is the point of using OOP in the first place.

    • @raze2012_
      @raze2012_ Рік тому +1

      That's a shame. the encapsulation is a human safeguard, not some OOP "best practice". It should be very easy to explain "because people come and go from companies and private is a safeguard to remind the potentially new dev that this shouldn't be accessed directly". If you're a solo or small team and have the entire codebase in your head and processes ready, you shouldn't in theory need to make anything private with a keyword. But then again, even future you may forget past practices.
      As for setters: yea, it's rare but normally side effects for a setter involve mutating other private data. quick (but semi-contrived) example is telemetry to point out how often a particular piece of data is mutated, or simply to logged that it's been changed. If it's anything more expensive than small bookkeeping, I agree. it probably shouldn't be a setter anymore

  • @jasonazevedo1983
    @jasonazevedo1983 3 роки тому +15

    Ha, I'm not the only one who thought that getters and setters didn't make sense for most use cases!!

  • @judgedbytime
    @judgedbytime 2 роки тому +11

    Doing lots of typing without having to think is the end goal of pretendacoders.

  • @ar_xiv
    @ar_xiv Рік тому +8

    Learning C# it seemed like there was some mysterious purpose for using Properties and backing fields and I’m still kind of trying to both learn why they are so enforced and also unlearn their use altogether. As mostly an individual programmer I have to force myself at this point to just make public fields and not use properties.

  • @u9vata
    @u9vata Рік тому +6

    I mostly agree. Except for libraries it can indeed give implementation freedom (and if you change bar into bar_ you can only check your own source code codebase, not others and break half the internet lets say). So it might be useful on real module boundaries - but again people too much OOP they do this everywhere not on boundaries and that sounds premature.
    Also one more thing to consider: I hears from someone I forgot his/her name that putting too many things into private state likely indicates that your doing wrong logical separation of concerns and likely those things could be public and logically separated to their own thing if this starts really becoming an issue. Again not working always in module boundaries, but otherwise sounds not so bad idea...

    • @nan0s500
      @nan0s500 Рік тому +1

      Please just admit that it is just speculation. Even in libraries or whatever stupid example someone can come up with. When was the last time you actually needed to do something like this - that you didn't know you would need accessors but then out of nowhere this necessity popped up? This necessity is probably there from the beginning and doesn't pop up out of nowhere. When did you needed to do that, seen someone do that? And on top of that in a library? NEVER ever seen it. Its just poor practice and needs to be ditched completely.

    • @u9vata
      @u9vata Рік тому +8

      ​@@nan0s500 what you talk about? I myself literally wrote code that benefited this indirection. Where? again on a library boundary: It means you can release new version of the lib while still being binary compatible with the old API-wise! Which is either a big deal or "I don't care" - depending on other factors. One such factor is that in open source libraries you pretty much just not care because you users recompile it all anyways - but lets say its a physics engine and you add a "getter" or "getter-like" functionality to access a value instead of directly accessing. If you find out a better architecture (which changes data representation below this level) and want to keep compatibility - when there is hiding at this point, you can make the lib binary compatible with the old one - while using a fallback in that getter. The new codes then can access the new ways of doing things.
      Also this is not really need to be a getter - anything that hides the detail can go at the api boundary - like api design that makes the same hiding more broadly for ex.
      Another use case is logging accesses in a live system: I had this train control system where we could runtime exchange modules of it with a "logging" variant where some critical setters also logged if they were accessed. Was good for debugging a complex system with MLOC amouonts of codes over the years.
      Saying there are no use cases I disagree with - saying its overused religiously for some reason I agree with...

    • @Muskar2
      @Muskar2 3 місяці тому

      @@u9vata Sure, getters and setters are good specifically on module boundaries. But access modifiers still hurt a lot while barely expressing intent. It would be a lot better to write some simple compile-time rules to prevent common mistakes that interns make, while still allowing ways to circumvent those rules. E.g. you cannot create a struct that refers to an Entity type, unless it's in this white-listed set of structs. I.e. making the _typically_ wrong things harder to do, but never impossible.

  • @gracehall2897
    @gracehall2897 2 роки тому +1

    I love this

  • @noxagonal
    @noxagonal 2 місяці тому +4

    There is a tradeoff. Getters I understand, theyre useful when you want to protect some internal variable, like vector size or capacity, you can prevent stupid mistakes by preventing modifying internal data directly. Setters are almost useless though, the only place where I use them now is with virtual function calls in very few areas. Simple POD structs definitely have their place too. Purpose of all of this is to guide the api user towards the right direction, make it easier and faster to use.

    • @Vintagestep
      @Vintagestep 2 місяці тому

      Setters I get when some validation is required, but yeah, if there's no reason to protect or validate anything there's no point to use them.

    • @noxagonal
      @noxagonal 2 місяці тому

      ​@@Vintagestep Hmm. Good point. I have a couple of other ideas for when to use setters.
      1. If you must notify that something has changed.
      2. As a convention when "would-be" public variables may be used internally.
      3. Making classes contain member functions only, structs data only.
      I noticed that I'm often gravitating towards classes contain functions only, so sometimes I may write setters on those.

    • @Vintagestep
      @Vintagestep 2 місяці тому

      @@noxagonal Yeah, it makes sense. Tbf I'm still too attached to the OOP mentality since that's how I was taught, I still have to internalize a lot of common patterns and see how to apply them outside of the OOP programming, but yeah, that comes from experience and awareness I guess.

  • @leonardomaia7661
    @leonardomaia7661 Рік тому +2

    Damm i am a vim user but now i want to try emacs...

  • @MyAce8
    @MyAce8 6 років тому +35

    Just FYI if you're into the theory behind OO, the point behind getters and setters is not usually to hide implementation details (although many people who use OO think that's what it's for) the idea is that if you have multiple representations (for example you could have an aabb that could be described as either two points or as a position, and dimension) you can abstract idea of "getting the upper right corner" which for implementation A would be (p2.x,p1.y) and for implementation B would be (x+w,y). having this abstraction can be nice because now you don't have to write two functions, or a function and conversion functions, you can just right one function that takes a base class. Casey solution would be: just write the two functions was it really that hard. If you want a real OO language where this isn't painful try small talk

    • @igorswies5913
      @igorswies5913 4 роки тому +5

      but this works only for deeply backwards compatible systems, and you don't want a game to be such system because in a game things change all the time and you have control over everything, you can just search and replace if you want to make a breaking change (which will inevitably happen at some point). if you stick to the old code just so that you don't have to update it everywhere then that's one step to creating legacy code - it's fine for an API that is meant to be used for decades with backwards compatibility but if you start to introduce it to a game, which is a self contained system with no public API then you're gonna end up with useless getters/setters for every struct and you're gonna change those anyway which misses the point. OOP enthusiasts tell you to write getters and setters for every variable but really it only makes sense for those backwards compatible API that cannot have breaking changes. again, there's no point in making a game such legacy intended system

    • @MyAce8
      @MyAce8 4 роки тому +12

      @@igorswies5913 I'm not advocating for OOP. I think most of the ideas in OOP are either obvious or wrong. We had vtables long before virtual classes and got along fine. That being said this video misrepresents the OOP position, and I'm just trying to be fair

    • @rdoetjes
      @rdoetjes 3 роки тому +2

      @@MyAce8 I concur, this video was a useless rant by someone who for whatever reason didn't fully comprehend OOP and the true intension of accessor methods. And consistent interface practices. I personally don't like C# that certain things are done by direct property access and other require a function, it's not intuitive because I don't know, not care when sometimes a property when I access it, does more than just return the value.

    • @MyAce8
      @MyAce8 3 роки тому +1

      @@rdoetjes I personally don't like OO, but his argument in the video is poorly made.

    • @ChrisWaymire
      @ChrisWaymire 3 роки тому +13

      Most of these anti-oop rants I see on YT are from game developers who only see things through their own lens, and since oop may not be a viable solution for them that makes it unusable for anyone. They are running around with a screw driver and advocating how superior it is than a wrench. Both are tools, and their usefulness is largely based on the problem you are solving.

  • @kolosso305
    @kolosso305 2 місяці тому

    He's so right. But it's not common practice sadly

  • @ikokujin
    @ikokujin 4 роки тому +8

    What about using private data to protect an invariant?

    • @Bjekan
      @Bjekan 3 роки тому +17

      name the data doNotAccess and consider yourself an idiot if you do :D

    • @wanderer7480
      @wanderer7480 3 роки тому +4

      If your language don't allows you to enforce the protection of invariants without sacrificing performance, you should find a better language.

    • @cemgecgel4284
      @cemgecgel4284 2 роки тому +1

      @@wanderer7480 what does that mean? Should I give up on C,

    • @wanderer7480
      @wanderer7480 2 роки тому

      @@cemgecgel4284 Maybe? Depends on your motivation to learn or use C.

  • @nexovec
    @nexovec 4 роки тому +28

    I think the reason these types of things are done is so that the coder himself has no idea what the code is doing and therefore can't leak anything.

    • @dandymcgee
      @dandymcgee 3 роки тому +15

      He can leak something alright.. memory.

    • @Anteksanteri
      @Anteksanteri Рік тому +2

      Also, being able to type get or set and having your IDE complete the possible things that you can get or set gives people comfort. It doesn't make any sense, but still.

    • @ChrisAthanas
      @ChrisAthanas Рік тому +4

      Average developer has less than 5 years of experience and none of this is taught in schools, which is sad

  • @zacharychristy8928
    @zacharychristy8928 3 роки тому +25

    This is why I like the way C# does it. You can treat fields like raw data and still have mutator/accessor logic like firing off property changed events. It sounds like his issue is having pointless accessors that clutter your code, which things like auto-properties address really well.

    • @sdwone
      @sdwone 3 роки тому +6

      Yeap... Auto-properties in C# rocks! And definitely saves you this kind of nonsense! And, if you need to do something special with an accessor, you're still free to go ahead and make those changes.

    • @comradepeter87
      @comradepeter87 3 роки тому +27

      I find it extra bad. It saves you on syntax, but now it's even more ambiguous what _variable.attribute_ does. Does it simply return a value, or does it try fetching a JSON file from the web, parse it and return it?

    • @zacharychristy8928
      @zacharychristy8928 3 роки тому +4

      @@comradepeter87 preventing that kind of thing can come about in 2 ways. You either favor fields, which are just raw data, or you follow the convention that get/set needs to be inexpensive. It sounds wishy/washy but you'll follow similar conventions if you have an explicit get() function anyway. If you eliminate get functions entirely, then you'd have to follow different conventions anyway, by executing similar logic whenever that data was accessed. There's really no way around it.

    • @comradepeter87
      @comradepeter87 3 роки тому +4

      @@zacharychristy8928 Kotlin does this pretty well. For variables that you want to expose for reading purposes but not writing, you can just attribute them with "private set". This way, get() and set() function presence means there's something non-trivial going on, and at the same time introducing a get() just for the aforementioned reason is no longer an issue, making such convention unambiguous.

    • @zacharychristy8928
      @zacharychristy8928 3 роки тому +1

      @@comradepeter87 Nice! C# has that exact functionality too, it's really useful. It STILL means you have to follow sensible conventions, but my previous point was that conventions about what you can put in mutators/accessors, will always be something you have to contend with anyway.

  • @zdspider6778
    @zdspider6778 2 місяці тому

    "Never ever, unless it does something."
    But... it does something. 🤨 It protects the (PRIVATE) variable from being messed with from someplace else... Not that you can't mess with it from some place with a "setter" member function, but then you at least get a call stack and can Trace it, whereas with a variable you cannot, you have to manually and explicitly set "watchers" for variables in your IDE to notify you when (or if) that variable was changed. With a stack trace you can just see what called which function, including the one that changed the damn variable that caused trouble down the line.
    And a setter also allows you to place a breakpoint in that function, to pause immediately upon executing it, then "step back" in the code to see where it was called from. Whereas with a member variable you cannot.

    • @gaurangshukla8235
      @gaurangshukla8235 2 місяці тому +2

      1. We have data breakpoints in debugger.
      2. Every compiler already has that functionality, its called adding an underscore at the end of variable and the compiler will show where it is used.

  • @ifstatementifstatement2704
    @ifstatementifstatement2704 2 роки тому +9

    I had the same reaction when I first learned about getters and setters lol. The point of using getters and setters for private attributes is to give you who made the class control over the method that sets or returns the value of the variable.
    For example, what if you have an Address class and you have a postcode field and you want to ensure that a postcode is inserted in that field? You would make a setter function that checks the new postcode value passed to it and have a conditional statement in it to check that the postcode is in a valid format, before assigning the new value to the private postcode variable.
    But yeah I agree, you should only create accessors if there is a need to. In the team I am working on, we are programming a web app in Java and they always create accessors by annotating their classes with @Data all the time. It gets on my nerves and is a stupid practice. Because what if you don't want a variable to be accessed.

    • @theo-dr2dz
      @theo-dr2dz Рік тому +1

      The @Data thing is the endpoint in an evolution.
      In the early beginning they just typed out getters and setters for all data members.
      Then, java IDE's got a function to automatically generate getters and setters for all data members.
      But that's still a lot of clutter, so they invented Lombok that has @Data that implicitly generates all getters and setters. The code behaves as if they're there, but they are really not there.
      I think setters are useful if they do something useful, like enforcing an invariant. And in that case you also need a getter.
      Getters can be useful if you want something to appear like a data member but that really is computed on the fly. Lika in a bank account get_balance() that really accumulates all transactions from some starting point. In that case there would be no setter.
      In all other cases (9 out of 10) just make the damn thing public.

    • @vytah
      @vytah 10 місяців тому

      For that postcode example, just make a postcode datatype and do validation in the constructor/factory.

  • @abdolilahmajid_21
    @abdolilahmajid_21 Рік тому +5

    casy moratori know better than any of us when it comes to performance optimization you should listen

  • @stackercoding2054
    @stackercoding2054 9 місяців тому +3

    When I started to learn how to code I remember the first time I wrote the first kind of: "foo->set_data(foo->get_data() + 1)" and I felt such and idiot hahaha, it was probably the first time I realized that I should think more by myself and stop trying to apply every clean code technique I saw

  • @BlazertronGames
    @BlazertronGames 10 місяців тому

    I do think theres merit to private members. When you do need an accessor function, its nice to hide the member so you cant accidentally change it. But i can definitely agree with not making a getter and setter for no reason.

  • @michakryszak9536
    @michakryszak9536 4 роки тому +23

    That's why I like C# auto properties, you just create an auto property at the start and add logic down the road if needed.

  • @broyojo
    @broyojo 3 роки тому +13

    right to jail

  • @marcotroster8247
    @marcotroster8247 2 роки тому +1

    Haha yeah, plain getters/setters are really bad, especially setters. Use TDD/DDD to get the data structure right, then optimize the data representation such that the setters actually do something useful like carving bits out of an optimized bitboard or bookkeeping caches, etc. 😂

  • @senkrouf
    @senkrouf Місяць тому

    anybody saying that it protects... that not the reason the "experts" said it was a good practice to always use for setters and getters, the real reason was to avoid CHANGE of code when they needed to add BEHAVIOR before setting or getting a variable, Imagine working at old twitter with 8k devs working on different SCALA classes where 7k of them are Junior devs, and someone, randomly, decides that before editing a field, something needs to be checked, well you can imagine possible the problems your own.
    I think It makes a lot of sense forcing everyone to use setters and getters for everything on a nonperformant platform like twitter or facebook or youtube comments section.
    Its a human communication problem. On small teams it makes no sense to use setter and getters.
    Java and C# have introduced some notation tricks so you can choose not use setters and getters at start and not worry about the need to add behavior in the future.

  • @Ratstail91
    @Ratstail91 Місяць тому

    Structs and classes are diffrrent for a reason.

    • @ItsBaffledd
      @ItsBaffledd 14 днів тому

      oh please do explain lmao.
      The only difference is access, he is using c++ not C so you can have functions on either.

  • @somniad
    @somniad Рік тому +2

    In general, the introduction of a boundary has a significant cost, and whenever I see code that's written in a very heavy OO style, I feel like the person who wrote it thought that cost was zero.

  • @AndrewKln
    @AndrewKln 2 роки тому +6

    I'm reading Herb Sutter's books, which as far as I know are considered among the best books about C++ and his opinion is the opposite. His idea is that you should write getters that return a reference(but it will include less typing than Casey's example), which gives the advantage that if the variable will change, the code that uses it won't need to change. Also in case of needing some debug info, the getter might be changed without notifying the rest of the code. Funny that Casey gives the opposing argument exactly about that. Man, people, and their opinions...

    • @T0m1s
      @T0m1s 2 роки тому +8

      "the advantage that if the variable will change, the code that uses it won't need to change". I keep hearing this and I don't get it. What is the big deal if the code needs to change? Out of all possible things to solve and optimize, is this really the one to choose?

    • @uipo1122
      @uipo1122 2 роки тому +8

      These accessors get custom access logic in 99%) you are wasting time by doing this. So what "brilliant" OOP minds suggest is to waste 99% percent of your time typing getters and setters instead of going through your code and changing direct variable access to custom get/set functions when the need actually ARISES.

    • @XPCagey
      @XPCagey 2 роки тому +11

      @@T0m1s Casey's project is ambitious and complex but self-contained. Herb Sutter is on the C++ committee that defines language standards including the interfaces for the C++ standard library. Herb also is one of the principle engineers behind Microsoft C++ development. Why you are writing code is critical to picking the right tools to use, and all-or-nothing opinions typically reveal a lot about the environment where a programmer has spent their career.
      If every use case for your change is sitting in a single repository, it's easy and appropriate to change all the places that break as Casey suggests. If Microsoft shipped a Windows library update that broke the ability for windows software to compile until it was edited, millions of man-hours would be necessary to correct the issue and many projects would just remain broken due to lack of active maintainers.
      Both Herb and Casey can be right from the correct perspective, and when the cost of backward incompatibility is breaking all software on an operating system or all software using a language feature, yes it is important to do that as little as possible.

    • @T0m1s
      @T0m1s 2 роки тому +6

      @@XPCagey - Herb Sutter is a self-appointed expert who became known because of some books he wrote. Anyone can write a book. He's not Knuth or Dijkstra. A lot of people managed to get in the C++ committee but that doesn't elevate them to God status.
      Regarding backwards compatibility, then sure, you do what you need to do. But if that's not a requirement, my question stands. Why sacrifice other metrics in favour of "it makes the code change less"?

    • @XPCagey
      @XPCagey 2 роки тому +5

      @@T0m1s You seem to be projecting something I never said about the quality or lack of quality in a person's work. I went out of my way to say Casey's approach was "easy and appropriate" with small codebases. One more time for the people in the back:
      Why you are writing code is critical to picking the right tools to use.
      "if that's not a requirement, my question stands"
      This is apparently something you feel passionate enough about to both admit the point was valid and insist that only one perspective can be correct; enjoy your time on the internet.

  • @jamesevans2507
    @jamesevans2507 3 місяці тому

    based

  • @leonader9465
    @leonader9465 Рік тому +1

    I thought this was obvious. Incredible.

  • @howard_blast
    @howard_blast 5 років тому +20

    Go off king.

  • @Mark-kt5mh
    @Mark-kt5mh 4 роки тому +9

    I don't like the premise either, but I feel like the justifications here are absurd. I write pure, side-effectless, stateless code wherever possible, sometimes that is not possible. OOP is just an abstraction methodology, one that encourages side-effects so long as they are localized and documented. The use of getters and setters should only be used when side-effects are intended to occur within and only within the object in question. In my opinion, the existence of getters and setters implies side effects, therefore, whenever side-effects are not wanted or intended, an object's variables should be made public.

  • @vborovikov
    @vborovikov 2 роки тому +5

    Getters/setters are extension points. Later you can change its implementation if you need it. Replace storage with calculation and vice versa. Expand storage, reduce it. More information you hide, more you can later change without breaking other code.
    Besides, expose behaviour, not state. So you can "tell, don't ask".
    Renaming variables and breaking stuff works only if you work alone and/or nobody uses your code in the production out of your control.

    • @oscareriksson9414
      @oscareriksson9414 2 роки тому +5

      I do not agree with the last part that it only works when working alone. Getters and setters should not be exposed in an api any way. You don't make a service where you set or get one variable, you use requests and responses. When you need to change internal code you can do that without any problems, it is not going to break api contracts

  • @llothar68
    @llothar68 2 роки тому +1

    How do you easily set a breakpoint to a data member when you don't have getters? Getters are good on tracking terrible complicated bugs. Sure you can turn them into getters later as you said but i still prefer it to not touch dozens of locations. And come on. Typing shouldn't be a problem.

    • @_tavomaciel
      @_tavomaciel 2 роки тому +4

      In GCC you can set a memory watch, that will make it pause whenever something reads or writes a variable/specific memory address.
      Isn't that much better than changing all your code just so you can use line breakpoints instead?

    • @llothar68
      @llothar68 2 роки тому

      @@_tavomaciel Yes but this works only useable speed when you can use the 4 hardware debug watch registers.
      Also you can put profile hints etc.
      There are lot of reasons for getters in complex systems. I agree that if everything is encapsulated in a compile unit you don't need this.
      And games are quick and write once software anyway, unlike business software they don't need to be maintained over 30 years.

  • @puffinrock2871
    @puffinrock2871 2 роки тому +4

    All these people getting triggered because their sacred cows are getting slaughtered.

  • @andrewherrera7735
    @andrewherrera7735 3 роки тому +26

    The irony is that one of the weakest languages ever, python, says "we are all consenting adults" and therefore making things private is for kids.

    • @brycemw
      @brycemw 3 роки тому +4

      One I had to use a specific library in python for HTTP requests. It had built in encoding for parameters and you couldn’t do it yourself. But the encoding was slightly broken. No problem in Python though because I could overwrite that function to one of my own. You can of course do this with C as well. At least via semantic interposition on Linux but you can probably instruct the linker as well. (Of course things like inlining do cause issues with this)

    • @comradepeter87
      @comradepeter87 3 роки тому +2

      It's a bittersweet thing. On the first hand, it's great for allowing patching of the code after-the-fact and we don't have to re-compile the library with changed source, or ask the vendor to make changes for us.
      On second hand, this makes it harder to change internal representation without risking breakage.
      But I'd still prefer all public fields like Python, with the _private_field type syntax, to let the user know that this shouldn't be changed unless you know what you're doing and that you risk breakage in the future.

    • @thehckergamingchannel8347
      @thehckergamingchannel8347 8 днів тому

      @andrewherrera7735 "weakest languages" sure thing, bud. And this is exactly why you are writing this comment on a platform powered by Django (Python), which uses ML algorithms running on PyTorch (Python again)

    • @thehckergamingchannel8347
      @thehckergamingchannel8347 8 днів тому

      @andrewherrera7735 “one of the weakest languages”. This is exactly why you are writing this comment on a platform powered by Django (Python), which uses ML algorithms running on PyTorch (Python again)

    • @thehckergamingchannel8347
      @thehckergamingchannel8347 8 днів тому

      @andrewherrera7735 “one of the weakest languages”. This is exactly why you are writing this comment on a platform powered by Django, which uses algorithms running on PyTorch

  • @techpriest4787
    @techpriest4787 Рік тому

    Maybe try Rust it is less bloated at least. Though Rust could make good use of a read only keyword to prevent silly one line functions just to read fields.

  • @almighty1984
    @almighty1984 Рік тому

    I use them but without the set and get prefix. Even though most simply return or set the data, I still like the consistent interface and to know which variables are part of a base class.

  • @Beeftitan
    @Beeftitan 2 роки тому +4

    I have noticed a phenomena where particular indie game devs are almost anti abstraction. Like Casey and Jonathan Blow, I however would much rather build code that assumes scalability and changes. If I take the couople extra seconds to make getters and setters, now in the future when i need them its not a big deal. If i never add special logic to them then there is little to no side effect. If the code is consistent then its easy to navigate and maintain. If only some vars are private and have getters and setters than itll be much more confusing for teams or people using the code. I noticed that the people that feel very strongly against abstraction are typically 1 man teams.
    If you want code that will be used by others and or service more than 1 game, abstraction is a great tool when used correctly. Yes sometimes it means you write more code like int++ becomes setInt(getInt()++); but who cares?

  • @wisnoskij
    @wisnoskij 2 роки тому +6

    I am not sure I really follow the reasoning here.
    Yes, the getter/setter example is like 4 times longer, but it is not really 4 times longer, it is 4 lines longer so is the different between a 10mb source code and 10.00001mb source code.
    incrementing) Typically you are not doing arbitrary math on variables in other classes. In that case you might not even need a setter, you would simply have an incrementer. If you need to do any number of arbitrary math on a variable outside of its class, then it probably should not be a class, it should be a strut.
    It hides hash table lookups and shit) Well first off abstraction hides nothing, you are just using getters/setters to assert to anyone programming that you can worry free use them without having to read through and understand the entire class. Nothing stops them or even slows them down in reading the class, they just have an unspoken assertion that if they use this public api, it should just work. This seems to be the most powerful part. No one is going to memorise all the source code. I dont think it is reasonable to expect everyone who works on windows to have even read the entire code base, so you create simple public api to use.
    secondly. Well if the hash table lookup has to happen every time myData is changed for the program to work, what does it matter if it is abstracted into a setter or not? That just means you have a single location to optimize, instead of searching the code for every part where myData is changed and the slow update code is ran.
    Function calls are slow and foo.myData++ is just faster than foo->.incrMyData();
    That should be a compiler problem. Code is designed for coders to express themselves in the most clear way possible, it is the job of the compiler to turn this into efficient opcode.

    • @vrsoup1245
      @vrsoup1245 2 роки тому +2

      based.

    • @Beeftitan
      @Beeftitan 2 роки тому +3

      his main argument is the waste of writing more code. But you only write a class once (ideally)... In terms of saving time, id rather have the redundant getters and setters in the off chance that eventually something else must happen. Rather than having to create a getter and setter late in teh game and do what he suggests which is change code to find all the areas that need to be changed.

  • @JustFlyIt09
    @JustFlyIt09 2 роки тому +16

    "Fire you immediately", the perfect example of a bad manager.

    • @meandtheboyz4796
      @meandtheboyz4796 11 місяців тому +10

      cope

    • @Rockyzach88
      @Rockyzach88 4 місяці тому

      ​@@meandtheboyz4796Low media IQ

    • @Evilanious
      @Evilanious 4 місяці тому

      Yes, but I'm pretty sure he's being hyperbolic.

  • @Westernaut
    @Westernaut 2 роки тому +3

    Disagree. Oversimplified. Based on presumption of naming it as such, get or set, is merely getting or setting something entirely primitive. Designing a simple interface need not imply simplicity under the hood.

  • @UberOcelot
    @UberOcelot 6 років тому +23

    As always, these things are case-dependent.
    Getters/setters are useful because the abstraction can be optimized away at compile time, while allowing you to change you're access behavior without changing the interface to the rest of your program. This is very useful when you need to stabilize some api, it's simply best practice for library writers. For anything that isn't at such a boundary, then sure you might be better off accessing things directly. If you want to all of a sudden make an internal structure thread safe it's way easier to box a field if it was behind a getter all along.

    • @blakemartin2785
      @blakemartin2785 6 років тому +15

      This is an intermediate view-point along the transition to Casey's mindset. I know because I used to make that argument. See this ua-cam.com/video/B2BFbs0DJzw/v-deo.html for a funny example of why those getters/setters _aren't_ always optimized out. Your compiler isn't magic, and there are limits to the amount of bullshit it can sift through. If you give it a simpler starting point, it can only ever help.
      As far as the stable API business goes, getters/setters aren't the place to introduce this. The places where portability/stability are more important than knowing exactly what your code is doing are places where a few plain procedures would be better.
      The "accessor" nature of that code compared to the plain structs everywhere else indicates that those are the areas that the application programmer can't make assumptions about. If you do that crap everywhere, the application programmer can't make assumptions about _anything_. If the application programmer can't know how any of his code works, you may get some "stability" in that the code still compiles when you change the library out for a new version, but you've traded fixing a few compiler errors for a decrease in the stability of the application, whether it's stability in behavior or performance. The worst part about that kind of trade is that if the behavior or performance of your application changes, you won't know why until you consult the changelog on the library's website. At work, I work on an embedded system that people thought Boost and tons of OO would be great on. Now, at 26K LOC, there are performance and behavioral problems that are extremely hard to fix because all of the implementation details of threads and memory have been abstracted away. Oh, and compile times are 6 minutes... At least, they were before I showed up. Now it's at 2:20, but that's still terrible.
      Fixing compiler errors is just about the easiest problem a programmer can solve, while fixing weird behavior that was silently introduced during a library patch is one of the hardest. The trade-off doesn't make sense. I don't expect you to be convinced right away, but after a few months of structs and procedures, everything about your software will improve, and you will look at something like Boost and feel nauseous. Good luck!

    • @UberOcelot
      @UberOcelot 6 років тому +4

      How are you so confident it's the getters and setters that are prohibiting the optimizations in that example? What's really happening is a loop transform, which is pulling something out of the loop that doesn't need computed in every iteration. Since Casey breaks that function out into it's individual components manually the compiler will move the independent sections. Further he changes from using a v2 struct to individual real32s. Where as the v2 has to be two contiguous real32s in memory. This change allows the independent 4 bytes to be moved out of the loop up into a different stack frame. He avoid computing the same thing 3 extra times. In the code with the v2 the compiler is correct in not deconstructing a struct and instead doing literally what it's being told to do. So there is our speed up. It's further possible that breaking up the v2 struct manually allowed for a better memory access pattern that could have prevented the waste of a cache line if that v2 happened to get bad alignment.

    • @notnullnotvoid
      @notnullnotvoid 6 років тому +4

      UberOcelot, functions cannot be inlined across translation unit boundaries unless you enable link time optimization (which is expensive, single-threaded, and non-incremental, so say goodbye to your compilation speed). And they can't be inlined at all across API boundaries defined at runtime - i.e. any dynamically linked library, which is exactly where the API boundaries in question are likely to show up.
      Also, the fact that the compiler fails to elide the struct or hoist the computations after inlining the functions - even though they are valid and well-defined optimizations that don't change the program behavior, and even though the compiler evidently *can* do them in the case where the functions are manually inlined - is exactly what Blake Martin means when he says that "compilers aren't magic." Your explanation proves the point perfectly.

    • @UberOcelot
      @UberOcelot 6 років тому +2

      Incurring a compilation cost, which can further be sequestered to just final_release or perf_testing builds, is not really an excuse to not use good abstractions when LTO is available. Especially if you are maintaining a statically linked library that needs a stablized API. You are right about the dynamically linked library case, but that is also precisely the sort of boundary that you'd want to use getters and setters for, because you are forced to incur that dynamic dispatch cost anyways. Plus if you use that same public api internally (i.e not from across the link boundary) then the non-functional getters/setters still get optimized away. The case when they aren't is when you're using dynamic polymorphisim and it's necessary to go through an objects vtable, in case some types don't have their getters/setters as trivial ones. The primary reason not to organize your data as objects with getters/setters is more to do with data organization and access patterns that introduce unnecessary data dependencies like in the example I responded to in my second comment.

    • @notnullnotvoid
      @notnullnotvoid 6 років тому +3

      You eat some portion of the compile time cost for getters and setters at all optimization levels, including -O0. Plenty of performance-sensitive programs (especially games) are painfully slow on -O0 (usually because of useless boilerplate like getters and setters!) and so are regularly compiled at -O1 or above for testing. You should DEFINITELY care about compile time for perf test builds, because that's a time when you're iterating a lot - and if you're relying on LTO for performance, then incremental compilation can't save you! And if you use CI intensively, you're making release builds all the time as well. Oftentimes libraries are distributed as source and built on the user's machine, and if that's the case, you'll surely be wasting other people's time as well as your own. I could keep going, but I'm sure you get the picture.
      What do you mean by "you are forced to incur that dynamic dispatch cost anyways"? What scenario are you comparing against?
      Regarding your second comment, you seem to have some misconceptions. When placing variables on the stack, whether you use a V2 or two naked floats makes no difference to how likely they are to cross a cache line boundary. And it doesn't matter if they do, because they're in a place on the stack that is definitely already in L1. And if they are optimized off the stack entirely and exist only in registers, then it *really* doesn't matter.

  • @slysquash2473
    @slysquash2473 4 роки тому +6

    But just because you want one piece of information within the class to be transparent doesn't mean you want all of them to be. Some private variables within the class get accessors, but others that are important to maintain state within the class but should never be needed and certainly never changed outside of the class often still exist.

    • @roadent217
      @roadent217 4 роки тому +2

      "but others that are important to maintain state within the class but should never be needed and certainly never changed outside of the class often still exist."
      Right. So they don't get accessors.
      "Some private variables within the class get accessors, "
      Why? Why keep the variable private then? Why not make it public and access it directly? I'd say the only main reason to do so is if you want a variable access to have side-effects - if the getter or setter isn't trivial, but also changes the state of the program, sure, write it in. Otherwise, just make the variable public. Casey's ranting mostly about trivial getters and setters, such as those required under the JavaBeans convention.

    • @slysquash2473
      @slysquash2473 4 роки тому +3

      ​@@roadent217 My take is that he's not complaining about getters and setters in general; he's complaining about classes that exist EXCLUSIVELY of getters and setters because his solution is to make a struct of public variables and just be done with it. I'm saying that I can buy his rationale in wanting to eliminate such paper-thin classes that offer no useful methods but those required to access what are effectively-public data variables, but not all classes that contain data do that.
      I also don't buy accessor functions are always bad compared to just making the class variable public. For one thing, using accessors instead of public access gives finer control over restricting access to the variable. Maybe you decide that knowing the internal state of the variable is useful outside of the class but that it's too volatile to the inner workings of the class for it to be manipulated outside of the class: now you can eliminate the setter and make it effectively read-only. In addition, getters/setters free up naming conventions. You can use Hungarian notation, shorter variable names, or whatever convention you need for the private variable name, but when exposing it outside of the class you can give users of the class a more friendly/longer/clearer name.

    • @charlesalexanderable
      @charlesalexanderable 4 роки тому +4

      If it is all self owned code you should never do it. If it is exposed to third parties via a public API it can make sense to do.

    • @slysquash2473
      @slysquash2473 4 роки тому +1

      @@charlesalexanderable I don't know what "self-owned code" means. If you mean "one-man project", you can of course do literally whatever you want. If it means it doesn't expose a public API, what about the private APIs (i.e. those methods and functions intended to be called by other classes in the program but not by other programs)? A lot of large projects are structured if not at the class level then at the module level, often with these modules being compiled into libraries and "APIs" connecting the libraries to form the overall program. Accessor functions give tighter control to the module's developer (which helps its developer limit its state to what they expect) and still frees up naming convections (not all companies have rigid programming standards, and this can help modules to play nicely with other modules particularly in such environments). All of this can still be helpful even if your program doesn't expose an external API to "3rd party" programs.

  • @MrAbrazildo
    @MrAbrazildo 2 роки тому +1

    1:30, it's not absurd, because you are getting a copy of the data, which means it remains unharmed. 1:40, now this is absurd, because encapsulation evaporated. The setting-f(), if any, should not be public. Only 'friend's of the class should modify it.

  • @omnipi
    @omnipi 2 роки тому

    Hard disagree. Obviously using pointless boilerplate getter/setter cruft is bad, but that doesn’t translate to never ever ever use a getter. While I think very often private is overused (it should almost never be used), sometimes it’s good to have private data and a public getter/setter that forces the coder to appropriately access the data. An example to imagine is where a session management class may have a token stored: you don’t want someone being able to set this directly without going through your business logic, and use of willSet doesn’t necessarily provide the kind of control you need. Furthermore, it is also a healthy practice to make it so the user has to conscientiously know they are calling setToken, which can prevent errors that arise from access without realizing the consequences. At the end of the day the goal is making life easier for the programmer and sometimes - not often - a small barrier like this is your friend.

    • @Ignas_
      @Ignas_ Рік тому +9

      That's literally not a hard disagree. Casey said to add accessors when you actually need them. Not to just blindly add them for all variables, which often happens because it's considered "good practice".

  • @adamdude
    @adamdude 2 роки тому +5

    I'd hate to have this guy as my boss

  • @fangsunjian2
    @fangsunjian2 3 роки тому +10

    This is ridiculous.
    1.You can't use dirtyflag without setter
    2.You can't indicate whether the variable is safe in multithreading environment without const getter
    3.You will need to write a lot of code while trying access bitflag without getter
    4.Stop saying performance without profiling it. There is a lot of game engine using getter/setter. It's never ever a problem using a simple getter/setter. Stop your IMAGINATION.
    5.It's good to use struct when necessary, but which is not alwayse an alternative to getter/setter

    • @taxerap8498
      @taxerap8498 3 роки тому +1

      Obviously you do not see his point. Watch 2:31.
      He's not complaining about getter/setter that actually has use like safety or boundary checking, he is talking about getters like a simple { return xxx; }, and making fields private without any propose other than following the stinky "OOP style."

    • @SaHaRaSquad
      @SaHaRaSquad 3 роки тому +1

      He didn't say anything about cases with bitflags and other things where getters can actually be useful. Of course you want to put internal checks, side effects etc. in getters and setters so you don't spread those all over the codebase. But he's talking about the programmers who type (or auto-generate) getters and setters for all the class fields without even thinking about it, or considering whether it's needed in the first place. That's a sign of someone who doesn't really understand their purpose. Most classes don't have a dirty flag, data accessed by multiple threads or bitflags. And even if they have, you don't add the setters/getters before you actually need them.

    • @fangsunjian2
      @fangsunjian2 3 роки тому +2

      ​@@SaHaRaSquad No, he didn't say that clearly like you did. He didn't say under what circumstance should or should not use getter/setter, which will cause misleading information. Just like who type getter/setter without thinking about it, they will also ignore getter/setter everywhere, which i think is even a worse habit. So I give some tips how to use them properly.
      Furthermore, he never uses getter/setter in his video, all of the benifits I said is replaced by global function, copy&paste code, or human's memory, which has already caused a lot of matters.
      The reason I think is people dont't want to mix getter/setter and public variable in one struct/class.
      Since there is no actually performance imact with getter/setter, I strongly recommend to use it even if you don't know what it can do just now.

    • @dnkreative
      @dnkreative 2 роки тому +2

      @@SaHaRaSquad He actually said that if you write a getter it'd better be some logic behind it than just returning a value

  • @CacheTaFace
    @CacheTaFace 4 роки тому +3

    Y e s

  • @jpettys
    @jpettys 9 років тому +50

    Just wanted to lay down a comment here, for any aspiring software professionals looking for good advice, that this particular experienced programmer strongly disagrees with the content of this video. I find it very short-sighted, and only applicable in very narrow domains. If you're working on a large, man-year-effort level business application, you better not follow this advice.
    "Only a Sith deals in absolutes." Usually. :)

    • @vexedev
      @vexedev  9 років тому +26

      +jpettys I've seen those one-line setters/getters in large scale C++ applications million times, they do nothing besides getting/setting a value. Where is the value in that besides just having to type more and make it unclear what's actually happening when you're accessing those functions? Take for example Unity3D's properties such as transform.position , rotation etc. Every time you make a call to one of these, you're communicating with the C++ side of things, and probably allocating some memory in some situations behind the scenes - from the caller site it just looks like as if you're accessing a simple field - but in reality it's not, it's just that the cost is hidden from the caller - and if I learned anything the hard way in my experience, it is that hidden code that incurs hidden cost is to be avoided, it makes it harder and harder to reason about your system. Fields should be exposed, and the data layout of your structures should be clear too and not hidden.
      Yes if the getter/setter does something (not crazy) 'besides' getting/setting a simple value, it makes sense to put it in a function - in fact if you follow his stream you'll see him do just that.

    • @jpettys
      @jpettys 9 років тому +20

      +vexe In your Unity3D example, do you think that the "hidden" things can be avoided by making them fields? They cannot. And you imply a false choice by suggesting, "Either it's a simple field, or it's something crazy." There is a large continuum of extra things that a getter/setter may do. I could speculate that many Unity3D objects would benefit by having an internal, private dirty bit that gets flagged by setters, so that the rendering pipeline can be shortened in the unchanged situation. The recommended approach in the video leaves no way to make this performance optimization in later versions without introducing breaking changes. That's one area where the speaker's reasoning fails: that you can just rename a variable and let the compiler tell you where the fixes need to be made (@2:19). This is woefully simplistic.
      I think this gives just one very plausible example answer to your question, "Where is the value in that...?" All the arguments and papers from the past decades of managing complexity and coupling with encapsulation also answer your question.
      Too much typing is not a compelling reason here, especially if you're working in a language that supports a shortcut syntax for the getter/setter pattern.
      Consider the wisdom of some of these old timers who were banging out wicked code, presumably before either of us were born: "Premature optimization is the root of all evil." c2.com/cgi/wiki?PrematureOptimization Knuth said this when computers were many orders of magnitude slower than today.
      There's also an argument to be made about the general design of your system if, for most of the classes you are building, simple fields (and no private fields!?!?! @0:30) makes sense: stackoverflow.com/a/8368523/27846
      I'm not saying a class or struct should never use straight fields. For very simple datastructures in high-performance-demand situations, that's probably a good choice. But to call a general leaning towards getter/setter patterns "absurd" and "insane" "at the most fundamental level," "in every circumstance," with very little (none?) qualifying context, is, at best, unhelpful. At worst, it produces inexperienced, ignorant, yet arrogant coworkers.

    • @vexedev
      @vexedev  9 років тому +18

      +jpettys `do you think that the things can be avoided by making them fields? They cannot` - I didnt say that. I said make it `clear` which operation is expensive and which isnt, dont make expensive stuff hidden.
      `Premature optimization is the root of all evil` IS the root of all evil. Because its widely misunderstood and programmer end up writing lousy code and when someone confronts them, they reply with that quote. Its why I have to wait 30 seconds or so for Word or whatever to boot up.
      Not sure why you're linking to some C++ SO link. I don't know how much you programmed games, but it shouldnt take you long enough to realize that most of the practices, 'standards' and programmer fuss used in regular/business software development is not practical in game programming. Because the most important things in games is 'simplicity', which implies more robust, less error-prone and buggy, and easy to understand and follow code. Those practices encourage 'nothing' but complexity, driving your attention away from the real problem which is 'data', into some weird abstract relationships between objects that exist in some fairy land, not sure how that helps. So yeah all that paper stuff you mentioned, if it's not from game industry-standard elite programmers like Jon Blow, Carmack, Sean Barrett or Casey, it doesn't mean much cause the way things are done in games is just different than regular software.
      Jon Blow happen to have a rant on that as well "Implicit vs Explicit Software Engineering Costs" number-none.com/blow/rants.html
      Take private for example, it's pretty dumb. Yes it's a good idea to make it clear to your API users which part they use and which they shouldn't, but you don't need a keyword for that, just prefix with underscore and bam you're done! Then in your docs "Functions and fields starting with underscore are internal to the system" - A more useful keyword would have been 'readonly'
      "But to call a general leaning towards getter/setter patterns `absurd` and `insane`" - He was referring to dumb getters/setters that do nothing but return/set a value - and not all getters/setters.
      Maybe you should watch the handmade hero stream for a bit to see where Casey's coming from.
      Anyways, to each his own preference. For me I don't like spoon-fed materials. Program with whatever makes sense to you and makes you more comfortable :)

    • @jpettys
      @jpettys 9 років тому +17

      +vexe I don't agree with all your finer points, but here's the key: "If it's not from game industry-standard elite programmers... it doesn't mean much cause the way things are done in games is just different than regular software."
      You're pointing out that different values are important in different contexts, and that was my main, original point: that this advice is only applicable in a very narrow domain, from a general professional programmer's perspective. I'm sure if this rant were contextualized, it would become valid. But phrases like, "absurd," insane," "at the most fundamental level," and "in every circumstance," without context, are inflammatory and don't allow for thoughtful consideration of the trade-offs generally involved.
      Maybe this short video is pulled out of context and so it's not fair to Casey, but if it stands on its own on UA-cam, I feel it strongly needs the first, short comment I added so it's less likely to be abused in contexts where it doesn't apply.

    • @revealingfacts4all
      @revealingfacts4all 9 років тому +5

      totally agree. I work in the embedded field where my code runs on RTOS environments and C++ has been just fine. in the 90s I wrote in C for the gambling and betting markets which I think is very similar to present day quant type performance metrics and I never want to use C again. my C++ work is running behind the dashboard od many cars where graphics must be ontime and fast. the example in the video is a strawman at best. this guy appears to have no exposure to software development outside writing games and/or he has never worked with other developers to challenge his views and if he has, he suffers from a severe case of myopia. if you are someone just starting out, my advice is to not listen to another thing this guy has to say. my work is much like a game. in an automobile, my graphics code is moving speedometers, tachometers, communicating with the vehicle CAN bus and reacting to user input from the steering wheel mounted buttons which are often on a LIN bus. search you tube for Cadillac CUE if you'd like to see some of my work.

  • @BlazertronGames
    @BlazertronGames 5 років тому +5

    I don't understand what he's getting at. No sane person would write a getter/setter the way he did, he wrote it so it's essentially the same as a public variable, you'd probably put a check in the setter, otherwise there's literally no point. I must be missing something.

    • @Vitorruy1
      @Vitorruy1 5 років тому +45

      A LOT of OOP programmers and frameworks actually do just that

    • @BlazertronGames
      @BlazertronGames 5 років тому +4

      @@Vitorruy1 4 months later and I'm into java, lol. I actually just read something which IMO, justifies the use of getters and setters in that case. if you don't write a setter method, and months down the line, realise you want to do something when you set the value (limit within a range, etc.), you're screwed, you'll have to update every access to the variable with a method. But if you wrote a method the first time, you'd just have to update the method once, when you want to do something when setting.

    • @Vitorruy1
      @Vitorruy1 5 років тому +18

      @@BlazertronGames You are not screwed. Changing variable references is trivial. There is no reason to write and manage hundreds (thousands?) of dummy functions for such minor eventuality.
      The cost is big and real while the value is small and hypothetical.

    • @BlazertronGames
      @BlazertronGames 5 років тому +5

      @@Vitorruy1 Yeah, true. I don't know what I was thinking when I wrote that comment, java had me not thinking straight. Like casey explains, you won't need to limit the accessibility to a variable that often, and even when you need to, it's pretty easy.

    • @charlesalexanderable
      @charlesalexanderable 4 роки тому +2

      Java people do it. It can make sense in C++ only if it is in an API exposed to third parties you don't control.

  • @theyruinedyoutubeagain
    @theyruinedyoutubeagain 7 років тому +4

    The more I learn C++ (again, I started with it 10+ years ago), the more I appreciate Go.

    • @aiman_yt
      @aiman_yt 6 років тому +14

      Except generics, verbose error handling & garbage collection,

    • @mehmetakyuz5290
      @mehmetakyuz5290 5 років тому +4

      I hope Go or Rust or Jai dominates game programming instead of C++ in near future.

    • @alefratat4018
      @alefratat4018 4 роки тому +9

      @@mehmetakyuz5290 Go too slow, Rust too cumbersome, Jai is my last hope ;)

    • @mehmetakyuz5290
      @mehmetakyuz5290 4 роки тому +1

      @@alefratat4018 Yeap, same here :)

    • @blazefirer
      @blazefirer 4 роки тому +4

      you guys should look up Zig. Its an interesting new language and I think I am going to write my next game in it

  • @teilzeitbernd
    @teilzeitbernd Рік тому +1

    Pretty bad take, in my opinion.
    Sure, trivial getters/setters are ugly (less so, when done via an annotation or another shortcut), but that's a shortcoming of the language for not giving you the ability to override normal attribute access. But that's a small price compared to what happens when you need one later.
    Going by "compile error" could involve thousands of files in a large project, and good luck with any dynamic accesses that will only crash the system at runtime.
    And now there is mixed access in the code, where some attributes require using a getter and some don't, which means looking up how to use it every time, instead of having a consistent method behind it.

    • @aaronwinter7911
      @aaronwinter7911 8 місяців тому +5

      Id rather have a few miserable hours of fixing one up compared to having the entire duration of development being miserable because of having to type way too much for doing simple things.

    • @jesusmgw
      @jesusmgw 5 місяців тому +1

      You don't need to code defensively and fear refactors if you're engineers are decent.

    • @grenadier4702
      @grenadier4702 5 місяців тому

      Imagine you need a true value of getters/setterr only after they were used thousands of times. For me it's just an argument against them

    • @teilzeitbernd
      @teilzeitbernd 5 місяців тому

      @@grenadier4702 A true value? You're transforming the data and already are dealing with non-trivial getters and setters that are used all over the code then. Adding functions to deal with the raw values later on is no problem at all.

    • @grenadier4702
      @grenadier4702 5 місяців тому

      ​@@teilzeitbernd you literally have used this
      private data;
      getData() { return data }
      setData(value) { data = value }
      (which is an equivalent of just public data)
      in thousands of files and only after that you got the need to do something like
      setData(value) { data = data + 1 }
      So it basically means for a long time you had this
      setData(getData() + 1) in many many files and only after that you said: "Yes, I finally need some value out of getters/setters"
      For me, it's better to not use getters/setters rather having some rare moments when it's convenient to change logic

  • @darkdante2k4
    @darkdante2k4 6 років тому +14

    uhhh no. You come into a shop, and write that code then try to say code encapsulation isn't useful you'll be fired before your first commit

    • @suleyth
      @suleyth 5 років тому +52

      You’re arguing for what is accepted in enterprises, not for what’s the best coding practice.

    • @Vitorruy1
      @Vitorruy1 5 років тому +35

      99% of "encapsulated" classes can be set() by anyone anywhere. They have no encapsulation.

    • @comicsans1689
      @comicsans1689 4 роки тому +14

      Enterprise programming was a mistake.

    • @andrewherrera7735
      @andrewherrera7735 3 роки тому +4

      Python is popular but they know that encapsulation is bs.

    • @julioevr
      @julioevr 3 роки тому +1

      @@Vitorruy1 ironically funny. So so true.

  • @vvhat
    @vvhat 4 роки тому +22

    "I don't use private" You're not a software engineer, you're just maverick rebel programmer. You can argue about a lot of things, but separation of concerns? Jesus....

    • @skejeton
      @skejeton 2 роки тому

      bruh this guy works at epic games

    • @vborovikov
      @vborovikov 2 роки тому +3

      @@skejeton that means his payroll is calculated by software written by engineers with a proper encapsulation of that sweet sum field hidden behind getters and setters so it stays correct no matter what :)

    • @skejeton
      @skejeton 2 роки тому

      @@vborovikov sure

  • @mwatkins0590
    @mwatkins0590 7 років тому +19

    This guy is probably actually horrible at programming. This is one of the most unintelligent perspectives I have seen in programming.
    Getters/Setters causing a bottleneck? thats so ridiculous. Its almost always an inefficient algorithm or design pattern. Getters/Setters are just good design for many reasons, but I'm not getting paid to teach this on youtube.

    • @vexedev
      @vexedev  7 років тому +44

      Yo dawg where'd you get your weed man?

    • @mwatkins0590
      @mwatkins0590 7 років тому +7

      I usually get things from the paychecks I earn developing and designing software. Not sure whats up with your drug mindset.

    • @croakacola
      @croakacola 7 років тому +72

      Hello there. Casey Muratori mentions that getters/setters may cause a bottleneck because there is nothing stopping the programmer from doing something like "creating a hash table" or something other than the thing the programmer using the getter/setter is expecting. I have seen such things in real production code. But as far as I can tell, the reason for getters/setters is for the sake of encapsulation. For example, maybe you want to validate the data before accepting it in the setter method. You would probably want to throw an exception in that case or do some other forms of error handling. This is not uncommon. I believe Muratori argues against such encapsulation because he believes it to be unnecessarily verbose, and/or adds a potential bottleneck to some performance critical section. All valid criticisms, and common at that. He is a programmer for video games. Games need to be fast or customers will complain.
      You are correct that it's almost always the algorithm or the design of the program that is the heart of a bottleneck, but simply being a potential bottleneck is only part of his larger argument.
      You are incorrect that Muratori is "horrible at programming." I know this because of his accomplishments at RAD game tools and his work on Handmade Hero, if a "horrible programmer" was able to do what he does, then I don't know what to think. To say his perspective is "unintelligent" is just baffling and you say NOTHING to back up your arguments because "I'm not getting paid to teach this on youtube." Wow, what a maverick.
      His rants get hyperbolic at times, no one is perfect. If you have a point against his argument, please state it. Resorting to ad hominem detracts from useful arguments that some people are genuinely curious about.

    • @sasuke2910
      @sasuke2910 6 років тому +39

      I tried to port a Starling game to Android, but the Sprite().width property was a getter that did nested sprite size calculation, so I had to build a getCachedWidth() and find/replace it everywhere because all my code was accessing those properties assuming it was basically free. The implications that getter and setters gave me actually caused me to eventually give up on it because there was so much hidden bs going on behind every variable access.

    • @dumitrufrunza8136
      @dumitrufrunza8136 6 років тому +43

      "This guy is probably actually horrible at programming." - it's a losing bet. Casey M. is *not* horrible at programming, and there's enough evidence to back that up. Would like to see same similar evidence from the people who came up with the idea of get() / set(). Got any?

  • @devoiddude
    @devoiddude 4 роки тому +11

    This guy is talking out of his ass, FULL STOP!