2

사용하기 어려운 콜센터 응용 프로그램 용으로 간단한 MVC3 기반 티켓 입력 사이트를 구축했으며 부분적으로 디자인 패턴을 더 잘 준수하도록 내 프로토 타입을 리팩토링하려고합니다. 그것은 앞으로 더 maintainable하지만 대부분 학습 운동으로. 사용자 지향 뷰는 다양한 리소스 유형을 선택할 수있는 몇 가지 패널 외에도 기본 사용자 정보로 구성된 양식입니다. 추가, 제거 버튼이있는 이중 필터 가능 목록 상자, 요청 된 자원이 양쪽 정렬이 필요한 경우 조건부로 표시되는 선택적인 "양쪽 맞춤"텍스트 영역 및 일반 주석이 각 자원 유형 (하드웨어, 소프트웨어 등)과 동일한 방식으로 표시됩니다. 나는 각각의 패널에 대해 다음 뷰 모델을 구축 :MVC3 - ViewModels 및 컨트롤러 기능 : 제안 된 디자인 패턴

메인 뷰 모델은 다음 여러 RequestableLists 구성되어
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; } 
    } 
} 

필요에 따라 :

나는 SimpleRequestViewModel에 대한 강력한 형식의 뷰를 생성 한
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; } 
} 

(및 변형) 및 강력하게 형식화 된 RequestableList 용 EditorTemplate은 이중 목록 상자, 필터링 및 jquery를 연결합니다. 모두 잘 렌더링되고 작동하지만 코드는 현재 냄새가납니다.

컨트롤러에 게시 할 때 모델이 유효하면 콜센터 앱에서 새 티켓을 만들려면 읽을 수있는 텍스트 설명으로 변환해야합니다. 컨트롤러가 읽을 수있는 텍스트로 변환을 수행하는 것이 옳지는 않지만 viewmodels을 번역 할 다른 클래스를 설계하려고 할 때 장애물이 발생합니다.

  1. 요청 항목을 텍스트로 변환하기 전에 선택한 항목 값만 게시되므로 제공되는 값 (설명에 필요함)에 대한 적절한 텍스트를 먼저 찾아야합니다. 컨트롤러는 현재이 조회 쿼리의 콜 센터 데이터 모델에 액세스 할 수있는 유일한 개체입니다.
  2. RequestableLists의 다양한 조합이 포함 된 2 개의 유사한 ViewModel이 있으므로 모든 번역자가 다양한 조합을 번역 할 수 있어야합니다. 하나는 하드웨어 및 소프트웨어 만 있고 다른 하나는 하드웨어 소프트웨어 및 몇 가지 요청 가능 목록이있을 수 있습니다.

ViewModel에서 직접 ToString()을 재정의했지만 해당 비즈니스 로직 (조건부 렌더링)이 마음에 들지 않아 다시 게시되면 ViewModel에 선택한 항목의 텍스트가 listbox를 사용하여 데이터 모델에 액세스해야합니다. 컨트롤러에서 현재 처리중인 게시 된 값의 텍스트로의 변환은 switch 문에서 처리 될 때 냄새가납니다. 컨트롤러는 게시 된 각 RequestableList를 가져 와서 새로운 티켓 설명을 작성하기 전에 원래의 "Available"필드를 채 웁니다.

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. 이 문제에 접근하는 더 좋은 방법이 있습니까?

다시 말해서 나는 이것이 나를위한 학습 경험이되고 필요할 경우 추가 정보 나 설명을 기꺼이 제공하기를 바란다.

답변

1

몇 가지 제안 :

  1. 추상 자신의 클래스로 콜센터 제출을 수행하는 논리. 콜 센터 DB에 액세스하는 데 필요한 종속성을 컨트롤러에서 제공하십시오. 오버로딩을 사용하여 다양한 유형의 뷰 모델을 처리하는 여러 가지 방법을 사용하십시오. 아마도 설명은 DB에서 나온 것이므로이 클래스의 값을 기반으로 DB에서 설명을 추출 할 수 있습니다. 이 클래스는 표시 작업에 대한보기 모델을 작성하는 책임을 질 수도 있습니다. 이 패턴을 사용하면 클래스가 DB와 직접 상호 작용하거나 저장소를 통해 또는 웹 서비스/API를 통해 상호 작용할 수 있습니다.

  2. 성능이 DB에서 설명을 두 번째로 찾는 데 문제가있는 경우 일부 캐싱을 구현하는 저장소 패턴을 사용하십시오. 콜센터가 매우 큰 경우가 아니면 의심스러운 일이지만 쿼리 로직을 최적화 할 수있는 장소가 될 것입니다. 저장소는 컨트롤러가 제출 클래스에 전달할 수 있습니다.

  3. 컨트롤러에서 직접 DB에 액세스 할 필요가없는 경우 브로커 클래스를 종속성으로 직접 전달하는 것을 고려하십시오.

그것과 같을 수 있습니다

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(); 
} 
+0

적합합니다. 어떤 이유로 나는 컨트롤러와 뷰 이외의 다른 것에 ViewModels를 사용하는 것을 싫어했다. 브로커가 설치되었으므로 순환 복잡성이 크게 떨어졌습니다. 귀하의 회신에 감사드립니다. – Shawn