Reputation: 10476
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:
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
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
Reputation: 112512
Yet another possibility is to use the singleton pattern.
It has the advantages of:
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
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
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