安卓上的MVC模式

514

在Java中为Android实现模型-视图-控制器(MVC)模式是否可行?

或者已经通过活动(Activities)实现了它?还是有更好的方法来实现Android的MVC模式?


64
你的问题非常好。但是我认为标记为解决方案的答案并不正确。它可能会误导一些人。 - Saghar
4
请查看我的两篇文章,从这里开始 Android 架构:MV? - Dori
1
还有没有额外的规则需要遵循以符合MVC,或者因为Activity、XML和Resources,Android开发已经适应了MVC? - Flame of udun
3
@Dori,我修复了你的链接:Android架构:MV? - Andreybeta
这篇文章恰好符合您的需求,通过实际示例介绍了Android中的MVC架构:http://www.digigene.com/architecture/android-architecture-part-2-mvc/ - Ali Nem
在使用Android Studio进行开发时,Android应用程序开发几乎就像MVC一样。 - Sohan Arafat
21个回答

242

在 Android 中,没有 MVC 模式,但您可以使用以下内容:

  • 您可以通过分辨率、硬件等在各种 XML 文件中定义用户界面
  • 您可以在各种 XML 文件中按语言环境等定义资源
  • 您可以扩展像 ListActivityTabActivity 等类,并通过布局填充器使用 XML 文件。
  • 您可以为您的业务逻辑创建任意数量的类。
  • 已经为您编写了许多工具类 Utils - 如 DatabaseUtils, Html 等。

3
@JDPekham,为什么你说“在没有与布局/视图交互的情况下,无法实例化 Activity ”?实例化 Activity 并不需要和视图进行交互,事实上,与视图交互绝不是 Activity 实例化的一部分。您可以在需要时(但不必)调用各种 Activity 方法与视图进行交互。第二个问题:假设 Activity 旨在扮演“控制器”角色(我相信许多 Android 开发人员都这样认为),为什么不从 Activity 中与视图交互呢? - user1545072
8
如果有人说“Android是MVC”,请让他/她尝试使用Backbone.js(是的,客户端JS)一个星期,再回来说“Android是MVC”。然后您会最终理解这个问题以及为什么我们一直在问它 :) - Mark Peterson
14
在Android中,你并不是没有MVC模式。和其他编程语言一样,如果你需要MVC模式,那么你就可以实现它。 - Lorenzo Barbagli
1
@LorenzoBarbagli的意思是,Android在应用程序中没有像iOS那样通过设计强制实施MVC。如果您想要实现MVC提供的关注点分离和独立易测的模型,您必须自己实现MVC、MVP或其他类型的架构。 - Piovezan
不,Android 中肯定有 MVC,只是更加隐式。根据 Android 的整体结构,它采用了一种不同的实现方式。 - 6rchid

235

并没有普遍适用的MVC模式。MVC是一个概念,而不是一个完整的编程框架。你可以在任何平台上实现自己的MVC。只要你坚持以下基本思想,你就在实现MVC:

  • Model: 渲染什么
  • View: 如何渲染
  • Controller: 事件、用户输入

还可以这样考虑它:当你编写模型时,模型不需要关心渲染(或特定于平台的代码)。模型会对视图说,“我不在乎你的渲染是Android、iOS还是Windows Phone,这是我需要你呈现的内容。” 视图只会处理特定于平台的渲染代码。

使用Mono共享模型以开发跨平台应用程序时,这尤其有用。


14
虽然那是真实的,说得很好,但这只是理论,人们更注重实际情况! - TWiStErRob
1
@TWiStErRob 但是设计模式是理论上的、抽象的概念,没有一种实现它们的方法。声称“我不想理解MVC的理论,我只想将其实现”听起来像是可能会导致“我要在厨房放一个洗衣机,因为洗衣机实现了Cleaner™模式,而厨房需要这个”。 - Lukas Juhrich
1
我认为示例非常宝贵,因为它们展示了其他人的创意。我们可以在此基础上进行改进,并从他们的努力中学习。没有必要让每个人都重新发明轮子。在 Android 及其复杂的生命周期背景下,存在着设计模式无法解决的问题,但每个人都会面临这些问题。这就是我所说的实用性。 - TWiStErRob

48

Android 上的行为、视图和活动是处理 Android UI 的内置方式,是实现模型-视图-视图模型(MVVM)模式的一种方法,该模式在结构上与模型-视图-控制器相似(同一家族)。

据我所知,没有办法跳出这个模式。虽然可能可以做到,但您很可能会失去现有模式的所有好处,并不得不重写自己的 UI 层使其工作。


31
经过一番搜索,最合理的答案如下:
MVC在Android中已经被实现为:
1. View = 布局、资源和内置类(例如继承自android.view.View的Button)。 2. Controller = Activity。 3. Model = 实现应用程序逻辑的类。
(顺便说一句,在Activity中不包含应用程序域逻辑。)
对于小型开发人员来说,最明智的做法是遵循这种模式,而不是试图做谷歌决定不做的事情。
附注:有时Activity会重新启动,因此不应放置模型数据。(最简单的引起重新启动的方式是从XML中省略android:configChanges="keyboardHidden|orientation"并旋转设备。)
编辑:
我们可能在谈论MVC,但实际上是FMVC (Framework--Model--View--Controller)。框架(Android操作系统)强制实施其组件生命周期及相关事件的概念。在实践中,控制器(Activity/Service/BroadcastReceiver)首先负责处理这些由框架强行引入的事件(如onCreate())。用户输入是否应该分别处理?即使应该,你也无法将它们分开,因为用户输入事件也来自Android。
无论如何,尽可能减少不具体到Android的代码,放在你的Activity/Service/BroadcastReceiver中越好。

