首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >重构控制器中的Switch语句

重构控制器中的Switch语句
EN

Stack Overflow用户
提问于 2011-07-19 23:41:42
回答 2查看 2.1K关注 0票数 4

我目前正在开发一个MVC.NET 3应用程序;我最近参加了“鲍勃叔叔”马丁的一个课程,它启发了我(让我感到羞愧?)认真审视我目前的开发实践,特别是我的重构习惯。

所以:我的一些路线符合:

{控制器}/{操作}/{类型}

其中类型通常确定要返回的ActionResult的类型,例如:

代码语言:javascript
复制
public class ExportController
{
    public ActionResult Generate(String type, String parameters)
    {
        switch (type)
        {
            case "csv":
            //do something
            case "html":
            //do something else
            case "json":
            //do yet another thing
        }    
    }
}

有没有人成功地将“用多态替换开关”重构应用到这样的代码中?这是个好主意吗?很高兴听到你在这种重构方面的经验。

提前感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-07-19 23:51:45

如果您想在这种情况下“用多态性替换开关”,您可以创建三个重载的Generate() ActionResult方法。使用custom model binding,使类型参数成为名为DataFormat (或其他名称)的强类型枚举。然后你就会有:

代码语言:javascript
复制
 public ActionResult Generate(DataFormat.CSV, String parameters)
    {
    }

 public ActionResult Generate(DataFormat.HTML, String parameters)
    {
    }

 public ActionResult Generate(DataFormat.JSON, String parameters)
    {
    }

一旦你达到了这一点,你就可以进一步重构,将重复从你的控制器中提取出来。

票数 3
EN

Stack Overflow用户

发布于 2011-07-19 23:55:27

在我看来,这个控制器操作需要一个自定义的操作结果:

代码语言:javascript
复制
public class MyActionResult : ActionResult
{
    public object Model { get; private set; }

    public MyActionResult(object model)
    {
        if (model == null)
        {
            throw new ArgumentNullException("Haven't you heard of view models???");
        }
        Model = model;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        // TODO: You could also use the context.HttpContext.Request.ContentType
        // instead of this type route parameter
        var typeValue = context.Controller.ValueProvider.GetValue("type");
        var type = typeValue != null ? typeValue.AttemptedValue : null;
        if (type == null)
        {
            throw new ArgumentNullException("Please specify a type");
        }

        var response = context.HttpContext.Response;
        if (string.Equals("json", type, StringComparison.OrdinalIgnoreCase))
        {
            var serializer = new JavaScriptSerializer();
            response.ContentType = "text/json";
            response.Write(serializer.Serialize(Model));
        }
        else if (string.Equals("xml", type, StringComparison.OrdinalIgnoreCase))
        {
            var serializer = new XmlSerializer(Model.GetType());
            response.ContentType = "text/xml";
            serializer.Serialize(response.Output, Model);
        }
        else if (string.Equals("csv", type, StringComparison.OrdinalIgnoreCase))
        {
            // TODO:
        }
        else
        {
            throw new NotImplementedException(
                string.Format(
                    "Sorry but \"{0}\" is not a supported. Try again later", 
                    type
                )
            );
        }
    }
}

然后:

代码语言:javascript
复制
public ActionResult Generate(string parameters)
{
    MyViewModel model = _repository.GetMeTheModel(parameters);
    return new MyActionResult(model);
}

控制器不应该关心如何序列化数据。这不是他的责任。控制器不应该像这样做任何管道工作。他应该专注于获取领域模型,将它们映射到视图模型,并传递这些视图模型来查看结果。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6749999

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档