12
wowotek
5y

this is my legacy code, it's stupid, Change my mind.

a large number of lecturer and friends are against my thought. personally, i think this kind of code is told to be an OOP yet this is against the OOP concept. why ? first you assign the field to be private, but you implement Getter and Setter method later on, this is the same if you assign the field to be public in the first place.

another minor thing; yes this is old me, i use Bahasa Indonesia as a variable name.

Comments
  • 17
    Methods in OOP are way more powerful than fields; they can be overridden by subclasses and abstracted into interfaces.
  • 14
    You can also implement validation, accessibility checks etc. in the getters and setters, and set different levels of visibility for the getter and setter. Even if you don't do this right away, using methods allows you to retrofit this functionality without breaking existing code if you need to in the future. In short, this *is* the correct and conventional way to do it for a number of reasons, and you should continue to use getters and setters rather than just expose the fields as public.

    There is an argument that Java should implement this as a language level feature similar to C#, but that's a separate point :)
  • 13
    Wait wat? Are you calling this code legacy BECAUSE it uses proper encapsulation rather than c-struct-like functional programming style where members are accessed directly?
  • 3
    The point with better possibilities for later functionality has already been mentioned. You could even have full checking in every getter/setter for the debug build and remove that for release if you need more speed.

    On a higher level, however, encapsulation in OOP is largely a myth anyway.

    @netikras encapsulation that is worked around by getters/setters isn't that much encapsulated anymore.
  • 9
    @Fast-Nop ummm... I disagree. Getters and setters lead class users to *assume* the class has fields with these names. It does not mean a class actually does have them.
    The class exposes functionality via public methods. It does *not* say how it's implemented. This applies to getters/setters too. setLayoutX(double x) could simply set its field to 'x' value. It could also send notifications to its components to recalc position. Trigger some events, validation checks, etc.

    Encapsulation allows developers to enhance a class without bothering its users.

    Moreover encapsulation prevents class users from corrupting internal clockwork.

    Tbh I write code using all oop principles, using design patterns and according to clean code 'rules'. If I wouldn't the code would become messy and would look more like a puzzle. I couldn't do it w/o encapsulation...
  • 1
    there should be a Vim plugin which runs all of the function/variable names through Google Translate Autodetect -> English
  • 0
    @netikras adding one empty level of indirection like in the OP isn't really encapsulating anything.

    And 1:1 setters enable users to mess up the class internal clockwork because there is no internal clockwork. Actually, the whole class from the OP is pointless because it's really just a bloated struct, and a proper language like C++ would leave the choice to the programmer whether he wants a class or a struct.
  • 0
    @netikras i am exposed to haskell and this is why my thought came up. i see it useless to do this, i like to use interface to override setter and getter, instead creating a class in the first place.
  • 4
    @Fast-Nop hiding private parts behind public accessor methods allow you to protect the clockwork. Allowing direct public access to internal fields restricts you from any kind of protection of your logics.

    Additional layer of abstraction is *not* encapsulation. But encapsulation allows you to create additional layer of abstraction.
  • 2
    if it’s java use lombook so you don’t need to write those get/set methods
  • 0
    @irene finally, someone agrees with me
  • 0
    @netikras yeah the easier extensibility is a valid point. However, overdesigning into YAGNI is also a valid point.

    The actual reason for this pattern, at least in Java, is that Java stuffed everything into classes whether it made sense or not, at least back then it did, because it came out during the peak-hype of OOP. That's not OOP, that's shoehorning things into OOP.
  • 1
    @Fast-Nop code is alive. It evolves over time. People maintain it, add features, some incompatible with it's original architecture and implemented as hacks.

    It is very important that the software is written from the very start as extensible as possible without gepardizing too much development time.

    So that you don't reinvent the wheel every time, there are common ways to write stuff. One of them is encapsulation.

    Say you do it your way - you access members directly. Your class is then used in 200 different other places, that work with members directly. One day someone wants his code to subscribe to a member, and react to any access, with information about that access.

    He will curse you and will hope that you would have never been born, because now, after you've acted as if you know better than everyone else, he has to modify the entire code base, instead of a 5 minute coffee change in the getter and setter.

    And this is a frequent scenario.
  • 0
    @Fast-Nop imho yagni is far better than yagbatui - ya ain't gonna be able to use it. At least without breaking stuff that already works.. 😀

    where does this mindset of yours come from? I'm curious, cuz you aren't the first person I have this argument with. I wonder why is that
  • 0
    @AndSoWeCode well yeah the extensibility is a valid point, I'm saying that now for the third time, and of course there can be useful cases for getters and setters.

    But in the concrete example shown, it's not, and designing for all eventualities gives bloated code full of so many indirections that it becomes easier to throw it away and code something new.

    Besides, when the responsibility for the state of an object becomes so scattered that access logs are necessary to find out who is accessing an object, that points to an architecture problem.

    And I wouldn't really want to maintain a code base where setting one object launches totally different actions somewhere else. Such side effects are not really nice for maintenance.
  • 1
    Imo such classes - with private members and getters (and sometimes setters) - are those that actually represent data. In this case they simply *are* c-like structs (+ maybe immutability) and those getters and setters provide no advantage.
    And if you need a getter/setter in any other class then you don't have the correct abstractions.
  • 1
    Some random thoughts.

    #1 Stringly typed system 😏 The people advocating getters and setters for future-proofing should also want name to be an object so that you can extract first and last names plus validation (ctor), yes?

    #2 I cringe at all the boilerplate getters and setters in Java. I'm a fan of C# style properties. The danger with props is that what appears as a simple member variable read can infact be an expensive method invocation. But at the same time, if everything is a getter I get no indication that a call is actually expensive.

    #3 I've tried using Swedish variable names once and it was super weird since 'get' is Swedish for 'goat' so reading getters was super weird: 'goatName()', 'goatAge()' etc.
  • 1
    @netikras I've seen too much software designed along "everything should be always possible because you never know", and the only thing you can actually do with that is throwing it away after several rounds because rewriting it will be easier than trying to untangle the resulting web.

    The likely future extensions are taken into account of course, but clean design is not only marked by its capabilities, but also by its constraints.

    The most easy to extend architecture I prefer revolves around layers or actors passing around messages, and that gives you real encapsulation if you define the allowed message routing.
  • 0
    @host127001 soo... Is all the javafx framework riddled with wrong abstractions? And Spring's bean registry? And spring data? Hibernate? Other frameworks using setters/getters?
  • 2
    @ihatecomputers to #2: Have you seen Kotlins getters and setters? I already liked the C# ones, but Kotlin is great.
  • 0
  • 2
    @host127001 Noooo, but I'm going to check that out right now. Thanks!
  • 1
    @host127001 interesting 😀 so I guess builder pattern is also created just to be a bad practise. Got cha ;)
  • 0
    @netikras I actually dislike those kind of patterns. Well, I am just one of those grumpy fp guys :D
  • 0
  • 1
    @netikras functional programming
  • 1
    @host127001 Cool! Kotlin getters and setters look neat. I really like the var and val distinction.
  • 0
    @Fast-Nop the fact is that it's easy to implement encapsulation. IDEs support it. And the overhead is cheaper than the huge maintenance overhead if you don't use encapsulation.

    And the fact that now it looks like this doesn't mean that no class ever in that project won't benefit from encapsulation.

    Writing proper code might increase initial code complexity by a factor of 3, but for the future it avoids exponential maintenance complexity of having to refactor the entire code base when changing the initial member by a method pair.
  • 5
    Eww, variables capitalized
  • 4
    1. This style can be useful.

    2. This style can be awful.

    3. Don't follow OOP principles blindly without understanding why they exist.

    If this class is a true "object" then getters/setters can indeed aid in validation, test mocking, adjusting internal behavior without changing public interface, etc.

    But there are plenty of cases where an object is more of a Composed Type, a Struct, a DTO, whatever you prefer to call it.

    In those cases, it makes more sense to have public fields and static methods instead of protected fields and public methods.
  • 0
    Just because you CAN doesn't mean you should.
Add Comment