This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
Private methods can be very useful things. You won't be programming for long before you find yourself having to write a rather hefty chunk of code to do something in particular. For example, let's say you're writing some banking software.
For this software, you need to provide a public method called withdrawAmount(). The requirements for this method are as follows:
(1) Verify the user is authorized to withdraw funds from the account (2) Verify that sufficient funds exist in the account (3) If (1) and (2), withdraw funds appropriately.
How might we write this?
Yeah, so that works (forgive me if I've got compiler errors, I wrote this on the fly), but it's getting confusing and is hard to read. If we had to add more to this code, it would be difficult and time consuming. Additionally, if some other method, let's say transferFunds(), had to perform similar operations as verifying sufficient funds exist, that logic would have to be rewritten in that method. Using private methods, we can kill two birds with one stone and fix both problems. Let's rewrite what I had above using private methods:
Isn't that a lot easier to read? At this point, each method does something very specific, rather than having one method that tries to do a lot. This helps make code more readable as well as more maintainable, modifiable, and reuasable.
Now, if we had to make another method called transferFunds(), we wouldn't have to rewrite the logic to verify that the account had sufficient funds, we could just invoke the method hasSufficientFunds() and let it do the legwork for us.
So why make these methods private? Well, the idea here is that our Teller class will do things like withdraw funds, deposit funds, transfer funds, etc. Who would use such a class? Probably a Customer. It doesn't make any sense for a Customer to verify that he/she has access to an account - that's the Teller's job. So, we don't make that method public - we don't allow a Customer to do that. We keep it internal to the Teller by making it private but, by making it a separate method, we gain all the previous benefits.
I hope that helps. Private methods are essential things.
I've heard the argument made by a very smart friend of mine that private methods are generally indicative of bad design, excepting private constructors. At first, I thought he might be a little crazy, but as he went on to explain himself I have to say he made a good deal of sense.
Now, even he acknowledges that perhaps "bad" design is too strong--it might be a very good design overall that includes private methods. His purpose wasn't to denigrate the overall design or designer, but simply to point out that it could probably be made better. Typically, private methods are not used as in the example given in the last post. Using private methods simply for code organization might help out in some cases, but I've usually seen them used in situations where a class needs to run the same sequence of instructions over and over again from different places. Rather than rewrite that sequence again and again in each method, stick it in a private method and call it.
This is pure procedural oriented programming (POP). I want to patch in this sequence of steps here, here, and there, so I'll create a private method and call it from here, here, and there. Also, if the sequence has to change in one place, I'd have to go and change it in all three, so much better to have it in a private method. All of this is 100% procedural thinking.
Is there a better OO alternative? What if, instead of simply viewing that method as a sequence of steps that needs to be patched into various places, we look at it instead as a behavior of an object? The advantages here are well-known and well-understood...indeed, any argument you can make in favor of OOP vs. POP can be applied here. The broad strokes of the argument are as follows: if you are using that functionality from several places in your object, then that sequence of instructions has some kind of independence from any one particular context. It is a behavior that has sort of separated itself from the outside world in this way. Doesn't that sound a lot like an object, though?
Now in every project there's a trade-off between doing something the "pure OO" way and compromising the OO-ness of your app so that you can: 1) reduce complexity, 2) meet a deadline, or myriad other reasons. And that's fine, as long as you recognize the trade-off and comprehend what you're losing and what you're gaining, no one has any problems with that. But this way of looking at things started me questioning: what am I losing when I choose a private method over creating a separate class?
Joined: Dec 20, 2001
Originally posted by sever oon: I've heard the argument made by a very smart friend of mine that private methods are generally indicative of bad design, excepting private constructors...
A lot of this argument makes sense. The private methods I laid out could have been turned into public methods of the Account class and achieved, basically, the same effect.
However, it isn't always the case that you have access to write/rewrite all classes that you are using. If, for example, the Account class was being provided to you by some third party that isn't going to change their code, you'd be left with 2 options. First, you could follow this argument and create yet another class. In my opinion, that option would probably just added unnecessary complexity to the application. Secondly, you could create private methods as I showed earlier.
Like I said, that argument does make sense and I'm not saying that private methods are better than creating another class, but I'd have a hard time doing away with them altogether. I think it's something that's important to keep in mind while doing design work so that, depending upon the situation, you can easily go either way.
The private method in the example is a primitive used in multiple places in other methods. Making the method private ensures that everyone uses the same version of the method and that only methods within that class and its subclasses can call the method. As long as the data passing is solely though the parameters and return value, I don't see how OOP is broken.
I wouldn't create a new class that has behavior but no state. That's not really an object.
Off topic, I was surprised to see exceptions used for something as routine as insufficient funds. Isn't that a bit inefficient?
SCJP 1.4, SCWCD in process
Joined: Dec 20, 2001
Originally posted by Mike Gershman: Off topic, I was surprised to see exceptions used for something as routine as insufficient funds. Isn't that a bit inefficient?
Yes, probably. But the idea was that my example was taken from some "much larger" application. For the example I used, there was no need to use exceptions but, in a larger system, it may have been more important. Certainly, for my example, I could have simply returned true or false to dictate whether or not sufficient funds existed.
Originally posted by Mike Gershman: The private method in the example is a primitive used in multiple places in other methods. Making the method private ensures that everyone uses the same version of the method and that only methods within that class and its subclasses can call the method.
The statement that I boldfaced in the quote above is not correct. Private methods can only be called by other methods in the same class. Private methods can't be called by the subclasses. You will have to change the method signature from private to protected if you want the subclasses to be able to call the parent class's private methods.
[ July 30, 2004: Message edited by: Sadanand Murthy ] [ July 30, 2004: Message edited by: Sadanand Murthy ]
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus