iay9_q
Last Updated: February 25, 2016
·
2.418K
· dmichaelavila

Your Privates Stink

If ever there was a bad smell for lazily designed objects it would come from private methods. Every private method introduced should be a red flag, triggering a second glance at how responsibilities are being divided between objects.

Good objects provide a trustable, well-balanced interface to a simple implementation of some useful metaphor. Object-oriented programming is all of the activities we employ to make good objects. Unfortunately, many people mistakenly apply these activities to only a narrow aspect of programs, what is called the domain model, leaving the other domains that converge on the program to rot.

Often the mistake is in assuming that the business domain is the only domain that needs to be modeled. Instead, it should to be understood that many domains come together to make a program possible. Rotten software, like everything else that rots, is found hiding in the neglected, intentionally overlooked, private corners of things (in this case objects.) Each private bit of behavior is an opportunity for a new domain of good objects to take over. Freeing up your objects to do only those things relevant to their specific domains.

If you find yourself making private methods ask yourself why and see if there is a better design tool available. If you don't think one exists, consult someone who might provide a different perspective. Either way, seek out some way of solving your problem that doesn't involve hiding behavior. I worryingly quote the NSA, "If you have nothing to hide, you have nothing to fear." If you have something to fear, you probably have some poor design.

10 Responses
Add your response

10532

It's difficult to see what exactly you're trying to condemn here since you didn't give any real examples, but labeling a methodology entirely "bad" based on subjective experiences seems a little silly. Software isn't black and white. There is never one way to do something nor is there one right way. Private methods are useful in some circumstances and can be used without being overly obscure. Some methods are only intended for use inside the class it was written for, and revealing them could lead to exploitation or complete breakage. Sure, people abuse private methods and conceal useful information, but slandering a certain behavior because of abuse is a unreasonable and naive.

over 1 year ago ·
10533

@brettof86 my point is to question the idea that "private methods are useful in some circumstances." What I'm suggesting is that they are a crutch for what could be further productive design. I specifically tried to cast it as a "bad smell" so that it might be used in the way bad smells are used. I'm as guilty of poor design as anyone else is I'm sure, but when I'm given the chance to clean up my design I like having things that cue me with where my design might be improved. Private methods are an excellent cue, they smell bad, I can almost always productively redesign the private aspects of my objects into public objects from a slightly more specific domain. I don't think this is unreasonable and naive. In fact I think it's good advice.

over 1 year ago ·
10534

There's a very distinct difference between bad design and refactoring. Most people see refactoring as rebuilding poorly written code and it's not. Refactoring is taking what you have written and reassembling it to fit a better design. When it comes time to refactor, your private methods are some of the first to go, but they're not immediately a decision of bad design.

There's a real problem engineers have these days with trying to see too far in the future. We're engineers, not time travelers. YAGNI is a very prudent principle that most engineers forget to consider when they're starting development. Don't bother with overthinking designs and patterns before you even have a line of code written.

Honestly what you've described as your coding style doesn't sound poor at all. Write the code as it comes to you and make it work. Refactor once the code works and you start to see the possibility of a design.

over 1 year ago ·
10535

Thanks! I'm a big supporter of YAGNI as any of my pairs might begrudgingly admit. I guess though we'll just have to disagree on this particular point. When I encounter a private method I see it as an excellent candidate for improving the design. I also consider the other bad smells, like the size of methods, the number of methods, the amount of state, and the overall conceptual surface area of the the object. The difference is that private methods aren't explicitly called out, which is what I'd like to do here. I'd encourage you to reconsider when using private methods, asking instead where you'd put that behavior if you were required to make it public. Thanks for all this feedback.

over 1 year ago ·
10540

I would disagree. Private methods are a great way to separate API calls from business logic. Also private methods shouldn't be tested - they are used by the classes own public methods which are the ones that need to be tested. That way it's easy to refactor code without wrecking havoc, since private methods can change all the time. That's their purpose after all.

over 1 year ago ·
10548

@mrfoto try it the next time you create a private method. Imagine that you wanted to avoid making it private, where would it make the most sense being public? I find this to be a productive activity for finding holes in my design, in particular with objects that are extending themselves beyond their single responsibility. Private methods are indicative of lazy abstractions, if you did nothing but find more appropriate public homes for your private methods you would end up with tighter abstractions. This means taking into account all of the design principles and heuristics that are at your disposal. Let me know if you find this to be a fruitless activity after trying it. Thanks.

over 1 year ago ·
10583

This is an Interesting theory, but completely disregards breaking up a 10-line method into two (or more) smaller methods, which is something I do a lot. These smaller component methods make the public api methods more sensible (in that they call a handful of well-named private methods), which means that you can see easily what the intent of a public method is. Most of the time, all of that code could reasonably "fit" in the public method, but it is much harder to interpret.

As with many things, saying "never do this" or "always do that" is rarely the right approach (notice how even here, I say "rarely"). But if you're trying to incite readers, always be sure to include "always" or "never" in your posts.

over 1 year ago ·
10611

@toadjamb this doesn't "completely disregard breaking up a 10-line method into two (or more) smaller methods", I'm talking about those private methods too.

In regards to my saying "never do this" or "always do that" ... I never say anything like this directly in this post. However, I do think you should "always" second guess yourself when you're considering making some behavior private. In the same way I think you should "always" second guess yourself when you have too many methods, or too many properties, or you use single-character variables. If you feel it needs to be private in your object, it's most likely behavior that could be handled by objects from some other domain which offers that behavior publicly.

My goal isn't to incite readers. I find this to be a rewarding design technique. Describing the technique as a "bad smell" was deliberate. A lot of private behavior (or maybe even a little?) in my code base is a "symptom that possibly indicates a deeper problem". The deeper problem I think I keep finding when I encounter hidden behavior is lazily designed objects. By lazily designed objects I mean that the objects are doing just a little (sometimes a lot) more than their fair share. I say "lazily" because figuring out where the behavior makes the most sense being public is more work. Not that the programmer is lazy, but more work could've been done and it wasn't.

over 1 year ago ·
10612

Are there any circumstances in which you feel a private variable is appropriate, or do you avoid them as a rule in your coding practice?

over 1 year ago ·
10615

@viperxiv I certainly use them and generally think of state as "private". I think a good goal is to hide the state of the objects behind their behavior. Hopefully in the end you have some objects each with just a handful of state and all connected to one another through their public methods.

over 1 year ago ·