2009-07-13 3 views
6

프로그래밍 초보자로서 벽에 부딪쳤을 때 항상 버그가 난다. 현재 벽면 중 하나는 병에 의존하는 물체입니다.Java MVC - 느낌이 들지 않는다

내 질문에 역사에서 볼 수 있듯이 현재 MVC 패턴이라고 부르는 것을 구현 한 블랙 베리 응용 프로그램에서 작업하고 있지만 정확하게 의도 한 바가 아닙니다.

초보자 프로그래머는이 그래픽과 같은 초록을보고 아이디어를 얻습니다. 그러나 그것을 구현하는 것은 또 다른 일입니다.

alt text http://www.ibm.com/developerworks/wireless/library/wi-arch6/theoretical.gif

, 읽기 : 내가 당신에게 블랙 베리 특정 물건을 포함 내 일부 코드를 보여주는거야 멈추지 않는다, 그러나 당신은 내가 뭘하는지 볼 수하십시오. Mainscreen 모델

public class ContactManagerMainScreenModel 
{ 
    ContactManagerMainScreen v; 
    // Loading Local Storage 
    LocalContactStorage LocalContactStorage = new LocalContactStorage(); 

    // Define Data List 
    private Vector vContacts_Favorites; 

    public void register(ContactManagerMainScreen v) 
    { 
     this.v = v; 
    } 
    // Retrieve Favorite Contacts from Persistant Storage 
    public Vector getFavoriteContactsFromLocalStorage() 
    { 
     vContacts_Favorites = LocalContactStorage.getFavoriteContactsFromLocalStorage(); 
     return vContacts_Favorites; 
    } 
    // Put Retrieve Favorite Contacts from Persistant Storage 
    public void saveFavoriteContactsToLocalStorage() 
    { 
     LocalContactStorage.saveFavoriteContactsToLocalStorage(vContacts_Favorites); 
    } 
} 

MainScreenController

public class ContactManagerMainScreenController 
{ 
    private ContactManagerMainScreenModel _model = null; 
    private ContactManagerMainScreen _view = null; 

    public ContactManagerMainScreenController(ContactManagerMainScreen view, ContactManagerMainScreenModel model) 
    { 
     this._model = model; 
     this._view = view; 
    } 

    public void HideFavoriteList() 
    { 
     if(this._view._ContactList.getManager() != null) 
     { 
      this._view._ContactList.getManager().delete(this._view._ContactList); 
     } else 
     { 
      this._view._bottom_box.add(this._view._ContactList); 
     } 
    } 
} 
내 응용 프로그램

public class ContactManager extends UiApplication 
{ 
    private static ContactManagerMainScreenModel MainScreenModel = new ContactManagerMainScreenModel(); 
    private static ContactManagerMainScreen MainScreenView = null; 

    public static void main(String[] args) 
    { 
     new ContactManager().enterEventDispatcher(); 
    } 
    public ContactManager() 
    { 
     MainScreenView = new ContactManagerMainScreen(MainScreenModel); 
     // Displays the Splashscreen then opens the Mainscreen 
     new SplashScreen(UiApplication.getUiApplication(), MainScreenView); 
    } 
} 

에 대한

메인 엔트리 포인트 0

아직도 거기에? 좋아요 ...

내 문제는 컨트롤러를 사용하여 PopUp Box 표시, someting 또는 다른 것들을 숨기는 UI 요소를 변경하고 싶습니다.

그러나 이러한 모든 UI 요소는보기 (여기에서는 ContactManagerMainScreen)에 정의되어 있으므로 컨트롤러에보기에 대한 참조를 제공해야합니다. 내 공동의 목표를 불행하게 만듭니다.

보기를 선언하기 전에 컨트롤러를 만들 수 없습니다. 컨트롤러가 UIElements를 변경할 수있는 요구 사항이 없으면 (그래픽에 표시된 것처럼) 문제가되지 않습니다.

는보기

controller = new ContactManagerMainScreenController(this , model); 

은 그 의미가 있습니까 컨트롤러를 생성하는 내가 지금하고있어인가? 패턴을 이해하고 싶기 때문에 코드 쓰레기 나 원하는 것을 부르세요. 단지 뭔가 배우고 싶습니다.

P. 내 나쁜 영어에 대한 당신의 용서를 구하십시오 :)

답변

11

MVC는 흥미로운 추상화이지만, 몇 가지 문제가 있습니다.

사실 컨트롤러와 뷰는 이론적으로 서로 짝을 맞출 수는 있지만 실제로는 서로 다른 뷰의 인터페이스 메커니즘이 다르기 때문에 컨트롤러 &보기가 결합됩니다. .

Java와 관련하여 가장 잘 설명한 내용은보기가 스윙 구성 요소이므로보기 코드의 일부만 화면에 표시되는 것입니다.

컨트롤러는 나머지 클래스, 리스너 및 뷰와 상호 작용하는 나머지 코드입니다.

제 제안은 뷰와 컨트롤러를 분리하는 것에 대해 너무 걱정하지 않아도되지만, 모델과 뷰/컨트롤러간에 매우 강한 분리를 유지하는 것입니다.

EDIT/고급 : 저는 컨트롤러와 뷰가 분리되어 있으며 더 유연하지만 패턴이 더 많이 사용되는 경향이 있습니다. Struts는 바인딩 모델을 사용합니다. 일부 추상화 기술을 보길 원할 경우 "바인딩"스윙 컨트롤에 대한 정보를 검색하거나 검색 할 수 있습니다.

+0

+1 전적으로 동의합니다. – neuro

+0

+1 이것도 내 경험에 달려있다. – Zarkonnen

+0

