2010-04-07 2 views
2

좋은 MVC 구현을위한 리트머스 테스트는 뷰를 쉽게 바꿀 수있는 방법입니다. 나는 게으름 때문에 항상이 일을 정말로 잘못했지만 지금은 제대로하고 싶습니다. 이것은 C++이지만 과장된 것을 믿는다면 비 데스크탑 응용 프로그램에도 똑같이 적용되어야합니다.컨트롤러와 뷰 사이의 연결

다음은 하나의 예입니다. 응용 프로그램 컨트롤러는 백그라운드에서 일부 URL을 확인해야합니다.

BackgroundUrlCheckerThread(Controller & controller) 
{ 
    // ... 
    signalUrlAvailable.connect(
     boost::bind(&Controller::urlAvailable,&controller,_1)) 
} 

그래서 Controller::urlAvailable처럼 무엇을 보는가

: 그것은 다음과 같이 (부스트 신호를 사용하여) "URL 가능"이벤트에 연결할 수 있습니다?

void 
Controller::urlAvailable(Url url) 
{ 
    if(!view->askUser("URL available, wanna download it?")) 
     return; 
    else 
     // Download the url in a new thread, repeat 
} 

이 나에게, 뷰와 컨트롤러의 총 결합처럼 보인다 :

여기에 하나의 가능성이다. 이러한 결합은 웹을 사용하는 경우이 불가능 뷰를 구현할 수 있습니다

또 다른 가능성 (옆으로 코 루틴을.) :

void 
Controller::urlAvailable(Url url) 
{ 
    urlAvailableSignal(url); // Now, any view interested can do what it wants 
} 

나는 후자에 부분 해요하지만이 나타납니다 나는이 작업을 수행 할 경우이 것을 be :

  1. 이러한 신호는 400 억 개입니다.
응용 프로그램 컨트롤러는 주어진보기 실수로 일부 신호를 무시하는 것이 매우 현실 가능성이 적지 않은 응용 프로그램
  • A의 거대한 얻을 수있는 API (링크 시간에 당신을 알릴 수 있지만, 신호/슬롯은 런타임입니다)

    커플 링을 제거하고 복잡성을 낮추려면 어떻게해야합니까? 미리 감사드립니다.

  • 답변

    3

    좋은 MVC 구현을위한 리트머스 테스트는보기를 쉽게 바꿀 수있는 방법입니다.

    나는이 말을하기 위해 불을 붙이 겠지만, 나는이 말에 동의하지 않는다. 이것은 종이에서보기에는 좋지만 현실적인 예는 좋은 UI가 반응적이고 상호 작용한다는 것을 보여줍니다. 종종보기와 컨트롤러를 얽히게 할 필요가 있습니다. 예기치 않은 이론적 인 견해를 다루기 위해 완전히 일반적인 컨트롤러를 코딩하려고하면 컨트롤러와 뷰 모두에 많은 코드와 복잡성이 추가됩니다. 상호 연결된 뷰/컨트롤러가 내 경험에서 더 잘 작동했습니다. 저는 이것을 "M (VC)"라고 생각합니다.

    좋은 MVC 구현을위한 리트머스 테스트는 모델에 다른 뷰/컨트롤러 쌍을 "추가"하는 것이 얼마나 쉬운 지 말할 것입니다. 하나의보기/컨트롤러 (예 : 데스크톱 운영자)의 모델 변경 사항이 다른보기/컨트롤러 (예 : 웹 원격 사용자)에게 전파되었는지 확인합니다. 이 모델은 다른 뷰/컨트롤러 패러다임 (예 : 데스크탑 GUI, 명령 행, 예약 된/일괄 처리 된 입력, 웹 기반 UI, 웹 서비스 등)을 지원할만큼 충분히 일반적인 모델입니까?

    컨트롤러 코드를 공유 할 수 없다는 의미는 아닙니다 (예 : 공통베이스에서 파생 됨) 컨트롤러에서 처리해야하는 것 (모델의 외부 조작)) 그리고 모델의 행동 (모델의 내부 전이)의 일부로 간주되어야하는 것. 보기 코드도 마찬가지입니다.

    "What goes into the “Controller” in “MVC” 아래 답변 중 일부를 읽는 것이 도움이 될 것이라고 생각합니다.

    +1

    StackOverflow에 대한 광범위한 설문 조사에서 링크 된 게시물을 읽었습니다. 내가 너에게 동의하지 않는다고 말하는게 아니야. 제 경우에는 그렇습니다. 모델은 충분히 일반적인 것입니다. 현재 데스크톱 및 XML-RPC보기를 지원합니다. 그러나 피하려고하는 반복 된 코드가 많이 있습니다. 나는 MVC가 크게 도움이 될 것이라고 생각했다. 위의 예제를 상호 연결된 세계에서 어떻게 다시 작성하겠습니까? – cheez

    +0

    당신의 솔루션 ("이 ... 뷰와 컨트롤러의 커플 링")이 자연스럽고 예상되는 것입니다. 다른보기를 구현하려면 함께 연결된 새로운 상호 연결된 컨트롤러를 만들어야 할 수도 있습니다. 2 개의 뷰와 2 개의 컨트롤러 사이에서 공통 코드 (아마도 기본 클래스로)를 추출하려면 리팩터링해야 할 수도 있습니다. 위의 컨트롤러 코드는 데스크톱 응용 프로그램 용이고 새로운보기는 UI가 아닌 XML-RPC보기 용인 것으로 가정합니다. 사용자 상호 작용없이 URL을 다운로드하는 urlAvailable() 콜백을 사용하여 XML-RPC 컨트롤러를 만들 수도 있습니다. –

    +1

    그런 설정에서, 나는 컨트롤러가 0에서 전혀 로직을 갖지 않을 것이라고 추정한다. 즉, 단순히보기와 모델을 연결합니다. – cheez

    0

    'm'모델을 사용하여 디커플링을 유지하고 명령을 사용하는 패턴 및 수신기 패턴을 사용하여 복잡성을 줄입니다.

    그래서 컨트롤러는이 같은 외모 수 있습니다

    void 
    Controller::urlAvailable(Url url) 
    { 
        Controller::fireSignal("urlAvailable", url, ... other possible parameter); 
    } 
    Controller::fireSignal(char* cmd, Url url, ... other possible parameters) { 
        Model &M = new Model(); 
        M->command = cmd; 
        M->url  = url; 
        M-> ... other possible 
        for(int v = Controller::ViewCount; --v >= 0;) 
         Controller::Views[v]->notice(M); 
    } 
    

    참고 : 나는 프로그래머는 그렇게 잘못된 문법 용서 ++ C 아닙니다.

    MVC의 전체 아이디어는 M (odel)을 사용하여 V (iew)에서 C (ontrol)를 분리하는 것입니다. 이 예는 매우 단순합니다. 보다 실용적인 것은 다른 종류의 유사한 신호에 대해 다른 모델을 사용하는 것입니다.

    희망이 도움이됩니다.