重构开关案例

时间:2013-12-29 06:15:20

标签: c# c#-4.0 design-patterns refactoring

请考虑这个psudo代码:

switch (ddlPlan.SelectedValue)
{
    #region 02
       case "2":
           BL_02 bl_02 = new BL_02();
           bl_02.DeleteQues(Id, Version);
           break;
    #endregion

    #region 0503
       case "3":
           BL_03 bl_03 = new BL_03();
           bl_03.DeleteQues(Id, Version);
           break;
    #endregion

    #region 0505
       case "5":
           BL_05 bl_05 = new BL_05();
           bl_05.DeleteQues(Id, Version);
           break;
    #endregion
}

如何重构此代码以删除此切换案例?

我的大部分问题是如何以适当的方式获取BLs的实例。

感谢

2 个答案:

答案 0 :(得分:3)

假设每个类都是BL_Parent的子类,您可以使用反射从字符串值动态实例化该类。

var className = String.format("BL_{0,2}", ddlPlan.SelectedValue);

var blObj = (BL_Parent)Activator.CreateInstance(null, className);

blObj.DeleteQues(Id, Version);

如果您只想要一组特定的数字,您可以将其列为白色。

var whitelist = new string[] { "2", "3", "5" };

if (!whitelist.Contains(ddlPlan.SelectedValue))
    // handle exception

您可以找到有关Activator.CreateInstance() here 的更多信息。

另外,我建议你重新考虑你的类结构,因为从命名约定来看,有更好的方法来处理这样的数据。

答案 1 :(得分:3)

这样的事情怎么样?

把它放在某处,然后让你的BL类实现它:

public interface IBL
{
    void DeleteQues(string id, string version); // Assuming these are strings
}

然后重写你的switch语句:

IBL bl;
switch (ddlPlan.SelectedValue)
{
    case "2": bl = new BL_02(); break;
    case "3": bl = new BL_03(); break;
    case "5": bl = new BL_05(); break;
}

bl.DeleteQues(Id, Version);

或者,您可以创建Dictionary<string, Type>而不是使用开关:

Dictionary<string, Type> blTypes = new Dictionary<string, Type>
    {
       { "2", typeof(BL_02) },
       { "3", typeof(BL_03) },
       { "5", typeof(BL_05) }
    }

然后您只需执行以下操作而不是使用开关:

IBL bl = (IBL)Activator.CreateInstance(blTypes[ddlPlan.SelectedValue]);  // Could check if key exists
bl.DeleteQues(Id, Version);

或者,如果你真的想要花哨并使其可扩展,你可以使用反射来生成你想要实例化的类的名称。