(누구나 *보기와 컨트롤러를 완벽하게 구분할 수있는 케이스를 만들 수 있다면 매우 흥미가 있습니다.) – Zarkonnen

1

내 관점에서 볼 때, 이것은 첫 번째 데스크톱 응용 프로그램에서 내 모델, 뷰 및 컨트롤러를 분리하려고 처음 시도했을 때의 문제입니다.

웹 응용 프로그램을 사용하면 MVC 패턴이 자연스럽지 만 웹에 자연스럽지 만 유감스럽게도 순수 MVC 패턴을 운영 체제가 알림에서 타고난 역할을하는 데스크톱 응용 프로그램에 맞출 수 없습니다. 이것은 일반적으로 다이어그램에 표시된대로 패턴이 구현되도록합니다.

그러나 당신이 보여준 패턴이 정말 이런 식으로 구현 될 필요가있다, 나는 생각한다 (I 자바 짧은 일 후 .NET으로 전환, 그래서 명심하시기 바랍니다) :

public class ContactManagerMainScreenModel 
{ 
    ContactManagerMainScreen v; 
    // Loading Local Storage 
    LocalContactStorage LocalContactStorage = new LocalContactStorage(); 
    // Favorite list 
    boolean showFavoritesList = true; 

    public void register(ContactManagerMainScreen v) 
    { 
     this.v = v; 
    } 

    public void ShowOrHideFavoritesList() 
    { 
     if(showFavoritesList) 
     { 
      showFavoritesList = false; 
      v.RefreshView(this); 
     } 
     else 
     { 
      showFavoritesList = true; 
      v.RefreshView(this); 
     } 
    } 
} 

한편 컨트롤러는 사용자 동작을 수신 할 책임이 있습니다. 그래서 "Toggle Favorites"라는 버튼이 있다면 컨트롤러가 _model.ShowOrHideFavoritesList()를 호출하게됩니다. 모델 자체를 업데이트하고 새로운 상태를 사용하여보기를 새로 고치라고 요청합니다.

보기에는 이제 컨트롤러에 대한 종속성이 없습니다.

+0

답장을 보내 주셔서 다시 한 번 감사드립니다. 귀하의 구현은 UI 자체를 직접 제어하는 ​​모델로 이어질 것입니다. 전체 컨트롤러를 삭제 하시겠습니까? –

+0

아니요, 코드 뒤에 마지막 두 단락을 읽으십시오. 컨트롤러는 모든 사용자 알림을 처리합니다. 다른 예가 있습니다. 사용자가 "새 연락처 추가"를 클릭하면 컨트롤러가 _model.AddNewContact (string firstName, string lastName)을 호출해야합니다. 모델은이 연락처를 자신의 내부 상태로 추가 한 다음 뷰에서 RefreshView (this)를 호출합니다. –

+0

내 말은 컨트롤러가 모든 사용자 알림을 캡처 한 다음 모델을 업데이트하는 방법을 결정할 책임이 있다는 것입니다. 그러면 모델은 항상 뷰에서 RefreshView (this)를 호출하여 자신을 다시 표시합니다. –

3

나는 다이어그램이 매우 좋다고 생각하지 않으며 아마도 훨씬 더 혼란스럽게 만듭니다.

컨트롤러는 모델을 뷰에 제공해야합니다. 모델에는 데이터에 간단한 접근 자 이상을 포함하면 안됩니다. 모델과 상호 작용하거나 값을 변경해야하는 필요성은 컨트롤러를 통해 발생해야합니다.

이렇게하면보기는 모델을 사용자에게 렌더링/표시하는 방법 만 알아야합니다. 따라서 모델의 모든 작업 (예 : saveFavoriteContactsToLocalStorage())은 View 클래스가 아닌 컨트롤러의 메소드 여야합니다. 또한 Controller는 View에 대한 참조를 생성 할 필요가 없습니다. 전체 MVC 패턴의 의도 된 순서를 뒤집을 것이라고 생각합니다.

+0

나는 다이어그램이 정확하다고 생각합니다. 문제는 MVC가 좋은 추상화가 아니며 모든 툴킷이 그것을 설계 한 방식에 맞도록 조정한다는 것입니다. 어떤 사람들은 잘하고, 그렇지 않은 사람도 있습니다. 한 가지 확실한 점은, 당신이 관점을 바꾼다면, 결국 (이론에 반하는) 컨트롤러를 바꾸게된다는 것입니다. 아마도 –

+0

. 저는 웹 컨텍스트에서 MVC를 사용하는 것에 정말로 익숙합니다.이 경우 Controller는 Spring MVC 에서처럼 View 및 Model을 반환하기 만하면됩니다. 데스크탑에서 꽤 다를 수 있습니다. –

2

빌 K에 동의합니다. 리치 클라이언트를 처리 할 때 표준 MVC가 중요하지 않습니다. 이벤트 (브라우저의 클릭)가 사용자의보기 (HTML 렌더링)와 완전히 다른 경우 웹 앱을 작성할 때 훌륭한 모델입니다.

표준 GUI의 경우 더 좋은 모델은 PAC (표현/추상화/제어)입니다. 여기서 프레젠테이션은 (뷰 + 이벤트 핸들러) 컨트롤러는 프레젠테이션과 추상 사이의 교환을 관리합니다. 그리고 추상화는 비즈니스 모델입니다.

이렇게하면 GUI 부분 (보기 + 사용자 이벤트)과 추상화 사이의 링크를 관리하는 컨트롤러가 있습니다. 당신은 개발 한 GUI 조각을위한 PAC 에이전트와 그것들 사이의 깨끗한 분리를 가지고 있습니다.

MVC보다 PAC에 관한 또 다른 기사 : HMVC. 꽤 오래되었지만 실용적이며 이해하는 데 도움이됩니다.

관련 문제