作为编程的初学者,当我遇到墙壁时,它总是让我烦恼。 目前,其中一面墙是共同依赖的物体。
正如你在我的问题历史中所看到的,我正在开发一个黑莓应用程序,我在其中实现了一些我称之为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);
}
}
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);
}
}
}
还在吗?好的......
我的问题在于,我想使用控制器来更改UI元素,例如显示弹出框,隐藏某些内容或其他内容。
但是所有这些UI元素都在View中定义(此处为ContactManagerMainScreen),因此必须向Controller提供对View的引用。这导致我的共同依赖对象的痛苦。
在声明视图之前,我无法创建控制器。如果没有允许控制器更改UIElements的要求,则没有问题(如图中所示)。
我现在正在做的是View创建控制器
controller = new ContactManagerMainScreenController(this , model);
这有意义吗?我想了解这个模式,所以请把我的代码垃圾或任何你喜欢的东西叫做:)我只是想学点东西。
P.S。请原谅我糟糕的英语:)
答案 0 :(得分:11)
MVC是一个有趣的抽象,但有一些问题。
实际上,控制器和视图通常是成对的 - 即使理论上你应该能够替换任何一个而不是另一个,实际上,不同视图的接口机制是如此不同,以至于控制器和视图不同。视图结合在一起。
我见过的关于Java的最佳描述是视图是你的swing组件,所以你的视图代码部分只不过是将这些组件放在屏幕上。
您的控制器是该类的其余部分,侦听器以及与视图交互的其余代码。
我的建议是不要过分担心隔离视图和控制器,但是说,我完全支持在模型和视图/控制器之间保持非常强大的分离。
EDIT /高级: 我使用了一种模式,其中控制器和视图是隔离的,它更灵活,但它往往是更多的工作。我认为Struts使用绑定模型 - 如果你想看到一些抽象技术,你可能会看到那里或搜索关于“绑定”swing控件的东西。
答案 1 :(得分:3)
我认为这个图表不是很好,可能会让事情变得更加混乱。
控制器应负责将模型提供给视图。模型应该只包含数据的简单访问器。任何需要与模型交互 - 或更改其中的任何值 - 都应该通过Controller进行。
这样,View只需要知道如何向用户呈现/呈现模型。因此,模型上的任何操作 - 如saveFavoriteContactsToLocalStorage()
- 都应该是Controller的方法,而不是View类。此外,Controller不需要对要构造的视图的引用 - 我认为这最终会颠倒整个MVC模式的预期顺序。
答案 2 :(得分:2)
我同意Bill K.标准MVC在与富客户打交道时并不重要。在编写Web应用程序时,它是一个很好的模型,因为事件(浏览器中的点击)与您的视图(HTML呈现)完全不同。
使用标准GUI,更好的模型称为PAC(表示/抽象/控制)。这里的演示文稿是(视图+事件处理程序),控制器管理演示文稿和抽象之间的交换。抽象是您的商业模式。
这样你就有了一个控制器来管理GUI部分(视图+用户事件)和你的抽象之间的链接。对于您开发的任何GUI,您都有一个PAC代理,并且它们之间有清晰的分离。
另一篇关于与PAC相关的比PAC更好的文章:HMVC。相当古老,但它很实用,有助于理解事物。
答案 3 :(得分:1)
从我的角度来看,这是我第一次尝试在我的第一个桌面应用程序中分离出我的模型,视图和控制器时遇到的问题。
对于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);
}
}
}
同时控制器将负责接收用户操作。因此,如果您有一个显示“Toggle Favorites”的按钮,这将导致控制器调用_model.ShowOrHideFavoritesList()。该模型将更新自身并要求视图使用它的新状态刷新自身。
视图现在可以免受对控制器的依赖。