The author seems to misunderstand the open-closed principle, and his first example confuses bug-fixing with API modification. The open-closed principle is designed to promote API stability and reduce errors caused by API contract changes that cascade to its users. A class should expose an interface that allows for such contract changes to be encapsulated in subclasses. This is not a "debunked" or "outdated" idea, especially if you are designing APIs for public consumption.<p>Then there's a bunch of stuff about properties that seems to go around in a circle...<p>It seems that his rationale for this rant stems from poor API design by others---where class modification through sub-classing is impossible to achieve because of opaque interfaces. This has nothing to do with people using private variables, and all to do with people not designing proper and extensible interfaces.
I found a few problems with the article.<p>Firstly, right at the end, he says: "Remember, unless you unlucky enough to be using Java or another archaic language with no proper property support, you can always refactor your class to replace a public field with a protected one with a public accessor property if requirements change". Is Java really considered archaic nowadays? C++ and Java probably make up a fairly large portion of programs written today, and this article doesn't address them. Probably should have mentioned that at the top of the article.<p>Secondly, his example of why the principle of “open for extension but closed for modification” is a not great. He gives an example of a class with a "div" method that is found to contain a bug. Instead of fixing the bug, a "div2" method is added which fixes that bug.<p>The problem is, that's exactly the approach I would advocate in plenty of situations. When I was in charge of QA for an embedded system, if he'd have come to me with a bug 1 week before a release, I would never have agreed to fix it. In a big enough system, you can never tell what code relies on bugs to work, and would break if that bug was removed. This is a lesson that was hard to teach most of the programmers, but in the end, whether the system actually works or not matters a lot more than whether the code contains any bugs.
OO seems to be the proverbial elephant: everyone touches a different aspect of it, and comes away with a different understanding.<p>Unlike the blog author, I'm not sure the most important part of it is data hiding.<p>Alan Kay said in 2003: "<i>OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late binding of all things.</i>"<p>In terms of the last part of that definition (the late binding aspect), I saw Kay give a demo where he described a framework wherein any method can act on any object.<p>I.e., he rejected the C++ style idea that a method is bound to a specific class, and can only act on that class.<p>This is an idea from Smalltalk, and you can also do it easily in Lisp.<p>BTW, if this seems unnatural, think about the Visitor pattern, which allows you to do exactly this, within the framework of C++ style class definitions.
There <i>is</i> a difference between a library author thinking his users are too stupid and a library author reserving the right to replace his tree-map-with-cached-most-recently-accessed-element with a hashmap in the next version.
The article may be a bit on the drastic side, but I do agree with the conclusion that libraries should not treat everyone like idiots. Keep the users from shooting themselves in the foot, yes, but If someone is extending a class in a library, then they have the burden of doing it right. No developer can predict everything people will want to do with his/her library.
<i>Imagine I have a system that generates a series of graphs based on a changing complex number. I could use a round-robin approach of constantly calling a set of functions, passing in a new complex number each time. This would work, but it’s incredibly clunky and doesn’t scale well. Alternatively, I could create a sub-class of ComplexNumber that uses a callback to expose its fields to just the main controlling class. I then use dependency injection to give all the graph drawers access to a reference to that value. The graph drawers can then run independently (say in different threads) and only the controlling class gets to change the value contained by that reference. This is a far neater. more robust and more scalable solution.</i><p>So, the neat, robust, scalable solution is to subclass his immutable value class to make it mutable and then inject it into code expecting the immutable class and change it behind their backs?<p>Step away from the compiler...
I'd go further. I think inheritance is the modern day goto. I used to consider myself a bit of a 'framework engineer'. I was wrong. Inheritance creates structures that are difficult for you to refactor and others to understand.<p>As I moved away from java and settled into the vibe with python, I've abandoned inheritance. I use simple objects, but tend to orient encapsulation around modules, at to do real encapsulation at this higher level (rather than with classes). It's faster to write, easier to read and much easier to refactor.<p>I like the Kay quotes that dpapathanasiou raises in another comment here. Are there books or other references that seek to teach "message-oriented programming" with mainstream languages like C or Java?<p>(On the author's main point I disagree. If you're going to do a lot of inheritance you need private variables, otherwise it's easy for descendants to create hard-to-diagnose bugs.)
Title is a bit incendiary, what the author really means is this:<p><i>Before we go any further, let me make one thing clear: the well thought out use of public properties and hidden fields is good practice as it hides the implementation. What I’m suggesting is that blindly using them in a simple full-mutable record-style (or tuple-style if you prefer) class is bad practice.</i>
I agree, at least partially, with the author.<p>In Java, I use package visibility a lot and since starting to use Ruby in a big way about 5 years ago, I often just make attributes public - no getters/setters. A bit sloppy, but makes code shorter and easier to read. I admit that this makes APIs less stable, etc.<p>On large or huge projects, I would follow conventional wisdom for Java best practices, but for smaller projects, shorter code and better readability works for me.
I couldn't agree more. As someone who deals with implementing and customising 3rd party libraries a lot, it's highly frustrating when things are private just for the sake of it. Things should be made private when there's a specific way of accessing/altering that variable, not because you don't think anyone will need it.
The author clearly has no concept of using the best tool for the job, he just has a beef with a few programmers doing things wrong, and his response is to act just like them.<p>I'm sure he was the kid on the playground who took his ball and left if someone didn't play by his demanding rules.
He completely lost me here:<p>"The 'goto' statement took a long time to die, but it has gone from being a fundamental programming concept to a programming pariah used by only the most misguided of developers."<p>Rather ignorant, and just plain incorrect.
The divide by zero anecdote is really odd. He offers it as an example of something crazy "they" used to do in the olden days (before "they" knew better), but the twist at the end is that he proposed it and his coworkers voted it down.