2

我已经为一个不太可用的呼叫中心应用程序构建了一个简单的基于 MVC3 的工单入口站点,并且正在尝试重构我的原型以更好地遵循设计模式,部分是为了使其更易于维护,但主要是作为一种学习练习。面向用户的视图是一种由基本用户信息和一些允许选择各种资源类型的面板组成的表单。每种资源类型(硬件、软件等)都以相同的方式显示:使用带有添加/删除按钮的双重可过滤列表框、可选的“理由”文本区域,如果请求的资源需要理由,则有条件地显示,以及一般注释。我为各个面板构建了以下 ViewModel:

public class RequestableList
{
    // list of requestable items ids requiring justification
    private List<string> _restrictedItems = new List<string>();
    public List<string> RestrictedItems
    {
        get { return _restrictedItems; }
        set { _restrictedItems = value; }
    }

    // the key-value pairs from which to populate available items list
    private Dictionary<string, string> _availableItems = new Dictionary<string, string>();
    public Dictionary<string, string> AvailableItems
    {
        get { return _availableItems; }
        set { _availableItems = value; }
    }

    // item ids requested by user
    private List<string> _requestedItems = new List<string>();
    public List<string> RequestedItems
    {
        get { return _requestedItems; }
        set { _requestedItems = value; }
    }
}

然后根据需要,主 ViewModel 由多个 RequestableLists 组成:

public class SimpleRequestViewModel
{
    public UserInfo userInfo { get; set; }
    public RequestableList Software {get;set;}
    public RequestableList Hardware {get;set;}
    public RequestableList Access {get;set;}
    public string SoftwareAdditionalInfo { get; set; }
    public string HardwareAdditionalInfo { get; set; }
    public string AccessFileMailShare { get; set; }
    public string AccessAdditionalInfo { get; set; }
    public string SoftwareJustification { get; set; }
    public string HardwareJustification { get; set; }
    public string AccessJustification { get; set; }
    public string Comment { get; set; }
}

我为 SimpleRequestViewModel(及其变体)创建了一个强类型视图,并为 RequestableList 创建了一个强类型 EditorTemplate,它连接了双列表框、过滤和 jquery。一切都很好并且正在工作,但代码目前有异味。

发布到控制器时,如果模型有效,我必须将其翻译成可读的文本描述,以便在呼叫中心应用程序中创建新工单。让控制器执行翻译成可读文本感觉不对,但是当我尝试设计另一个类来翻译视图模型时遇到了障碍。

  1. 仅发布选定的项目值,因此在将请求转换为文本之前,我必须首先为提供的值查找适当的文本(它们在描述中是必需的)。控制器是当前唯一有权访问此查找查询的呼叫中心数据模型的对象。
  2. 有 2 个相似的 ViewModel 包含不同的 RequestableLists 组合,因此任何翻译器都必须能够翻译各种组合。一个只有硬件和软件,另一个可能有硬件软件,还有几个 RequestableList。

我考虑直接在 ViewModel 中覆盖 ToString() 但不喜欢那里的业务逻辑(条件渲染),并且再次发布后,ViewModel 不包含列表框中所选项目的文本,因此它需要访问到数据模型。将发布的值转换为文本,因为它当前在控制器中处理,因为它是在 switch 语句中处理的。控制器获取每个发布的 RequestableList 并在构建新的工单描述之前填充原始的“可用”字段。

switch (requestCategory)
{
    case RequestableCategory.Software:
        itemList = sde.GetSoftware();
        break;
    case RequestableCategory.Hardware:
        itemList = sde.GetHardware();
        break;
    case RequestableCategory.Access:
        itemList = sde.GetAccess();
        break;
    case RequestableCategory.Telecom:
        itemList = sde.GetTelecom();
        break;
    default:
        throw new ArgumentException();
}

所以,我的问题:

  1. 您会推荐哪些模式来执行已发布的视图模型到工单描述的翻译?
  2. 当您需要文本和值时,您通常如何处理选择框的“仅发布值”问题?
  3. 我有没有更好的方法来解决这个问题?

同样,我希望这对我来说是一次学习经历,并且如果需要,我非常愿意提供额外的信息或描述。

4

1 回答 1

1

几点建议:

  1. 将呼叫中心提交的逻辑抽象到它自己的类中。提供(从控制器)访问呼叫中心数据库所需的任何依赖项。使用重载有不同的方法来处理各种类型的视图模型。大概描述来自数据库,因此您可以根据此类中的值从数据库中提取描述。此类还可以负责为显示操作构建视图模型。请注意,使用这种模式,类可以直接与数据库交互,通过存储库,甚至通过 Web 服务/API。

  2. 如果性能是第二次从数据库中查找描述的问题,请使用实现一些缓存的存储库模式。我怀疑除非您的呼叫中心非常大,否则不会,但这将是优化查询逻辑的地方。存储库可以是控制器传递给提交类的东西。

  3. 如果您不需要直接在控制器中访问数据库,请考虑直接将代理类作为依赖项传递。

它可能看起来像:

private ICallCenterBroker CallCenterBroker { get; set; }

public RequestController( ICallCenterBroker broker )
{
   this.CallCenterBroker = broker;
   // if not using DI, instantiate a new one
   // this.CallCenterBroker = broker ?? new CallCenterBroker( new CallCenterRepository() );
}

[HttpGet]
public ActionResult CreateSimple()
{
    var model = this.CallCenterBroker.CreateSimpleModel( this.User.Identity.Name );
    return View( model );
}


[HttpPost]
public ActionResult CreateSimple( SimpleRequestViewModel request )
{
    if (Model.IsValid)
    {
       var ticket = this.CallCenterBroker.CreateTicket( request );
       // do something with ticket, perhaps create a different model for display?
       this.CallCenterBroker.SubmitTicket( ticket );
       return RedirectToAction( "index" ); // list all requests?
    }
    return View();
}
于 2011-05-08T15:19:54.677 回答