代码之家  ›  专栏  ›  技术社区  ›  Henrik P. Hessel

JavaMVC——我感觉不到

  •  6
  • Henrik P. Hessel  · 技术社区  · 16 年前

    作为一个编程初学者,当我遇到墙壁时,它总是让我心烦。 当前其中一个墙是相互依赖的对象。

    正如你在我的问题历史中看到的,我目前正在开发一个黑莓应用程序,在这个应用程序中我实现了我称之为MVC模式的东西,但它并不是我所认为的那样。

    你看,一个初学的程序员,你看像这幅图这样的抽象图,你就会得到它背后的想法。但实现它是另一回事。

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

    请不要停止阅读:)我给你们看了一些我的代码,其中包含了一些特定于黑莓的东西,但你们应该看看我在做什么。

    我的申请的主要入口点

    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);
        }
    }
    

    主屏幕模型

    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);
        }
    }
    

    主屏幕控制器

    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);
            }
        }
    }
    

    还在那儿吗?可以。。。

    我的问题是,我想使用控制器来更改UI元素,比如显示弹出框、隐藏某些内容或其他内容。

    但是所有这些UI元素都是在视图中定义的(这里是contactmanagerminscreen),因此必须向控制器提供对视图的引用。这导致了我的共同依赖对象的痛苦。

    在声明视图之前,无法创建控制器。如果没有允许控制器更改uielements的要求,就没有问题(如图中所示)。

    我现在要做的是视图创建控制器

    controller = new ContactManagerMainScreenController(this , model);
    

    这有道理吗?我想了解这个模式,所以把我的代码称为垃圾或者你喜欢的任何东西:)我只是想学习一些东西。

    另外,请原谅我英语不好。)

    4 回复  |  直到 16 年前
        1
  •  11
  •   Bill K    16 年前

    MVC是一个有趣的抽象,但有一些问题。

    实际上,控制器和视图经常是成对的——尽管理论上您应该能够替换其中一个而不替换另一个,但实际上,不同视图的接口机制是如此不同,以至于控制器和视图是组合在一起的。

    我见过的有关Java的最好描述是视图是Swing组件,所以视图代码的一部分只是把这些组件放到屏幕上。

    控制器是该类的其余部分、侦听器以及与视图交互的其余代码。

    我的建议是不要太担心隔离视图和控制器,但也就是说,我完全落后于在模型和视图/控制器之间保持非常强的分离。

    编辑/高级: 我使用了一种模式,其中控制器和视图是隔离的,而且它更灵活,但它往往要做更多的工作。我认为Struts使用绑定模型——如果您希望看到一些抽象技术,您可以在那里查看或搜索有关“绑定”Swing控件的内容。

        2
  •  3
  •   matt b    16 年前

    我不认为这个图表很好,可能会让事情变得更混乱。

    控制器应负责将模型提供给视图。模型只应包含数据的简单访问器。任何与模型交互的需要——或者改变它的任何值——都应该通过控制器来实现。

    这样,视图只需要知道如何向用户呈现/呈现模型。所以模型上的任何操作-比如 saveFavoriteContactsToLocalStorage() -应该是控制器的方法,而不是视图类。此外,控制器不需要对要构建的视图进行引用——我认为这最终会颠倒整个MVC模式的预期顺序。

        3
  •  2
  •   neuro    16 年前

    我同意比尔K。标准MVC在处理富客户时并不那么重要。当编写Web应用程序时,它是一个很好的模型,因为事件(在浏览器中单击)与视图(HTML呈现)截然不同。

    使用标准的GUI,一个更好的模型称为 PAC (陈述/抽象/控制)。这里的表示是(视图+事件处理程序),控制器管理表示和抽象之间的交换。抽象是你的商业模式。

    这样,您就有了一个控制器来管理GUI部分(视图+用户事件)和抽象之间的链接。对于您开发的任何一个图形用户界面,您都有一个PAC代理,并且它们之间有一个清晰的分离。

    另一篇关于比MVC更好的关于PAC的文章: HMVC . 很古老,但它很实用,有助于理解事物。

        4
  •  1
  •   Praveen Angyan    16 年前

    从我的角度来看,这是我第一次尝试在第一个桌面应用程序中分离模型、视图和控制器时遇到的问题。

    对于Web应用程序,由于Web固有的特性,MVC模式非常自然地适合,但不幸的是,不可能将纯MVC模式适合桌面应用程序,在桌面应用程序中,操作系统在通知中扮演着固有的角色。这通常会导致如图中所示的模式被实现。

    但是,您所展示的模式确实需要像这样实现,我想(我在与Java发生了短暂的事件之后切换到.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);
            }
        }
    }
    

    同时,控制器将负责接收用户操作。因此,如果有一个按钮显示“切换收藏夹”,这将导致控制器调用_model.showorhideFavoritesList()。模型将更新自身,并要求视图使用其新状态刷新自身。

    现在视图将不再依赖于控制器。