本章擴展了 GeoQuiz 程序,并介紹了 MVC 設計模式
GitHub 地址 :
GeoQuiz 第二章未完成挑戰(zhàn)
GeoQuiz 完成第二章所有挑戰(zhàn)
1. MVC 設計模式
Android 應用基于模型-控制器-視圖(Model - View - Controller, MVC)的架構模式進行設計。MVC 設計模式表明:應用的任何對象,歸根結底都屬于模型對象、視圖對象以及控制對象中的一種。
模型對象存儲著應用的數(shù)據(jù)和業(yè)務邏輯。
模型類通常用來映射與應用相關的一些事物,如 用戶、商店里的商品、服務器上的圖片或者一段電視節(jié)目;又或是 GeoQuiz 應用里的地理知識問題。
模型對象不關心用戶界面,它存在的唯一目的就是存儲和管理應用數(shù)據(jù)。
** Android 應用里的模型類通常就是我們創(chuàng)建的定制類。應用的全部模型對象組成了模型層。**視圖對象知道如何在屏幕上繪制自己以及如何響應用戶的輸入,如用戶的觸摸等。
一個簡單的經(jīng)驗法則是,凡是能夠在屏幕上看見的對象,就是視圖對象。Android 默認自帶了很多可配置的視圖類。當然,也可以定制開發(fā)自己的視圖類。應用的 全部視圖對象組成了視圖層。控制對象含有應用的邏輯單元,是視圖與模型對象的聯(lián)系紐帶。
控制對象響應視圖對象 觸發(fā)的各類事件,此外還管理著模型對象與視圖間的數(shù)據(jù)流動。 在 Android 的世界里,控制器通常是 Activity 、Fragment 或 Service 的一個子類。
MVC 模式圖
上圖展示了在響應用戶單擊按鈕等事件時,對象間的交互控制數(shù)據(jù)流。注意,模型對象與 視圖對象不直接交互??刂破髯鳛樗鼈冎g的聯(lián)系紐帶,接收對象發(fā)送的消息,然后向其他對象發(fā)送操作指令。
隨著應用功能的持續(xù)擴展,應用往往會變得過于復雜而讓人難以理解。把 Java 類以模型、視圖和控制層進行分類組織,也有助于我們設計和理解應用。這樣,我們就可以按層而非一個個類來考慮設計開發(fā)了。
使用 MVC 模式還可以讓類的復用更加容易。相比功能多而全的類,功能單一的專用類更加有利于代碼復用。
盡管 GeoQuiz 應用不復雜,但以 MVC 分層模式設計它的好處還是顯而易見的。舉例來說,模型類 Question 與用作顯示問題的組件毫無代碼邏輯關聯(lián)。這樣,就很容易在應用里按需使用 Question 類。假設現(xiàn)在想顯示所有地理知識問題列表,很簡單,直接復用 Question 對象逐條顯示就可以了。
2. 具體實現(xiàn)
- GeoQuiz 的模型層由 Question 類組成。
- GeoQuiz 應用的視圖層是由 activity_quiz.xml 文件中定義的各類組件構成的。
- GeoQuiz 應用的控制層僅由 QuizActivity 類組成。
構建模型層 Question 類,成員有文本的資源 ID 變量 mTextResId 和標記問題答案是否正確的 mAnswerTrue 變量。重寫構造方法,添加了兩個成員變量的 Getter 與 Setter 函數(shù)。
Tip: 如何在 Android Studio 中優(yōu)雅地生成 Getter 和 Setter
使用快捷鍵 Cmd + N
- 修改視圖層,增加 Next 按鈕。
修改控制層,增加題目庫 mQuestionBank 數(shù)組、 updateQuestion() 函數(shù)與 checkAnswer() 函數(shù)。并完成實現(xiàn)邏輯
添加箭頭的圖標資源放在 Next 按鈕右側。
3. 挑戰(zhàn)
本章挑戰(zhàn)的難度較低,難點主要在于添加 Prev 按鈕時要注意數(shù)組越界的問題??梢杂幸韵聨追N實現(xiàn):
- 單獨拎出越界的情況
if (mCurrentIndex == 0) {
mCurrentIndex = mQuestionBank.length - 1;
} else {
mCurrentIndex = mCurrentIndex - 1;
}
updateQuestion();
- 直接避免越界情況
mCurrentIndex = (mCurrentIndex + mQuestionBank.length - 1) % mQuestionBank.length;
GitHub Page: kniost.github.io
簡書:http://www.itdecent.cn/u/723da691aa42