关于使用命令设计模式的思考

时间:2010-10-25 15:26:41

标签: design-patterns command

我有一些代码可以更新电子邮件的人员列表。此列表经常更新,在调用代码的实际“发送电子邮件”部分之前添加和删除人员。目前我的代码是这样的:

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);
    }
}

这很复杂,我不喜欢它。我一直在考虑实现Command设计模式。我的想法是创建两个命令:

  • SendAllocatedInstructorEmailCommand
  • SendDeallocatedInstructorEmailCommand

当教师被分配到课程时,我会新建一个SendAllocatedInstructorEmailCommand并将其添加到CommandInvoker.SetCommand以供日后使用。同样,我会为那些退出课程的教师创建一个SendDeallocatedInstructorEmailCommand对象。

这就是问题所在。

如果我为SendAllocatedInstructorEmailCommand创建了一个Instructor A对象,稍后会从课程中取消分配Instructor A(在保存页面上的任何数据或发送电子邮件之前) ),然后我需要删除我之前构建的SendAllocatedInstructorEmailCommand

什么是搜索已引用Instructor A的命令的简洁方法,以便我可以删除它们?我无法在命令中使用Undo方法,因为电子邮件已经通过SendAllocatedInstructorEmailCommand发送。

我在考虑向我的Query对象添加某种CommandInvoker方法,但我不确定这是不是一个糟糕的计划。

我应该使用Command设计模式吗?它确实是一种排队这些电子邮件的好方法。

干杯。 雅各

1 个答案:

答案 0 :(得分:1)

我会说你应该保留你的命令,只是将它们与发送任何电子邮件分开。

您的命令应该像IncludeInstructorEmailExcludeInstructorEmail,它们都应该实现一个接口,就像这样

public interface ICommandOverEmailsList
{
    void ApplyToList(List<string> emailsList);
}

然后主要部分中的代码将是这样的:

List<string> emailsList = new List<string>();
foreach(var command in instructorEmailsCommandsQueue)
{
   command.ApplyToList(emailsList);
}
SendEmails(emailsList);

当然,这假设像“Exclude X,Include X”这样的命令序列会将地址X留在列表中。这似乎与原始代码逻辑不同,但是它真的需要吗?