关于java:Android上的MVC模式

MVC pattern on Android

有可能在Java中实现Android的模型-视图-控制器模式吗?

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


在Android中,您没有MVC,但您有以下功能:

  • 您可以通过分辨率、硬件等在各种XML文件中定义用户界面。
  • 您可以根据区域设置等在各种XML文件中定义资源。
  • 扩展了listactivity、tabactivity等分支,并通过膨胀器使用XML文件。
  • 您可以为您的业务逻辑创建任意多的类。
  • 已经为您编写了很多实用程序-databaseutils,html。


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

  • 模型:渲染内容
  • 视图:如何渲染
  • 控制器:事件,用户输入

也可以这样考虑:当您编程模型时,模型不需要担心渲染(或特定于平台的代码)。模型会对视图说,我不在乎你的渲染是Android还是iOS或Windows手机,这是我需要你渲染的。视图将只处理平台特定的呈现代码。

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


android上的操作、视图和活动是与android用户界面一起工作的一种成熟方式,是model–view–viewmodel(MVVM)模式的实现,该模式在结构上与model–view–controller相似(在同一系列中)。

据我所知,没有办法打破这种模式。它可能是可以做到的,但是您可能会失去现有模型所具有的所有好处,并且必须重写您自己的UI层才能使其工作。


经过一些调查,最合理的答案是:

