views:

776

answers:

13

A friend of mine has just posited that protected methods (yes, methods) constitute a code smell. That is, they're indicative of potential bad programming practice.

My gut says he's wrong, but I'm struggling to come up with a good example of where they're a good, legitimate solution. For example, I might be tempted to put the protected method in a separate utility class that both base and derived classes could use as required. But that might not cover situations in which the method wants/needs access to data members and/or private methods of that object instance.

What's your take on it?

Can you provide good examples of why protected methods aren't necessarily a bad thing?

Or am I just wrong? :)

BTW, I'll not be marking any answer as accepted on this one, as someone has (correctly) tagged this question as subjective. Just so as you know. :)

+5  A: 

Protected methods are absolutely not a "bad programming practice" in my opinion.

They, like every other feature in OOP just about, can be abused and misused. However, they serve a specific, valuable purpose. They allow you to relax your contraints on usage in a very specific case - classes that are subclasses of you have selective access to routines you allow, but still potentially hide from the rest of the world. This provides many benefits - including reducing code duplication and improving maintainability (by allowing non-public code to be consolidated into base classes).

Also, many patterns require protected methods in order to function correctly. For example, the Disposable pattern in C#/.NET is based around using protected virual methods to handle resource cleanup correctly.

Reed Copsey
Yep, I totally get the protected virtual side of things. I was thinking more of non-virtual protected methods, but completely failed to mention that. Sorry.
Mal Ross
The same benefits often apply, though - non-virtual methods allow consolidation of code, but still restrict it to a similar scope of classes. Without this, you have huge amounts of code duplication, or everything is public.
Reed Copsey
+1, especially for the comment about being able to abuse anything. Blanket assertions make baby Jesus cry.
Rob
+14  A: 

Lack of proper scoping is bad. Protected provides a valuable means to say "public within the scope of this group of classes". Without it, you are stuck making everything public, or making them private after clumping things together in classes where they don't belong.

I actually look at lack of protected (or variation for [insert language here]) as being the bad code smell.

joseph.ferris
A: 

IMHO, if someone is giving unqualified statements about something being "bad", it is because they themselves do not understand it properly. Often, they are just parroting (probably, also with somewhat distorted meaning) what they've heard from somebody else; here I'm alluding to the case of the "evil" goto.

How to proceed: ask him to justify his statement, also giving you references to the sources from which he learned this. Provided that you thoroughly understand the issue, his own misunderstanding will give you enough material to pursue this topic.

Also note that some people cannot be moved by rational arguments; they just keep on sticking to their opinion insisting that it's the only valid view of the world. If you figure that he's that kind of person -- stay away from him as much as possible.

zvrba
A: 

I definitely disagree - if you're doing things correctly, in fact, and creating classes with methods that do only one thing, you're going to have more protected methods and not less - its more likely that when you derive the class you'll need to have the derivative call one of the protected methods.

That said - the decision to make a method protected is one that should at least be thought of. One question that should be asked is how that method affects the internal, private state of the class - if its affecting things that no derivative should know about, it should be private.

John Christensen
+2  A: 

Are you sure he's not confusing protected member variables with protected methods? Protected methods are extremely necessary for many situations. Protected member variables, on the other hand, often leak details about the implementation of your class into the derived classes, thus making it difficult to change their type in the superclass (because it will break the derived classes). Generally, member variables should be private unless there is a compelling reason to make them public. Protected methods often provide the needed abstraction for manipulating the private members from a subclass.

rmeador
Positive. His initial question was whether protected was itself a code smell? I asked about members vs methods and he suggested that most protected methods smell just as much as members. Mind, he was just suggesting this; suspect he's trying to work it through himself.
Mal Ross
I'd argue that protected members are less of a code smell than protected methods. That is, provided that said protected member is an object wrapping data rather than the data itself.
Jason Baker
+5  A: 

If I had to choose position, I'd agree with your colleague.

I will personally prefer composition to inheritance in about 90% of the cases, but it all depends a little on which programming language you're using. In a rich language like C# I'd practically not be using inheritance at all - henceforth also quite few (if any) protected methods.

In a more primitive language like Java, there are so few sensible options to re-use that you basically have to use any means available to you. So inheritance is overused in java to create re-use.

If you're working for microsoft or sun and are making the api for "SQL" or the windows controls, template method may be appropriate. For the rest of us, the Template Method pattern borders on being an anti-pattern in my opinion.

  • A lot of times it uses up your inheritance hierarchy for "the wrong reasons".
  • Dependencies between subclasses and base classes tend to become littered
  • Base classes have a tendency to become littered with all sorts of unrelated code.
  • It forces you to lock down design, often quite early in the development process. (Premature lock down in a lot of cases)
  • Changing this at a later stage becomes just harder and harder.

So while by no means being religious, I tend to have very few protected methods in my code. Protected is the smell of coupling

krosenvold
Excellent answer. I was hoping someone would stand up for him at some point. Like you, I also tend to use very few protected methods in C#, but I wasn't ready to consign them to the code-smell bin (examples like Phill's probably being my primary use).
Mal Ross
I especially like your last sentence. +1
Randolpho
+8  A: 

There are plenty of reasons why one may wish to use protected methods. One of the reasons you see all the time in the .NET framework is to allow inherited classes to fire events on the base class:

public class Foo
{
public event EventHandler FooBar;

protected void DoFooBar()
{
if (FooBar != null)
FooBar(this, EventArgs.Empty);
}
}
}