5
Activity可以直接访问UI,而在MVC中,控制器不应该知道视图(只有反过来)。 - Konrad Morawski
2
@KonradMorawski 嗯....一个_View_知道关于显示事项___和___关于_Controller_的?例如,Button的子类知道关于_Controller_的?似乎更合理的是_Views_只知道关于显示事项。考虑到_Model_只知道数据的本质,这就是为什么需要_Controller_的原因:某些东西必须同时了解_Model_和_View_。 - 18446744073709551615
4
显然,视图需要了解控制器以便将事件委托给控制器。控制器将此信息传递给模型,并告知视图结果是什么(以便视图可以显示它)。控制器不会膨胀视图(而Activity会),也不应该知道任何关于按钮、文本框、列表等的信息(Activity则知道这些信息)。 - Konrad Morawski
1
我认为“服务”也属于控制器的范畴。 - Jodes
1
听说过观察者模式吗?我发现最好的分离方式是:1. 控制器只有模型实例,2. 模型不知道控制器或视图,但视图可以注册为模型观察者(所以模型有点知道视图,但他不知道是谁,也不关心)- 当模型完成数据加载时,它会通知所有观察者(通常只有一个),3. 视图只有模型实例来提取数据。这样,所有MVC框架只有两个依赖项。我认为2是最小的,因此应该是最佳布局。 - Srneczek
1
顺便提一下 - Activity/Fragment 有点像控制器 + 视图,我认为你应该只将其用作视图,并将控制器从中提取出来。类似于某些 PHP 和可能其他框架(如 Laravel、Symfony...)其中你有一个视图,然后加载“模板”(Smarty、Twig、Blade...)- 这里的 Activity 是视图,XML 是模板。 - Srneczek

18

没有一种固定的MVC模式可供遵循。MVC只是更或少地说明您不应混淆数据和视图,例如,视图负责保存数据或处理数据的类直接影响视图。

但是,Android处理类和资源的方式有时甚至迫使您遵循MVC模式。在我看来,更复杂的是活动,它们有时负责视图,但同时充当控制器。

如果您在XML文件中定义了视图和布局,并从res文件夹加载资源,并且在代码中尽量避免将这些东西混合在一起,则无论如何都是在遵循MVC模式。


15
你可以在Android上实现MVC,但它不是“本地支持”的,并且需要一些努力。
话虽如此,我个人更倾向于MVP作为Android开发的更清晰的架构模式。当我说MVP时,我的意思是这个:

enter image description here

我还在此处发布了更详细的答案。

在尝试多种Android MVC/MVP实现方法后,我提出了一个合理的架构模式,并在这篇文章中进行了描述:Android中的MVP和MVC架构模式


13

我发现实现Android上MVC的最佳资源是这篇文章

我在一个项目中采用了相同的设计,效果很好。我是一个Android初学者,所以不能说这是最好的解决方案。

我做了一个修改:我在应用程序类中为每个活动实例化模型和控制器,以便在横竖屏模式更改时不会重复创建它们。


9
如有一天该文章被删除,能够获得摘要就太好了。 - pqsk
1
链接页面对我来说什么也没有显示。 - Thomas S.
Webarchive来拯救 https://web.archive.org/web/20200719232657/http://www.therealjoshua.com/2011/11/android-architecture-part-1-intro/ - Hervé Donner

12

Android中的MVC架构 在android中最好遵循任何形式的MVP而不是MVC。但是根据问题的答案,这也可以是一种解决方案。

输入图像描述

描述和指南

     Controller -
        Activity can play the role.
        Use an application class to write the
        global methods and define, and avoid
        static variables in the controller label
    Model -
        Entity like - user, Product, and Customer class.
    View -
        XML layout files.
    ViewModel -
        Class with like CartItem and owner
        models with multiple class properties
    Service -
        DataService- All the tables which have logic
        to get the data to bind the models - UserTable,
        CustomerTable
        NetworkService - Service logic binds the
        logic with network call - Login Service
Helpers -
        StringHelper, ValidationHelper static
        methods for helping format and validation code.
SharedView - fragmets or shared views from the code
        can be separated here

AppConstant -
        Use the Values folder XML files
        for constant app level

注意 1:

现在你可以做一些奇妙的事情。一旦你分类了代码段,就像 IEntity 和 IService 这样编写一个基本接口类,声明通用方法。然后创建抽象类 BaseService,并声明自己的一组方法并分离代码。

注意 2:如果您的活动需要呈现多个模型,则最好将视图分割成片段而不是在活动中编写代码/逻辑。这样以后如果需要在视图中显示更多模型,则只需添加一个新的片段即可。

注意 3:代码的分离非常重要。体系结构中的每个组件都应该是独立的,没有依赖于逻辑。如果您有一些依赖逻辑,那么请在中间编写映射逻辑类。这将帮助您处理未来的问题。


12

我同意JDPeckham的观点,认为仅使用XML是不足以实现应用程序的UI部分。

然而,如果您将Activity视为视图的一部分,则实现MVC相当简单。您可以重写Application(在Activity中通过getApplication()返回),并在这里创建一个控制器,该控制器在应用程序的生命周期内都存在。

(或者您可以使用Application文档中建议的单例模式)


11

7
链接失效了,先生。 - Rat-a-tat-a-tat Ratatouille
2
似乎这个COSC346-lab2.2up.pdf文件没有包含完整的细节。 - james

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接