I was wrong regarding the private keyword. Here’s why
At the time, I noticed that most of the people agreeing with my anti-private stance were – like me – Flex developers. If you want to see an example of badly written OO code, in which the use of the private keyword causes endless problems, I’d recommend taking a look at some of the Flex framework source. A lack of interfaces, gigantic classes and massive use of inheritance make it a tough framework to work with. Having important functionality hidden away behind private methods makes a bad situation far worse. At the time, the solution to me seemed simple: ban the use of private, for it was clearly the cause of many of the problems with using the Flex framework. Or so that was the way I saw it.
Time moves on and – like any half-decent developer – I have continued to expand my understanding of, and skills with, software development. Through conferences like QCon and try {harder} and with help from folk who, instead of just saying “you are wrong” sought to teach me why, I have come to understand that private members are a symptom of bad OO design, not the cause of it. Some of these people have taught me much and deserve a name check: I’m thinking of you Till Schneidereit, Stray (Lindsey Fallow) and Shaun Smith.
To understand why I had a problem with the private keyword, consider the following real-world example. In an application I was working on, we used the Flex 3 component NumericStepper. This component is a text field with up and down buttons. A numeric value can be entered, or the up/down buttons can be used to select the desired value. In one case, we used the component to set a value with one decimal place. Our QA department raised an issue against it as it would advance up through numbers thus: “1.8″, “1.9″, “2″. The significant decimal place was lost on a whole number and they wanted it fixed so it would advance as “1.8″, “1.9″, “2.0″. To fix this, I delved into the source of the component to see what was going on. The method responsible for setting the value was:
private function setValue(value:Number, sendEvent:Boolean = true, trigger:Event = null):void { var v:Number = checkValidValue(value); if (v == lastValue) return; lastValue = _value = v; inputField.text = v.toString(); if (sendEvent) { var event:NumericStepperEvent = new NumericStepperEvent(NumericStepperEvent.CHANGE); event.value = _value; event.triggerEvent = trigger; dispatchEvent(event); } dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT)); } |
The key line was inputField.text = v.toString();. All I had to do was change this behaviour. But there was a problem: the method was private. I couldn’t change it’s behaviour. We ended up creating a special case TextInput class, overriding its text setter, which formatted the text as we needed it, and then forced the NumericStepper instance to use our new class through a series of hacks and bodges to the code. The code was unintuitive and required lots of “this is why we are doing this weird shit” comments to explain why we were doing it the way we were. All because a vital method had been marked private. This is just one of many cases where the use of the private keyword in the Flex framework makes life hard for users of the framework. We actually seriously considered doing a global replace of all occurrences of private with protected and rebuilding our own version of the framework. It is unsurprising therefore that I concluded the the use of private was a bad thing and ought to stop.
At this point, it’s time to introduce the SOLID principle. A good OO design will obey the following principles:
- Single responsibility principle: an object should have only a single responsibility.
- Open/closed principle – classes should be open for extension, but closed for modification.
- Liskov substitution principle – objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.
- Interface segregation principle – many client specific interfaces are better than one general purpose interface.
- Dependency inversion principle – one should depend upon Abstractions. Do not depend upon concretions.
An examination of the Flex framework quickly reveals that its formed from a set of gigantic classes, many of which are thousands of lines long, each with many responsibilities. They are often closed to easy extension, such as shown above in the NumericStepper class. Classes such as the Menu class break the Liskov substitution principle by extending the List class and then crudely hiding list functionality such as scrollbars. There are very few interfaces in Flex, much less many specific interfaces, so the interface segregation principle is ignored too. Finally, it’s heavy use of locator patterns and singletons mean it doesn’t work well with injected abstractions. It is hardly surprising that a framework that breaks all the SOLID principles also suffers from misuse of the private keyword. When looked at this way, I started to realise that maybe the private keyword wasn’t the problem.
In the last year or so, I’ve adopted a very simple rule for the code I write and that those I work with have been bullied into adopting too: a class should aim to be less than 100 lines and must not be more than 200 lines. This simple rule has a profound effect upon code. Classes become simpler and more focused. Rather than having to extend existing classes, simply implementing another version of an interface becomes the simpler solution. Those interfaces need to be numerous and focused on a few methods to keep implementing classes small and dependency injection tends to get used without even thinking about it. In short, the SOLID principle almost falls out of small classes. It stops being a principle that one must struggle to achieve and becomes a by-product instead.
Small classes had another effect too: protected methods become unnecessary. As classes tend to be replaced with alternate interface implementations, rather than being extended, there are no need for protected methods. Testing the public methods of a small class tests its internals too and so there becomes no need to expose those internals for testing. In short, those internals become implementation details that can be marked private. In so doing, the open/closed principle neatly comes into effect.
In summary, I’m still glad I wrote my anti-private article two years ago: it forced me to put into words those frustrations I was suffering back then. Two years on I’m older and wiser and now understand I was wrong in what I wrote. Private members are a good idea, but only in well written code. So I now write my code better than I did before and I have started using the private keyword once more.
TweetShare This Post...
10 comments so far, click here to read them or add another
10 Comments so far


all good except the”forcing everyone to make classes 200 lines or less” was actually something that I enforced using checkstyles and you, yes you David, were dead set against at the time!
So, let me get this straight… Instead of one class of 500 lines you will have 5 classes of 100 lines. Right? Same amouth of lines still… And it might be more hard for a new developer to instead of searching in 100 classes, to search something in 500 classes.
If you are not carefull you will make it much more hard for new people to know there way around your code.
If a class is 300 lines of code, and still has the SAME responsibility, there is nothing against it.
Obvious, classes with multiple responsibilities should be avoided to the best we can.
“concretions”
really?
I get funny looks when I say “accessors” and “mutators” instead of “getters” and “setters”, and the first two really are words.
Just because “abstraction” is a word does not mean that “concretion” is, and if you are going to invent a word to replace “concrete implementation”, at least make it a nice one.
Cheers
Another Arno u-turn!! I am still half convinced on this one though, I think it generally makes sense to leave things protected unless there is a specific reason to close off extension.
One thing I would say though is that while the principal of keeping your classes less than a couple of hundred lines is a good one, I believe personally that keeping methods small and the cyclomatic complexity low is more so important. A 100 line class which just contains 2 methods is not much better, and will probably be a headache to unit test. Also I find that generally you are unlikely to have several interface implementation without a bit of shared logic, so the abstract base class is often required, and so the protected methods generally come with it.
@rvt,
Give it a try: I promise you you will find it far easier to navigate your way around five 100 line classes than one 500 line class. Small classes encourage smaller, simpler to understand methods collected into more focused classes.
@Richard C Haven,
“Concretions” isn’t my term. I quoted it from Wikipedia. Sorry if that wasn’t clear and I agree it’s an awful term. I didn’t think it right to modify the quote though.
@anonymouse dodd,
I agree that small methods are important too. I aim for methods to be as near to just one line long as possible
@David: I think you are to harsh on your 100-200 line rule. It’s just pointless to create a new class just to justify your 100-200 line rule. This class properly needs to have a interface created just to justify a other rule. So instead of one class now you have 3 classes. Just for the insane moment that somewhere in it’s lifetime it needs to get replaced through whatever method.
What’s far more important in the OO world, and that’s what we both agree on is “Single responsibility principle: an object should have only a single responsibility.”
If a class is 400 lines, or heck 600 lines of code with a couple of well organized methods. then this doesn’t have to be split given the class just has one responsibility.
According to your above rules, 600 lines of code separated out would generate 5 more classes. SOLID principle sounds good to me and I agree on that, don’t get me wrong I understand what you are saying.
I actually think you have been right on the spot with your first posting. I know that I’m not in concord with the OO main stream, but private class members and methods are a bad thing in open source frameworks. There is hardly any functionality in a class that would require to be protected in this way provided the class is developed right in the first place. I have hit flex framework limitations due to senseless private members and methods so many times that I stopped counting. I love Flex for many reasons, but this is an area that needs to be addressed. Now as it is part of the Apache foundation I hope some of these issues will be addressed over time.
Hey David,
thanks for the shout-out, and for the great post!
As per our discussions at try {harder}, I think the most important reason for making members private in a framework’s classes is that making them protected means they become part of the API you have to support.
Sure, you can always say that the only API you support is the public one and that people relying on protected members are on their own. In reality, though, the amount of support you have to do and the sheer unhappiness people will suffer once you change the behavior or name of a protected member (or remove it entirely) will quickly pile up to show you the errors of your ways.
In Robotlegs 1, we realized pretty fast that changing any protected members just wasn’t feasible. That doesn’t mean that we’re happy will all the implementation details set in stone by that, though.
All of this only matters if anybody’s actually using your framework[1], of course, but that’s the situation we’re talking about, right?
[1]: note that this includes past-you, in a legacy project far, far away.