public class Bar : Foo
{
public void SomethingHappensCausingAFooBar()
{
DoFooBar();
}
}

This allows a class to define which of its events a subclass, and only a subclass, may call. There's also the whole area of factory methods where you have protected abstract methods which are overridden in a subclass to add the implementation for the subclass.

Another example would be a builder class where one step of the construction may be overridden and changed in a subclass.

There are plenty of more examples than these, a good place to start would be with a decent patterns book, you'll see plently of patterns which are implemented using protected methods.

Phill
Great example with the event-firing, there. :)
Mal Ross
+5  A: 

From John Lakos' Large-Scale C++ Software Design.

"What are protected members good for?... when you want to distinguish two distinct audiences: derived-class authors and general users....

"The next question is then, 'When would someone want to address two distinct audiences from within a single class?' More often than not, the answer is, 'When someone is trying to do too much with a single class.'"

S.Lott
That sounds great, in theory. But I can think of many examples, such as the ones Phill gave, where protected methods are a sign that you want the class to be simple to use while still leaving room for inheritance.
Steven Sudit
@Steven Sudit: All the examples of "protected" methods can (and should) be switched to Delegation using some kind of Facade or Strategy pattern between two cooperating objects. One is the public "interface", the other is the protected "implementation". Separate classes works out a lot better.
S.Lott
@S.Lott: No doubt that, in some cases, that's the right way to go. But in simpler cases, it's a lot of complexity being used to try to lower complexity, which becomes self-defeating.
Steven Sudit
@Steven Sudit: The complexity was there all the time. It's splitting two complex things away from each other, so each can evolve independently. In the long run, it's simpler to decompose.
S.Lott
+1  A: 

Using them in and of itself isn't bad. However, I find myself using them less and less the more I program. A few reasons why I use (or am tempted to use) protected methods are:

  1. To make a simpler API for any client code.
  2. Because the code is dangerous if used improperly.
  3. Because the code is dangerous if used outside the class or any of its subclasses.
  4. Because the code is doing too much.

I'll avoid making any arguments as to whether protected methods are a good idea or not. But based on the above reasons, the amount of times that you need protected methods isn't all that great. In my opinion, they're more frequently a crutch than they are a help.

After all, all you have to do is inherit from the class to gain access to it. In most modern languages you don't even have to do that (using reflection).

Also consider how much benefit you're getting from them. Honestly, how many times have you accidentally called a method that isn't supposed to be called outside its class? And if you're going to allow the method to be called by anyone and everyone who wants to inherit from your class, why can't you just make it public? If you want to control who can access a method, why not just leave it out of the interface? You are exposing an interface rather than giving direct access to the subclass, right?

I'm not trying to side with your friend or make any kind of case against protected methods. They have uses. But ultimately, you should think about whether you have a valid reason to make a method protected or whether you're creating them because that's what was drilled in your head in your object-oriented programming course. For me, it's usually the latter.

Jason Baker
A: 

I was initially going to say that I don't like when developers declare methods private as it needlessly places limits on anyone who would like to use their class. Most developers would rather write their own class than attempt to use a class that is hard to use and/or adapt to their needs. Which is what you would think a private method would do. But then I realized that it is really sealed classes that are more likely to cause this problem.

Anyways, I gave it some thought and I'm having a hard time thinking of good uses for protected methods (other than for something like the template pattern). So I looked at code from some old projects and I don't see many. Generally, if I create a non-public method it is because I'm simplifying a public method by creating helper methods. I certainly don't want anyone to be able to change the helper method as that will almost certainly break my public method.

I'd be interested in knowing if there was a specific example that brought this topic up that we could analyze. Or maybe someone has a good example (that is not the template pattern) of a good use of protected methods.

Dunk
No specific example that I'm aware of, I'm afraid.
Mal Ross
OK, why the negative votes? No big deal, but it is nice to know where my thinking needs to be re-examined.
Dunk
+1  A: 

I agree with your "friend", and with krosenvold.

Recently I've noticed that a significant amount of the friction I encounter when refactoring can be attributed broadly to inheritance of state and/or behaviour. I don't avoid such things religiously, and in fact implementation inheritance is very often the quickest way to get to a green bar. But I believe it comes with a cost, so I like to get rid of it as soon as I see it.

Protected methods are one symptom, a hint that the superclass has too many responsibilities and the subclasses are likely to be coupled to its internal design, rather than to its external interface/type.

(For the record, whenever I see any method that's less than public I ask myself whether it indicates a need to split the class. The answer is "yes" just enough of the time, and there's no harm in asking the question, imo.)

kevinrutherford
A: 

Making a method protected is a technique described in Working Effectively with Legacy Code by Michael C. Feathers to allow a method to be tested by deriving a test class and calling the method from it.

David Sykes
Well...somehow that technique just *feels* dirty to me, but at least you have been the only person so far to come up with a valid use of protected methods (other than template pattern).
Dunk
A: 

Is the use of protected methods a bad thing?

No, have a look at the Open-Closed principle. Right scoping is significant for a good design! Have a look at DomainDrivenDesign! With interfaces/views to your object, you prevent attributes from beeing modified without the control of the object. (except the use of reflection etc.)

It's part of a good OO Design.

Martin K.
What does the open-closed principle have to do with protected methods? public-virtual methods can be used to accomplish the open-closed principle. Other than template-method pattern, what would be a good example of right scoping for a protected (not public/private) method?
Dunk