I have some code which updates a list of people to email. This list is updated often, with people being added and removed before the actual "send email" portion of the code is called. Currently my code to take care of this is something like this:
if (instructorEmailType == InstructorEmailType.AddToCourse)
{
// If instructor not already in the list, then put them in.
if (!this.InstructorsToEmail.ContainsKey(courseInstructor))
{
this.InstructorsToEmail.Add(courseInstructor, InstructorEmailType.AddToCourse);
}
else
{
// If instructor already in the list, and marked for removal, then get rid
// of that entry from the list.
if (this.InstructorsToEmail[courseInstructor] == InstructorEmailType.RemoveFromCourse)
{
this.InstructorsToEmail.Remove(courseInstructor);
}
}
}
else
{
if (this.InstructorsToEmail.ContainsKey(courseInstructor))
{
this.InstructorsToEmail.Remove(courseInstructor);
}
else
{
this.InstructorsToEmail.Add(courseInstructor, InstructorEmailType.RemoveFromCourse);
}
}
It's complicated and I don't like it. I've been thinking about implementing the Command
design pattern instead. My idea what to create two commands:
When an instructor is allocated to a course, then I would new-up a SendAllocatedInstructorEmailCommand
and add it to CommandInvoker.SetCommand
for later use. Likewise, I would create a SendDeallocatedInstructorEmailCommand
object for those instructors who are taken off a course.
That is the problem.
If I've created a SendAllocatedInstructorEmailCommand
object for Instructor A
and later down the line Instructor A
is deallocated from the course (before any data on the page has been saved, or emails sent), then I need to delete the SendAllocatedInstructorEmailCommand
that I built earlier.
What is a clean way of searching for commands that already reference Instructor A
, so that I can delete them? I can't use an Undo
method on my commands since the emails will have been sent already via the SendAllocatedInstructorEmailCommand
.
I was thinking of adding some kind of Query
method to my CommandInvoker
object, but I'm not sure if that is a poor plan.
Should I be using the Command
design pattern at all? It does come across as a really nice way to queue these emails.
Cheers. Jas.
I'd say you should keep your commands, just decouple them from sending any emails.
Your commands should be like IncludeInstructorEmail
and ExcludeInstructorEmail
, they should both implement one interface, like this
public interface ICommandOverEmailsList
{
void ApplyToList(List<string> emailsList);
}
then the code in the main part would be like this:
List<string> emailsList = new List<string>();
foreach(var command in instructorEmailsCommandsQueue)
{
command.ApplyToList(emailsList);
}
SendEmails(emailsList);
Of course, this assumes that the sequence of commands like "Exclude X, Include X" will leave the address X in the list. This seems to be different from your original code logic, but is it really required?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With