I\'m currently writing a mailing interface for our enterprise application. Depen
ID: 645929 • Letter: I
Question
I'm currently writing a mailing interface for our enterprise application. Dependent on the send mode (regular email, bulk email, templates, mailmerge, ...) our Send() method requires a bunch of parameters.
Now we have got this Send() method that offers to take around 20 parameters, with nearly 10 overloads and default values.
Now of course you could use the C# 4.0 feature of named parameters like described here, but even that would be a mess when mostly 10 of 15 overloaded parameters have to be used.
Is there some better practice?
Explanation / Answer
It looks like your Send() method is doing too much and asking for too much information.
What happens when it has to deal with a template or mail merge? Is it really sending something? I don't think so, and so Send is a badly chosen name. But it's not the choice of the name which is bad here, but, again, the fact that Send() does too much: it sends e-mails, stores templates or does a mail merge and stores the results in a database (I suppose).
When you split the method into several smaller ones, your Send() one becomes smaller:
public void Send() // Actually sends regular e-mails or bulk e-mails.
public void StoreTemplate()
public void DoMailMerge()
Let's get back to Send(). If it still has too many arguments, you are possibly giving it configuration information. Instead, this information should either be loaded from a configuration file or be passed through properties to the instance of the object containing Send().
Instead of:
sender.Send(from, bulkTo, title, body, timeout, mailsPerSecond);
you should be doing:
sender.bulkMailsPerSecond = this.mailsPerSecond;
sender.Send(bulkTo, title, body);
given that:
from is now in the configuration, loaded directly by Sender when needed,
timeout becomes a property of Sender with a default value.
The next step is to reduce the size of Sender: you may end up noticing that the class is too large and doing too much. For example, you may end up exporting templating-related stuff in a separate class, or use inheritance in order to apply custom logic for regular e-mails and bulk e-mails:
public abstract class Sender
{
protected Address From { get { ... } }
protected TimeSpan Timeout { get { ... } set { ... } }
}
public class RegularEmailSender : Sender
{
public void Send(Address to, string title, string body) { ... }
}
public class BulkEmailSender : Sender
{
private int BulkMailsPerSecond { get { ... } set { ... } }
public void Send(IEnumerable<Address> bulkTo, string title, string body) { ... }
}
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.