MVC已经在Android中实现,如下所示:

  • VIEW=从android.view.View派生的布局、资源和内置类,如Button
  • 控制器=活动
  • 模型=实现应用程序逻辑的类
  • (顺便说一下,这意味着活动中没有应用程序域逻辑。)

    对于一个小开发者来说,最合理的做法是遵循这个模式,而不是尝试去做谷歌决定不做的事情。

    PS注意,活动有时会重新启动,因此它不适合模型数据(导致重新启动的最简单方法是从XML中省略android:configChanges="keyboardHidden|orientation",然后转动设备)。

    编辑

    我们可能在讨论MVC,但也可以这样说,fmvc,framework——model——view——controller。框架(android OS)引入了组件生命周期和相关事件的概念,在实践中,控制器(Activity/Service/BroadcastReceiver首先负责处理这些框架强制事件(如oncreate())。是否应单独处理用户输入?即使它应该,你也不能分离它,用户输入事件也来自Android。

    不管怎样,你在你的ActivityServiceBroadcastReceiver中输入的不是Android专用的代码越少越好。


    没有一个MVC模式可以遵循。MVC只是或多或少地声明,您不应该将数据和视图混合在一起,因此,例如,视图负责保存处理数据的数据或类,这些数据或类直接影响视图。

    但是,尽管如此,Android处理类和资源的方式,有时甚至被迫遵循MVC模式。在我看来,更复杂的是一些活动,这些活动有时对观点负责,但同时又充当控制者。

    如果在XML文件中定义视图和布局,从res文件夹中加载资源,并且避免在代码中或多或少地混合这些内容,那么您仍然遵循MVC模式。


    您可以在Android中实现MVC,但它不是"本机支持的",需要付出一些努力。

    也就是说,我个人倾向于将MVP作为Android开发中更清洁的架构模式。我说的MVP是指:

    enter image description here

    我也在这里发布了更详细的答案。

    在学习了Android中MVC/MVP实现的各种方法之后,我想出了一个合理的体系结构模式,我在本文中描述了这个模式:Android中的MVP和MVC体系结构模式。


    我发现在Android上实现MVC的最佳资源是:

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

    我做了一个修改:我为应用程序类中的每个活动实例化了模型和控制器,这样在横向纵向模式更改时就不会重新创建这些活动。


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

    但是,如果您将活动视为视图的一部分,那么实现MVC非常简单。您可以覆盖应用程序(由活动中的getApplication()返回),在这里您可以创建一个控制器,该控制器在应用程序的生命周期中一直存在。

    (或者,您可以使用应用程序文档建议的单例模式)


    使用布局、资源、活动和意图创建Android UI是MVC模式的一种实现。有关更多信息,请参阅以下链接-http://www.cs.otago.ac.nz/cosc346/labs/cosc346-lab2.2up.pdf

    PDF镜像


    MVC-安卓系统架构最好是在Android中跟随任何MVP而不是MVC。但根据问题的答案,这是可以解决的

    Enter image description here

    说明和指南

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
         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:代码分离非常重要。体系结构中的每个组件都应该是独立的,没有依赖逻辑。如果您偶然拥有某个依赖逻辑,那么在这两者之间编写一个映射逻辑类。这将在将来帮助你。


    Android的MVC模式是通过它们的适配器类实现的。它们将控制器替换为"适配器"。适配器说明如下:

    An Adapter object acts as a bridge between an AdapterView and the
    underlying data for that view.

    我只是在为一个从数据库读取的Android应用程序研究这个问题,所以我还不知道它有多好用。然而,这看起来有点像qt的模型-视图-委托体系结构,他们声称这是从传统的MVC模式中迈出的一步。至少在PC上,qt的模式工作得相当好。


    虽然这篇文章看起来很老,但我想增加以下两个内容来介绍Android在这一领域的最新发展:

    android绑定-提供一个框架,支持将android视图小部件绑定到数据模型。它有助于在Android应用程序中实现MVC或MVVM模式。

    机器人-机器人将猜测从发展中去掉。注入视图、资源、系统服务或任何其他对象,让roboguice负责细节。


    模型视图控制器(MVC)

    enter image description here

    描述:

    • 当我们必须在软件开发中主要进行大型项目时,MVC通常使用,因为它是组织项目。
    • 新开发人员可以快速适应项目
    • 帮助开发大型项目和跨平台。

    MVC模式本质上是这样的:

    • 模型:显示什么。这可以是数据源(例如:服务器、原始应用程序中的数据)
    • 视图:显示方式。这可以是XML。因此,它是演示文稿筛选器。视图附着到其模型(或模型零件)上。并获取演示所需的数据。
    • 控制器:处理用户输入等事件。这就是活动

    MVC的重要特性:我们可以修改模型或视图或控制器,但不影响其他模型或视图或控制器。

    • 假设我们改变了视图中的颜色、视图的大小或位置的观点。这样做不会影响模型或控制器
    • 假设我们更改模型(而不是从服务器获取数据从资产中获取数据)但它不会影响视图和控制器
    • 假设我们改变控制器(活动中的逻辑),它不会影响模型和视图


    我认为最有用的简化解释如下:http://www.cs.otago.ac.nz/cosc346/labs/cosc346-lab2.2up.pdf

    从我在这里看到和阅读的所有其他东西来看,实现所有这些东西会使它变得更加困难,并且不适合Android的其他部分。

    让活动实现其他侦听器已经是标准的Android方式。最无害的方法是添加像幻灯片描述的Java观察器,并将OnClash和其他类型的动作分组到仍然在活动中的函数中。

    Android的方式是,活动同时执行这两种操作。与之抗争并不能真正使扩展或将来的编码变得更容易。

    我同意第二个职位。它已经实现了,只是不像人们习惯的那样。不管它是否在同一个文件中,已经有了分离。不需要创建额外的分隔来使其适合其他语言和操作系统。


    令人惊讶的是,这里没有一个帖子回答了这个问题。它们要么过于笼统、含糊、不正确,要么没有在Android中解决实现问题。

    在MVC中,视图层只知道如何显示用户界面(UI)。如果需要任何数据,它将从模型层获取。但是视图并不直接要求模型查找数据,而是通过控制器来查找数据。因此,控制器调用模型为视图提供所需的数据。一旦数据准备就绪,控制器就会通知视图数据已准备好从模型中获取。现在视图可以从模型中获取数据。

    该流程总结如下:

    enter image description here

    值得注意的是,视图可以通过控制器(也称为被动MVC)了解模型中数据的可用性,也可以通过向模型中的数据(即主动MVC)注册观测值来观察模型中的数据。

    在实现部分,首先想到的一件事是,应该为视图使用什么Android组件?ActivityFragment是什么?

    答案是它不重要,两者都可以使用。视图应该能够在设备上显示用户界面(UI),并响应用户与UI的交互。ActivityFragment都为此提供了所需的方法。

    在本文中使用的示例应用程序中,我将Activity用于视图层,但也可以使用Fragment

    完整的示例应用程序可以在我的Github回购的"MVC"分支中找到。

    我还通过这里的一个例子讨论了Android中MVC架构的优缺点。

    对于那些感兴趣的人,我在这里开始了一系列关于Android应用程序体系结构的文章,其中我通过一个完整的工作应用程序比较了不同的体系结构,即MVC、MVP、MVVM,以便开发Android应用程序。


    厌倦了Android上的MVX灾难,我最近制作了一个提供单向数据流的小型库,类似于MVC的概念:https://github.com/zserge/anvil

    基本上,您有一个组件(活动、片段和视图组)。在内部定义视图层的结构和样式。还可以定义数据应如何绑定到视图。最后,您可以在同一个地方绑定侦听器。

    然后,一旦您的数据被更改,将调用全局"render()"方法,并且您的视图将被最新的数据智能更新。

    下面是一个组件的例子,其中包含代码紧凑性的所有内容(当然,模型和控制器可以很容易地分离)。这里"count"是一个模型,view()方法是一个视图,"v->count++"是一个控制器,它监听按钮的点击并更新模型。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public MyView extends RenderableView {
      public MyView(Context c) {
          super(c);
      }

      private int count = 0;

      public void view() {
        frameLayout(() -> {              // Define your view hierarchy
          size(FILL, WRAP);
          button(() -> {
              textColor(Color.RED);      // Define view style
              text("Clicked" + count);  // Bind data
              onClick(v -> count++);     // Bind listeners
          });
        });
      }

    对于分离的模型和控制器,它看起来像:

    1
    2
    3
    4
    5
    button(() -> {
       textColor(Color.RED);
       text("Clicked" + mModel.getClickCount());
       onClick(mController::onButtonClicked);
    });

    在这里,单击每个按钮,数字将增加,然后调用"render()",按钮文本将更新。

    如果您使用kotlin:http://zserge.com/blog/anvil-kotlin.html,语法会变得更令人愉快。另外,没有LAMBDAS的Java还有替代语法。

    库本身非常轻,没有依赖项,不使用反射等。

    (免责声明:我是这个图书馆的作者)


    没有实现的MVC体系结构,但存在一组库/示例来实现MVP(模型-视图-演示者)体系结构。

    请检查以下链接:

    • https://github.com/sockeqwe/mosby网站

    • https://github.com/android10/android-cleansarchitecture

    • https://github.com/antoniolg/androidmvp

    谷歌增加了一个Android架构MVP的例子:

    • https://github.com/googlesamples/android-architecture

    我已经看到很多人说MVC已经在Android中实现了,但事实并非如此。默认情况下,Android不遵循MVC。

    因为我不认为谷歌会强制实施像iPhone这样的MVC实现的限制,但这取决于开发人员在他们的项目中需要什么样的模式或技术,在小型或简单的应用中,不需要使用MVC,但随着应用程序的增长和复杂化,需要在以后的ye中修改其代码。ARS,然后需要在Android中使用MVC模式。

    它提供了一种修改代码的简单方法,也有助于减少问题。如果你想在Android上实现MVC,那么遵循下面给出的链接,在你的项目中享受MVC的实现。

    http://www.therealjohua.com/2011/11/android-architecture-part-1-简介/

    但现在,我认为MVP和Android体系结构模式是开发人员应该用于干净、健壮的Android应用程序的最佳选择之一。


    根据Xamarin团队解释的解释(在iOS MVC上,"我知道这很奇怪,但是等一下"):

    • 模型(数据或应用程序逻辑);
    • 视图(用户界面),以及
    • 控制器(代码隐藏)。

    我可以这样说:

    Android上的模型只是Parcelable对象。视图是XML布局,控制器是(活动+其片段)。

    *这只是我的观点,不是来自任何资源或书籍。


    当我们将MVC、MVVM或表示模型应用于Android应用程序时,我们真正想要的是拥有一个清晰的结构化项目,更重要的是更容易进行单元测试。

    目前,如果没有第三方框架,通常会有很多代码(如addxListener()、findViewByID()等),这些代码不会增加任何业务价值。

    更重要的是,你必须运行Android单元测试,而不是普通的JUnit测试,这需要很长的时间来运行,使单元测试有些不切实际。出于这些原因,几年前我们开始了一个开源项目robobinding,一个面向Android平台的数据绑定表示模型框架。

    robobinding帮助您编写更易于阅读、测试和维护的UI代码。robobind消除了不必要的代码(比如addxxlistener)的需要,并将UI逻辑转换为表示模型,这是一个POJO,可以通过普通的JUnit测试进行测试。Robobinding本身有300多个JUnit测试,以确保其质量。