基于安卓的移动课堂应用开发毕业论文(编辑修改稿)内容摘要:

MVC ( ModelViewController)模式了。 从 Smalltalk 时代开始, MVC 便被用来创建用户界面。 在 MVC 模式里,共包含三种类型的对象,模型 Model 是应用对象,视图 View 用于向用户展示,而控制器 Controller 定义了 View 对于用户输入的响应方式。 不使用 MVC 时,用户界面设计往往将这些对象混杂在一起,不利于提供设计的灵活性和复用性。 MVC 通过同时使用观察者模式和 策略模式分离视图和模型,同时提供对不同 UI 逻辑的支持。 同时建立一个“订阅 /通知”协议,视图和模型彼 此分离。 视图必须保证它的显示正确地反映了模型的状态。 一定模型发送了变化,它也将通知视图,从而,视图可以以此作为契机,更新对应的 UI。 模型的变更传播机制确保应用程序的数据发生变化时,所有的观察者将在正确的时间得到通知。 这让所有依赖于模型的视图和控制器得以同步。 这种方法 还 可以让你为一个模型提供不同的多个视图的表现形式,为能够为一个模型创建新的视图而无需重写模型。 在运行阶段,可同时打开多个视图(共享一个 model),还可以动态地打开和关闭视图。 图 MVC 模式 8 而对于 View 和 Controller, 则是策略模式的一个例子。 一个策略表示一个算法族的一个对象。 通过定义一个算法族,我们可以动态或静态地替换对应的策略。 而策略的使用者 —— 这里的视图,则完全不受影响。 通过将模型、视图和控制器分离,可更换模型的视图和控制器,甚至在运行阶段都可以替换用户界面。 但是,对于当今的移动开发, MVC 模式又有一些显著的不足。 首先, MVC 三个组件存在着一个环状的依赖关系。 也就是说,一个组件接口的变化,必将同时影响另外两个组件。 不仅如此,环状依赖也提高了单元测试的难度。 同一时间,如果我们想对一个组件进行测试,必 须提供两个 mock 对象。 此外,视图和控制器的关系过于紧密。 控制器和视图虽然分开了,但关系紧密,这导致无法分别重用它们。 不仅如此,视图和控制器与模型也是紧耦合的。 视图和控制器都直接调用模型,这意味着修改模型的接口将破坏视图和控制器的代码。 一种变体 —— MVP 模式 由于上述 MVC 模式的一系列问题,加之其诱人的优点,于是, 便 有了它的一个变体 —— MVP 模式。 MVP 作为一个面向用户界面设计的架构模式,被刻意设计,以充分利用一些自动化单元测试工具并且改善表现逻辑分离的问题。 图 MVP 模式 在 MVP 模式中,模型 Model 组件提供了一个定义用于展示的数据的接口,并根据用户的动作做出相应的处理逻辑。 这里的 Model 和 MVC 中的 Model 并没有什么差异。 9 而表现者 Presenter 则 作为一个中间人的角色而存在,所有的表现逻辑都存在于表现者Presenter 中。 它从 Model 中取得数据,并对它进行格式化,然后在 View 中展示。 所以, Presenter 也因此有了另一个名称 —— 超级控制器。 对于最后的 View 组件,这里我们称它为被动视图。 视图并不主动处理 UI 的更新和用户动 作,它所做的,就是非常单一的功能 —— 展示用户界面。 视图的更新由 Presenter 复制,对于用户的动作,它也是直接转发至 Presenter 中。 实际上,对于视图所处理的逻辑的多少,每个不同的实现都不尽相同。 在一个极端,视图是一个完全的被动式的存在,将所有的用户操作都转发至 Presenter 中。 在这种情况下,当用户触发 View 组件的一个事件回调时,它不会做任何的处理,而仅仅是调用presenter 的一个没有参数也没有返回值的方法。 然后, Presenter 通过 View 组件的接口,取出必需的数据。 最 后, Presenter 操作 Model 组件,得到结果后又相应地更新 UI。 而在另一方面,某些实现却运行 View 组件处理某些特定的事件、操作或命令。 这通常更适用于基于 web 的架构,这种情况下, View 组件通常运行在用户的浏览器中,所以,对于一些交互命令, View 组件是一个更好的处理场所。 MVP 模式与 MVC 模式最大的不同在于, MVP 并不存在环状依赖,取而代之,MVP 是链状的依赖关系。 这使得 MVP 更加地适合于单元测试。 同时,由于 Presenter 的存在,即便 Model 的接口发生变化 ,我们也只需要修改 Presenter —— 我们的 View 组件,依然可以继续使用而不需要做任何的修改。 而对于 MVC 的优点,在这里也同样保持着。 我们的 UI 和逻辑是显著分离的,组件也可以复用。 如果交换逻辑需要作出修改,也可以通过替换 Presenter 这个组件而得到所需的效果。 同时,这里的 Presenter 也是作为一个策略而存在的,这意味着,我们可以在运行时动态地更换表现逻辑。 遗憾的是, MVP 也有其缺点。 前面我们说 MVP 是链状依赖的时候,敏锐的你就应该意识到,我们的调用链过长了。 即使是 Model 中的一个小小的改变,也要跨过千山万水才能够表现在 UI 上。 也就是说,与 MVC 相比,对于性能很关心的应用,这个模式可能就不太适用了。 所幸的是,这种情况发生的几率实在太低,所以一般不会是太大的问题。 而更为致命的是,作为超级控制器的 Presenter, 对于 UI 的所有更新都要经手的它,实现中往往存在很多的盲转发。 大多数时候,我们根本不需要对数据进行格式化,只是从 Model 取出,然后直接应用于 View 组件的更新。 编写这么 多的 盲转发代码,可不会是一件愉快的事。 10 更进一步 —— MVVM 模式 前面 我们提到 MVP 模式中,将数据显示到 View 组件通常是一件比较无趣而繁琐的工作。 而 MVVM( ModelViewViewModel) 的出现,就是为了解决这么一个问题。 MVVM 同样是对图形用户界面与应用逻辑的分离。 它通过一种标记语言或 GUI 代码,将 UI 与商业逻辑或后台逻辑分离开。 MVVM 中的 View Model 组件是一个值转换器;这意味着 View Model 的职责是从将 Model 类得来的数据对象进行转化,使之更易于管理和表现。 从这一点看, View Model 比 View 组件更加的模型化 ,并处理着几乎所有的视图表现逻辑。 View Model 可以使用中间人模式进行实现,它处理 View 所支持的所有 对后端逻辑的访问 控制。 ModelViewViewModel 也叫 ModelViewBinder, 因为对 View 组件的更新,我们通常通过一些自动化的工具进行,也就是所谓的 data binding。 图 MVVM 模式 从组件的依赖关系上看, MVVM 和 MVP 非常地相似,唯一的不同是, MVP 里,我们程序员自己手动执行了一个所谓 data binding 的动作。 Model 组件也叫 domain model ,与 MVC 和 MVP 中的 Model 一样,这里用于表现业务逻辑,并提供应用数据的存取。 View 组件也是,作为一个用户界面而存在。 View Model 是 View 组件的一个抽象表示,用于暴露其公开的接口。 与 MVC 中的 Controller 和 MVP 中的 Presenter 不同的是, MVVP 有一个 binder。 在 View Model 中, binder 调节 着 View 和 View Model 的通信。 声明式的对数据、命令和 UI 的绑定在 MVVM 模式中是隐式的。 Binder 将开发者从手工编写大量模板代码解放出来。 11 毫无例外, MVVM 也有其缺点。 对简单的应用而已,这样的框架无意过于的厚重。 而对于复杂的交互逻辑,靠程序 ( binder) 进行自动的数据绑定又显得过于的力不从心。 使用 MVVM 时,我们得自行拿捏一个中庸之道。 回归简朴 —— DocumentView 模式 MVC 存在着环状依赖, MVP 调用链过长, MVVM 对简单应用过于复杂,对复杂应用支持又不足,那么,我们又应该选择哪一个模式呢。 回想前面我们讨论过的问题,我们需要的是 UI 和逻辑分离,需要它足 够的轻量,并具有相当的可扩展性。 它只解决最为迫切,一直重复发生着的问题。 那么,这样的架构模式存不存在呢。 答案是,存在,它就是所谓的 DocumentView 模式。 图 DocumentView 模式 DocumentView 也是属于 MVC 变体的一种。 这里的 View ,和 MVC 中的 View并没有什么显著的差别, 同样的用于向用户展示信息和提供交互。 而 Document 则相当于 Model 和 Controller 的结合,或者说, MVP 模式中的 Model 和 Presenter。 使用 DocumentView 模式的最为著名的架构,应该就属微软的 MFC 框架了。 默认情况下, MFC 的项目生成向导会生成两个类 —— Document 类和 View 类。 Document 负责管理数据并更新 View, View 组件则用于向用户展示数据和提供交互功能。 这就是我们所需要的最基本的 UI 和应用逻辑分离。 但是,如果仅仅是 UI 和逻辑分离,并不足以使我们选择这么一个架构。 选择DocumentView, 还有着更多的理由。 对于绝大多数的 Android 应用,一个 Model 仅仅对应一个 View, 我们并没有不需要 MVC 同步更新多个 View 组件的功能。 如果使用 MVC, 却要因此忍受它带来的环状依赖。 可以说, MVC 并不适用于 Android 应用的开发。 MVP 有着过长的调用链,无论是从 View 到 Model 还是从 Model 到 View, 我们不12 想要这些额外的消耗。 对于性能非常重要的应用而已,中间的 Presenter 是不能忍受的。 此外,很多时候,中间的 Presenter 并没有做太大有用的工作,它只是单纯地将View 和 Model 的调用相互转发而已。 对于 MVVM, 不使用他的原因和上面 所述的它的缺点一样。 在简单的应用表现不佳,复杂的应用却有力不从心。 最为重要的一点是,由于它们都是基于 UI 和逻辑分离的原则所设计的,四个模式都有其共通的地方。 而对于最简单的 DocumentView, 它提供了最为基本的 UI 分离的支持,使用它,在合适的场合,我们可以轻易对它进行扩展,以增强为其他模式。 假定我们现在的 UI 交换逻辑过于的复杂, DocumentView 已经无法满足我们的需求。 此时,我们可以对 DocumentView 进行扩展,使之成为一个 MVP 模 式。 需要注意的一点是,尽管此时已经变化为 MVP 模式,但我们还是重用了低层 DocumentView 框架的实现。 图 将 DocumentView 扩展为 MVP 模式 增强的 DocumentView 在前面我们描述模式的时候,我们通常都只是说“ View”,“ Model” 等等。 即便我们使用这样的术语,但是,这并不意味着,各个组件是在和实体的类进行交谈。 这里“ View”, 并不特指某个具体的实现,它完全可以是一个接口。 目前 Android 的 Native 应用主要是使用 Java 进行 开发的,利用 Java 的语言特性,我们完全可以做得更好。 13 图 增强的 DocumentView 这里的 I 指的是 Interface, 并且,这里的 interface 并不指一般意义上的接口,而是指 Java 语言的一个语法“ interface”。 组件并不互相直接就进行通信,而是通过引用一句接口。 通过针对接口进行编程,我们保留了对组件进行透明替换的能力。 双方通过接口进行引用, 使得在利用对方提供的接口时 ,只能使用接口所提供的抽象,这大大减少了需要同时关注的问题,很好地隔离了复杂度。 接口提供了一 个语言级的支持,可以实现安全、透明的实现替换。 我们并不关心 View 和 Document 的实际类型是什么,我们只知道,那个类实现了我们所需的接口。 只有实现对应的接口,我们就可以对一个组件进行直接的替换,而另一个组件则完全不用更改。 甚至,与 MVC、 MVP 等提供的动态性一样,我们也可以在运行时动态地选择 View 和 Document 的实现。 定义接口的过程中,可以迫使我们对组件所需要提供的功能进行细致的考虑。 通过对业务进行分析并制定接口,可以避免在尚不清楚逻辑的情况下过快地进行编程。 同时,它也可以帮助我们理 清应用的逻辑。 还应注意的是,接。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。