What would you say if you saw a C# framework that had classes with public fields. No, I'm not talking about const fields. I'm talking about public non-static mutable fields.
If you are like most developers, there are probably a number of things running through your head now. One is that whoever wrote the code must be naive. We all know that public fields are bad. At the very least, fields should be hidden behind properties, or at least getters and setters. It's just bad practice.
But... how do you know?
One answer is: because violates style rules. Another is: it ignores years of experience formulating best practices for programming.
But, again, how do you know it is bad?
I run into this problem frequently now. It seems that we're very good about articulating rules and best practices. If you go onto any newsgroup or mailing list, you'll find a number of people who will argue with you about the right way to do something. However, the saddest experiences I've had with teams are times when I've visited and seen code that applies nearly every "best practice" you can imagine, without thought. You look at a particular situation and you see that, well, in this particular case, the advice of so-and-so in this-or-that book about programming in C++, C#, or Java doesn't apply... that there is some much more contextual way of doing things, but no, the rule is the rule and we have to argue.
Good programming is contextual. Practice is contextual. We can articulate rules about how to use language constructs correctly, but they're just guidelines. Context is king.

Comments (9)
... and elegance is queen.
Posted by Anonymous | September 10, 2007 12:52 PM
In this one example, I know because I've had to spend hours upon hours changing them, and everywhere that used them to getters and setters in order to track down a bug in how they were used. (And I've actually run into the same problem again, where a field is protected instead of private, and someone's not cleaning it up correctly. Just how do you find a place where someone isn't calling a method, anyways?)
Posted by Blake Winton | September 10, 2007 4:58 PM
You're right, only if the writer has a perfect understanding of this program and its environment, so he knew and proved that it can make no differences to make it public.
But most of the time a class field is a parameter to some computation so we feel happy to restrict or permit its mutation the way we (the program writer) want, so we can keep a coherent representational state of our objects.
my 2 cents ^^
Posted by fasteez | September 11, 2007 4:13 AM
I agree that if someone is unaware of industry best practices, then their breaking of them is likely to be a bad thing. I personally break industry best practices because I disagree with them. I'd rather have a public field in Java until I need something more sophisticated.
Ideally, changing from a public field to a getter/setter pair shouldn't be a binary-incompatible (or even source-incompatible) change, but it is. If I didn't have an IDE that could perform the refactor, or if the code was public-facing then I'd probably stick with a getter/setter pair to begin with (or a public final Property field).
Posted by Ricky Clarkson | September 12, 2007 1:42 PM
Bravo, great post. I run into this all the time. I don't know if it is lack of experience, knowledge or just looking for easy answers. But many developers seem to want hard and fast rules that just don't exist. I won't even use the word "rules" anymore and only talk about "guidelines". That way I reserve the right to change my mind for the same thing done in a different context.
I think the previous comments are missing the point by focusing to much on the example.
Posted by Richard Hansen | September 14, 2007 1:57 PM
A good seasoned programmer often makes the wise decision to break a particular guideline, but there are only few such people and the chances are less that the reader of the code is equally as experienced as was the writer. And so it often (read always) happens that we curse the writer. But I completely agree "Context is king" and if you happen to see any good coding practice document, the author will always emphasize on thinking in context. One golden rule (and not a guideline) is : When you break a rule/guideline and tend to be different than your project-team write a line of comment to explain. The reader will always appreciates you. Good contextual comments always make beautiful code.
Posted by Shuva | September 25, 2007 12:38 AM
Huh. I'm not the most guideline-following programmer in practice, but in principle I don't think many basic guidelines are contextual, i.e., a really solid guideline makes sense on almost all large projects. Most guidelines are born from some scenario where breaking them causes a screwup, e.g., you should write unit tests for as much as you can so that testable bugs don't slip through; you should name variables consistently so that you don't forget and misspell names; you should use getters and setters so that you can later add processing code on get/set. In a large, long-lived system you've got a pretty good chance of running into the screwup scenario, and the screwup tends to be more costly than following the guideline.
I do agree with you that systems that follow guidelines can still be really bad. Furthermore, teams sometimes get the big things right -- keeping designs simple, paring down requirements, having a vocabulary of idioms and libraries and tools and so forth, managing expectations, effective testing and debugging -- and manage to do a great job (especially seen from the outside) while breaking a lot of rules. We're in agreement that rules aren't everything, but even folks like Steve McConnell admit that.
I bet you've read it, but Steve McConnell's Software Project Survival Guide is lovely.
Posted by Randall | September 30, 2007 3:01 AM
What's wrong with public fields? That's just telling the people using them that there is no guarantee anything will happen before they are set. How is this at all difficult? If you want guaranteed options, scroll up and erase the word public and type in private.
Object.field = "x";
works just fine. It just provides no guarantees.
Object.setField("x");
This looks a lot more impressive. I hope it makes you all feel good about this "best practice".
How many java programs have pages and pages and pages of getXyz() nd setXyz() that do nothing at all? Line count is not the goal, setting and retrieving variables is the goal and getters and setters 90% of the time don't matter at all.
Posted by Lance | October 4, 2007 3:38 PM
From the Java world, get and set are required to make an object a 'bean'. The gets and sets became hugely popular when they became requisites to deploy objects on many engines.
I think this is exactly the difference between struct of C and class of C++/Java/C#... Inheritance, polymorphism is possible through private fields with gets and sets. Also, if
1. these objects are complex objects that require the incoming/outgoing data to be modified
2. these objects are required to satisfy some contractual bindings such as read-only (i.e., getters only)
I reckon that unless an object will never change, or the usage is very limited, it is better to have getters and setters.
Posted by sipayi | October 11, 2007 1:13 PM