Adam Levitt
Adam Levitt

Reputation: 10476

C# Helper Pattern vs Service Method

Let's say we have the following classes:

public class Ticket {
  public int Id { get; set; }
  public string Event { get; set; }
  ...
}

public class TicketService {
  public void acceptTicket(Ticket ticket) {
    ...
  }

  ...
}

My question is, where's the best place to add static helper methods (that require no state like the service class might) related to the ticket entity? (Keeping in mind this is one entity/service amongst many other entities/services in the entire system).

Right now I'm thinking of the following possibilities:

  1. Create a new class called TicketHelper in its own .cs file.
  2. Create a static Helper class directly on the Ticket class
  3. Create a static Helper class directly on the Service class
  4. Just add the methods directly onto the service class as any other service method
  5. ... a better solution than these?

For the sake of clarity, here's what I mean for #2 or #3.

public class TicketService {
  public void acceptTicket(Ticket ticket) {
    ...
  }

  ...

  public static class Helper {
    public static Dictionary<string, List<Ticket>> groupByName(List<Ticket> tickets) {
      // returns the map of name/tickets
    }
  }
}

The API might look as follows in this case:

Ticket ticket = new Ticket();
List<Ticket> tickets = new List<Tickets>();
TicketService service = new TicketService();
service.acceptTicket(ticket);

// leaving out the creation of a list of tickets...
var groups = TicketService.Helper.groupByName(tickets);

Upvotes: 5

Views: 8177

Answers (4)

Ian Kirkpatrick
Ian Kirkpatrick

Reputation: 1960

I wouldn't call it a helper method. It's an aggregation method. So I would make a class called TicketAggregator with this method on it. Then, when you have others like "GetAverageTicketPrice", you can put that in the TicketAggregator too.

By naming it TicketAggregator, you are describing it's content more clearly. Someone immmediately knows what methods are in that class just by the name of it. Besides, the word helper really doesn't mean anything... aren't all methods there to help you?

Upvotes: 0

Olivier Jacot-Descombes
Olivier Jacot-Descombes

Reputation: 112512

Yet another possibility is to use the singleton pattern.

It has the advantages of:

  • being able to implement an interface
  • providing an object that you could pass to a method or constructor in a dependency injection scenario
  • providing a static behavior
public interface ITicketHelper
{
    void HelpThis(Ticket t);
    IList<Ticket> HelpThat();
}

public class TicketHelper : ITicketHelper
{
    public static readonly TicketHelper Instance = new TicketHelper();

    private TicketHelper()
    { ... }

    public void HelpThis(Ticket t)
    { ... }

    public IList<Ticket> HelpThat()
    { ... }
}

Usage

 var result = TicketHelper.Instance.HelpThat();

Upvotes: 2

Jord&#227;o
Jord&#227;o

Reputation: 56487

You could use extension methods for this. Create them in a separate TicketExtensions class.

public static class TicketExtensions {
  public static Dictionary<string, List<Ticket>> groupByName(this List<Ticket> tickets) {
    // returns the map of name/tickets
  }
}

...

var ticket = new Ticket();
var tickets = new List<Tickets>();
var service = new TicketService();
service.acceptTicket(ticket);

// leaving out the creation of a list of tickets...
var groups = tickets.groupByName();

Also, using interfaces like IEnumerable<T>, IList<T> or IDictionary<K, V> is preferable than the concrete collection classes.

Upvotes: 3

Morten Mertner
Morten Mertner

Reputation: 9474

I suppose the answer depends on who you expect to be calling the method.

Personally, I would put the static method on the TicketService class, as it works on more than a single entity, and make it private to the service itself.

Then I would create an instance method on the service to expose the functionality to any consumers of the service. It sort of makes the API cleaner and avoids people having to know the implementation detail of whether something is a static method or not.

Upvotes: 1

Related Questions