Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are helperclasses anti pattern

A recent question here made me rethink this whole helper classes are anti pattern thing.

asawyer pointed out a few links in the comments to that question: Helper classes is an anti-pattern.

While those links go into detail how helperclasses collide with the well known principles of oop some things are still unclear to me.

For example "Do not repeat yourself". How can you acchieve this without creating some sort of helper? I thought you could derive a certain type and provide some features for it. But I bellieve that isnt practical all the time.

Lets take a look at the following example, please keep in mind I tried not to use any higher language features nor "languagespecific" stuff. So this might been ugly nested and not optimal...

//Check if the string is full of whitepsaces
bool allWhiteSpace = true;

if(input == null || input.Length == 0)
    allWhiteSpace  = false;
else 
{
    foreach(char c in input)
    {
        if( c != ' ')
        {
            allWhiteSpace = false;
            break;
        }
    }
}

Lets create a bad helper class called StringHelper, the code becomes shorter:

bool isAllWhiteSpace = StringHelper.IsAllWhiteSpace(input);

So since this isnt the only time we need to check this, i guess "Do not repeat yourself" is fullfilled here.

How do we acchieve this without a helper ? Considering that this piece of Code isn't bound to a single class?

Do we need to inherit string and call it BetterString ?

bool allWhiteSpace = better.IsAllWhiteSpace;

or do we create a class? StringChecker

StringChecker checker = new StringChecker();

bool allWhiteSpace = checker.IsAllwhiteSpace(input);

So how do we acchieve this?

Some languages (e.g. C#) allow the use of ExtensionMethods. Do they count as helperclasses aswell? I tend to prefer those over helperclasses.

like image 922
CSharpie Avatar asked Feb 26 '14 18:02

CSharpie


People also ask

Are helper classes anti-pattern?

asawyer pointed out a few links in the comments to that question: Helper classes is an anti-pattern. While those links go into detail how helperclasses collide with the well known principles of oop some things are still unclear to me. For example "Do not repeat yourself".

Are helper classes evil?

Utility classes (or helper classes), “structures” that have only static methods, which as design is very popular in Java world (as well as in C#, Ruby, Python worlds) as they can provide usual functionalities that are used everywhere in a simple manner.

What is the purpose of Helper class?

In object-oriented programming, a helper class is used to assist in providing some functionality, which isn't the main goal of the application or class in which it is used. An instance of a helper class is called a helper object (for example, in the delegation pattern).

Is a Helper class a code smell?

A Helper class is a lesser known code smell where a coder has identified some miscellaneous, commonly used operations and attempted to make them reusable by lumping them together in an unnatural grouping.


1 Answers

Helper classes may be bad (there are always exceptions) because a well-designed OO system will have clearly understood responsibilities for each class. For example, a List is responsible for managing an ordered list of items. Some people new to OOD who discover that a class has methods to do stuff with its data sometimes ask "why doesn't List have a dispayOnGUI method (or similar such thing)?". The answer is that it is not the responsibility of List to be concerned with the GUI.

If you call a class a "Helper" it really doesn't say anything about what that class is supposed to do.

A typical scenario is that there will be some class and someone decides it is getting too big and carves it up into two smaller classes, one of which is a helper. It often isn't really clear what methods should go in the helper and what methods should stay in the original class: the responsibility of the helper is not defined.

It is hard to explain unless you are experienced with OOD, but let me show by an analogy. By the way, I find this analogy extremely powerful:

Imagine you have a large team in which there are members with different job designations: e.g, front-end developers, back-end developers, testers, analysts, project managers, support engineers, integration specialists, etc. (as you like).

Each role you can think of as a class: it has certain responsibilities and the people fulfilling those responsibilities hopefully have the necessary knowledge to execute them. These roles will interact in a similar way to classes interacting.

Now imagine it is discovered that the back-end developers find their job too complicated. You can hire more if it is simply a throughput problem, but perhaps the problem is that the task requires too much knowledge across too many domains. It is decided to split up the back-end developer role by creating a new role, and maybe hire new people to fill it.

How helpful would it be if that new job description was "Back-end developer helper"? Not very ... the applicants are likely to be given a haphazard set of tasks, they may get confused about what they are supposed to do, their co-workers may not understand what they are supposed to do.

More seriously, the knowledge of the helpers may have to be exactly the same as the original developers as we haven't really narrowed down the actual responsibilities.

So "Helper" isn't really saying anything in terms of defining what the responsibilities of the new role are. Instead, it would be better to split-off, for example, the database part of the role, so "Back-end developer" is split into "Back-end developer" and "Database layer developer".

Calling a class a helper has the same problem and the solution is the same solution. You should think more about what the responsibilities of the new class should be. Ideally, it should not just shave-off some methods, but should also take some data with it that it is responsible for managing and thereby create a solution that is genuinely simpler to understand piece by piece than the original large class, rather than simply placing the same complicated logic in two different places.

I have found in some cases that a helper class is well designed, but all it lacks is a good name. In this case, calling it "Builder" or "Formatter" or "Context" instead of "Helper" immediately makes the solution far easier to understand.

like image 170
rghome Avatar answered Oct 10 '22 06:10

rghome