我正在Android中使用MVP模式。结构如下所示。
Activity - Presenter
|
Fragment
|
CustomView
|
views
因此,当演示者从网络获取数据时,它将直接将数据传递给片段,然后将片段传递数据传递给自定义视图,并将自定义视图传递数据传递给视图。
我不确定如何使用MVP模式传递活动视图中使用的数据。如果我为每个片段,自定义视图和视图创建演示者,那么如何将数据从活动演示者传递给其他演示者? 有人可以帮我举例吗?
答案 0 :(得分:1)
为了给您的问题一个更具体的答案,您需要举一个具体的例子。每个解决方案在 上下文 中均有效。我将提供几种方法来实现此目的。选择一个适合您的问题。
MVP 的非常重要的部分是 模型 。据我所知,术语 Model 在论文Thing Model View Editor的发布中在编程中很流行,该论文后来被完善并重命名为MVC。
本文中 模型 的概念定义为:
模型 是 抽象 的有效表示形式,其形式为 计算系统中的数据
模型 在计算机中表示为数据的集合 以及处理这些数据所必需的方法。
随着时间和经验的积累,人们发现并指定了不同类型的模型。
其中一些是
MVP (由于它是从MVC派生而来的)进行了两个主要的职责划分: 模型 (代表概念的抽象< / em>)和 演示文稿 (查看和演示者以可视化 模型 ))
由于我们已将 模型 与 演示文稿 相除,所以我们可以乘以 显示相同 模型 的>视图 。例如,表示 统计数据 的 模型 可以用不同的方式显示:饼图,柱状图等。在此示例中, 统计数据模型 是 域模型 。
在上面的示例中, 模型 可能会在两个 View-Presenter对 之间共享, PieChart 和 BarChart 。如果您使用Observer pattern,则当 视图展示者对之一 更新 StatisticalModel 时,它将引发更改的事件,并且两个 View-Presenter对 都会收到有关此更改和更新的通知。
有时应用程序需要 ApplicationModel 。此模型可以在不同的 视图-展示对 之间共享。让我们看一个非常简单的示例。
假设我们有一个文件浏览器应用程序,例如Windows资源管理器。该应用程序的GUI有两个主要部分:左侧面板显示文件夹的 Tree ,中间面板显示文件文件夹面板。在左侧文件夹树面板中选择一个文件夹时,所选文件夹中的文件和文件夹必须显示在中间面板中。我们可以通过定义 ApplicationModel 来做到这一点,该模型将捕获并表示上述逻辑,并在两个 View-Presentation对 < / strong>(左侧面板和中间面板)。
注意:我将省略该示例的详细信息,并减少代码量
public class ApplicationState {
// singleton, it's evil I know,
// but it's the simplest way without DI or ServiceLocator
private static ApplicationState mInstance = new ApplicationState();
public static ApplicationState getInstance() { return mInstance; }
private Folder mSelectedFolder;
public bool hasSelectedFolder() { return mSelectedFolder != null; }
public Folder getSelectedFolder() { return mSelectedFolder; }
public Folder setSelectedFolder(Folder f) {
mSelectedFolder = f;
RaiseSelectedFolderChangedEvent();
}
// method for registering listeners, raising events etc.
}
public class FoldersTreeViewPresenter {
private ApplicationState mApplicationState;
public void onSelectFolder(FolderView view) {
// select the folder in the view
mApplicationState.setSelectedFolder(view.Folder);
}
}
public class FilesFoldersViewPresenter : ApplicationStateListener {
private ApplicationState mApplicationState;
public FilesFoldersViewPresenter() {
// you can use service locator, dependency injection, whatever
mApplicationState = ApplicationState.getInstance();
mApplicationState.addEventListener(this);
}
private void getFilesAndFoldersFromFileSystem(Folder folder) {
// get from fs
// fill views with them etc.
}
private void clearView() {
// clear the panel
}
public void onApplicationStateChanged() {
if(mApplicationState.hasSelectedFolder()){
getFilesAndFoldersFromFileSystem(mApplicationState.getSelectedFolder());
}
else {
clearView();
}
}
}
在此示例中,我们创建了一个共享对象,该对象表示应用程序状态和逻辑,即我们的应用程序具有可以更改的选择。在这种情况下, ApplicationState 类是 Model 的一部分,并且是 Application Model 。因为它是共享的,并且其生命周期与应用程序相同(只要应用程序正在运行,它就存在),它将保持状态。创建并销毁了 视图 和 Presenters ,但是此类将存在并保持状态,因此当创建新的 查看 和/或 Presenter ,它可以检查此状态并执行某些操作。
在我的经验中,人们确实更专注于“视图”和“演示者”,而他们应该使用其 模型 。我经常使用 Models ,因为它可以使事情变得更整洁,并使应用程序更易于理解。
当然,使用 模型 并不总是有效,因此,当它们不起作用时,您可以使用 消息 ,让一个 演示者 向其他人发送消息。这是具有相同文件浏览器应用程序的示例。
public class MessageBus {
// static this time, you can use DI or ServiceLocator with interface
public static void sendMessage(object m) { }
public static void registerListener(MessageListener listener) { }
}
public class FoldersTreeViewPresenter {
public void onSelectFolder(FolderView view) {
// select the folder in the view
MessageBus.sendMessage(new FolderSelected(view.Folder));
}
}
public class FilesFoldersViewPresenter : MessageListener {
public FilesFoldersViewPresenter() {
MessageBus.addListener(this);
}
private void getFilesAndFoldersFromFileSystem(Folder folder) {
// get from fs
// fill views with them etc.
}
public void onMessage(object m) {
if(m instanceof FolderSelected) {
FolderSelected folderSelectedMessage = (FolderSelected)m;
getFilesAndFoldersFromFileSystem(folderSelectedMessage.Folder);
}
}
}
根据您的具体情况,如果可以创建一个不错的 模型 (域,应用程序或演示文稿),请执行此操作。共享此 Model ,从而从 Presenters 中创建对 Model 的依赖> ,而不是在 Presenters 之间创建依赖关系。这样,您可以在 Presenters 之间松散耦合,并且可以更轻松地进行更改
如果您不能使用 模型 ,请使用 消息 。通过创建用于通信的消息的 协议 ,这是使 Presenters 脱钩的好方法。
查看this文章,内容涉及使用消息在组件之间进行协作。
这里还有一些关于GUI体系结构的好文章: