4 ms·
I can't speak to Java, but in C#, the original goal was to reduce coupling. You can add behavior to getter and setter methods without breaking binary compatibil
by bunderbunder 9y ago
I can't speak to Java, but in C#, the original goal was to reduce coupling. You can add behavior to getter and setter methods without breaking binary compatibility among packages. It absolutely is obfuscation, to the extent that encapsulation is just a special kind of obfuscation.
Possibly more importantly, public fields give you no way to create immutable types.
- flukus 9y ago> Possibly more importantly, public fields give you no way to create immutable types. public readonly int Foo; readonly fields can only be set in the constructor, great for immutable types and with much better guarantees than protected/private/no setters.
- InclinedPlane 9y agoAnd when you want to make Foo no longer a primary value and instead calculated from some other field? When you want to add logging to every change of Foo? Every access? When you want to switch to having Foo's value come from a database? Web service?
- flukus 9y agoThen I'd change it to a property and recompile. If it's value comes from the database or a web service then nothing has to change, whatever is calling the service will invoke the constructor as always. The only exception here is for public APIs, but that's a minority of projects.
- zmmmmm 9y ago> Then I'd change it to a property and recompile You mean, change it to a property, then fix dozens or hundreds of references, possibly in downstream dependencies some of which aren't under your control and can't be changed. Sounds fun.
- alkonaut 9y agoThen that is when you have to change the public field to a property, with no change to calling code. Reasons for going with a property from the start is if you a) ever use reflection (which would need to change depending on whether the storage is a public field vs a property) b) If you need to implement interfaces using the property. Reasons for going with a public field is for special cases where you know a lot about how inlining affects your performance. Typically in structs. Since there is no more boilerplate used to write "public int Id { get; }" vs "public readonly int Id", in 99% of cases I'd choose the latter.
- kevingadd 9y agoThis isn't true. For structs you can use 'this = ...' to overwrite yourself (including readonly fields) and reflection lets you set them too. fwiw those are both gross but I've run into both in production code (not written by me, naturally)
- flukus 9y agoThe same can be said for setters and getters with a backing field, you can access them through reflection. I can't remember how it works for properties with implicit backing fields but I thought they could be set via reflection as well?
- kevingadd 9y agoYou can find the backing field and set it, yes, but the name is at least not predictable because the compiler mangles it (which discourages doing this because getting a grip on the field is harder)
- HumanDrivenDev 9y ago> I can't speak to Java, but in C#, the original goal was to reduce coupling. If you want to reduce coupling, why not write a real method? Get/Set couples you to your class fields. If you change your class fields, your getters and setters all suddenly become useless. Maybe I just hate the middle ground (:
- bunderbunder 9y agoNo, they don't. I have, plenty of times in the past, changed a class's implementation details in a way that results in fields being removed, without having to create a breaking change in the associated property getters and setters. All it took was changing their implementation to work with whatever the new thing was.