9

I have quite a few Helper classes in my project. I have read that this is a bad thing, but I suspect that "Helper" is the wrong suffix for them. I'll give an example.

First, I have a User class. I need a method GetSuggestedFriends() for a user. I want to keep the logic for determining the list of suggested friends out of the User class, so it doesn't get bloated. Right now, I have a FriendshipHelper which receives a User in its constructor. It contains the logic for getting suggested friends, and I can now call myUser.FriendshipHelper.GetSuggestedFriends().

Originally FriendshipHelper had static methods only, and a User object was passed into each one. If I was writing the class from scratch now, maybe I'd call it FriendshipManager - it also does things like adding and removing friends.

I've also read that ...Manager classes are bad, though. What should I call this class? Or, is this "bad code"? Where should the logic for getting suggested friends, current friends, and adding and removing friends live? Surely not all in a giant User class?

  • Where does this code live? Is it a service? Does it access a data store? It is the UI for doing this friend-y stuff? – Telastyn Jun 26 '15 at 13:24
  • 3
    Once you got rid of all the static methods and found a real home in your OOP design, these classes are really not helper classes, so feel free to rename. There's nothing wrong with a FriendshipManager if you need to manage friendships in your project. – JeffO Jun 26 '15 at 13:35
  • What's wrong with Facebook? – toniedzwiedz Jun 27 '15 at 11:06
  • Possible duplicate of Which is a better practice - helper methods as instance or static? – gnat Aug 29 '16 at 16:09
10

How to avoid …Helper or …Manager classes«

In general: by good Design

First, I have a User class. I need a method GetSuggestedFriends() for a user.

Yes. A user has a relationship to other users. And the relationship could be expressed as a method on user, e.g. user.isFriend(user2). This is the responsibility of the user-object. Besides that, you ask another object for help finding other friends. You delegate the responsibility for finding friends to another object and that's quite fine.

Right now, I have a FriendshipHelper which receives a User in its constructor. It contains the logic for getting suggested friends, and I can now call myUser.FriendshipHelper.GetSuggestedFriends()

That is not per se bad, but has one downside: initializing the "Helper" with one user limits the possibilities to that one user.

What you need is an object, which helps finding friends to any user. So a generic method would make sense: userMatcher.findFriendsFor(user) which in return delivers a collection of possible friends (user).

If I was writing the class from scratch now, maybe I'd call it FriendshipManager

Your problem is not writing "helper classes", it is finding the right names. ;)

it also does things like adding and removing friends.

That is a wrong design. Take yourself for example: Does your mommy add friends to your life or do you add them by yourself?

Of course the collection of friends is a property of user itself and so is the method user.addFriend(user) or user.removeFriend(user)

What should I call this class?

As said before: you only have a naming issue and your "helpers" are okay. But you have to think more carefully about the responsibilities of each object.

Where should the logic for getting suggested friends, current friends, and adding and removing friends live? Surely not all in a giant User class

No. These are two jobs for which you need one separate object, like in real life where you have people and a dating agency.

  • 2
    Great explanation, but you've clearly never met my mother. :'( – Matt May 8 '17 at 16:50
  • @HEATH3N I hope, that does not influence your software modeling capabilities. – Thomas Junk May 9 '17 at 10:15
3

I would suggest that you have a FriendshipService class that has a (non-static) GetSuggestedFriends(User) method. Avoid static methods since you cannot implement an interface which makes it more difficult to test. Avoid adding the user object to the constructor since you might want to extend your FriendshipService with methods not specifically related to a single user. (For example, you might want to suggest friends to a set of users, or suggest friends based on something else)

A user should most likely not be aware of the FriendshipService (due to the Single Responsibility Pattern)

  • 7
    Changing the suffix from "Helper" to "Service" doesn't make it any easier to get an idea of the class's responsibility by its name, which I think is the heart of the question. – Mike Partridge Jun 26 '15 at 14:38
  • Well, the name itself may not say that much, but I would say that using the suffix "Service" is a more standardized way of communicating that the class performs some sort of advanced logic. "Helper" classes are (at least to my experience) usually more related to very simple tasks, such as simple formatting and small static methods. I would expect that you could replace a "Service"-interface with different implementations. Futhermore, there are a lot of questions here, not only the naming. – Bjorn Jun 26 '15 at 14:45
  • Agreed. All three of "Helper", "Manager", and "Service" are ways that we group methods to avoid tons of super-specific classes with a single method, but "Service" has a little more meaning, as you described. I would add that it implies that the class is part of the service layer interface, helping to simplify access to the business logic (which may be made up of many more specific classes) for a given domain class. Whether the suggestion logic should be in a separate class from the add/remove logic depends on how complex the suggestion logic implementation is. – Mike Partridge Jun 26 '15 at 15:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.