基于数据库记录或枚举值的可扩展设计模式

时间:2013-05-16 11:41:29

标签: c# design-patterns switch-statement

我正在开发一个需要非常可扩展的项目。它是基于字符串代码或枚举值执行操作。我现在使用switch-case语句并手动调用方法。

我想要做的是遍历数据库记录(并最终获取枚举值或字符串代码),调用方法“PerformAction”并使之后可以实现类或方法。

    public bool PerformAction(ActionToPerform actionToPerform)
    {
        bool isPerformed = false;

        switch (actionToPerform.Action.Code)
        {
            case "MAIL":
                isPerformed = Actions.SendEmail(actionToPerform);
                break;
            case "RESTART":
                isPerformed = Actions.RestartSendport();
                break;
            case "EVENT-LOG":
                isPerformed = Actions.AddToEventLog();
                break;
        }
        //Do some more
        return isPerformed;
}

我希望以后能够实现SendEmail,RestartSendport和AddToEventLog等操作。我知道这可以以某种方式使用反射并给方法命名CODE(例如“MAIL.cs”),这样我就可以避免使用switch case并执行一次调用。

我需要这个非常动态并且在另一个库中,所以我想知道这种问题是否有最佳实践或良好的设计模式。

2 个答案:

答案 0 :(得分:4)

您可以从创建字典开始:

private Dictionary<ActionType, ActionBase> actions;

所以代替switch (currentActionType)你可以做这样的事情:

if (actions.ContainsKey(currentActionType))
    actions[currentActionType].Run(someArgs);

这样,您可以将操作映射与操作调用分开。映射可以在构造函数中完成:

actions[ActionType.SendEmail] = new SendEmailAction();
actions[ActionType.OtherAction] = new OtherAction();

在此之后,您可以将操作字典提取到单独的ActionsRepository并将其作为依赖项注入。存储库可以有一个方法RegisterAction(ActionType type, ActionBase action),用于在运行时创建映射。

答案 1 :(得分:0)

如果您可以设法统一您的动作调用模式,您可以向基础Action类添加一些ID字段并以这种方式调用它:

public bool PerformAction(ActionToPerform actionToPerform)
{
    bool isPerformed = false;
    var foundAction = Actions.SingleOrDefault(a => a.Code == actionToPerform.Action.Code);
    if (foundAction != null)
    {
        isPerformed = foundAction.Invoke();
    }

    //Do some more
    return isPerformed;
}