本章擴(kuò)展了 GeoQuiz 程序猾担,并介紹了 MVC 設(shè)計(jì)模式
GitHub 地址 :
GeoQuiz 第二章未完成挑戰(zhàn)
GeoQuiz 完成第二章所有挑戰(zhàn)
1. MVC 設(shè)計(jì)模式
Android 應(yīng)用基于模型-控制器-視圖(Model - View - Controller, MVC)的架構(gòu)模式進(jìn)行設(shè)計(jì)袭灯。MVC 設(shè)計(jì)模式表明:應(yīng)用的任何對象,歸根結(jié)底都屬于模型對象绑嘹、視圖對象以及控制對象中的一種稽荧。
模型對象存儲(chǔ)著應(yīng)用的數(shù)據(jù)和業(yè)務(wù)邏輯。
模型類通常用來映射與應(yīng)用相關(guān)的一些事物工腋,如 用戶蛤克、商店里的商品、服務(wù)器上的圖片或者一段電視節(jié)目夷蚊;又或是 GeoQuiz 應(yīng)用里的地理知識問題构挤。
模型對象不關(guān)心用戶界面,它存在的唯一目的就是存儲(chǔ)和管理應(yīng)用數(shù)據(jù)惕鼓。
** Android 應(yīng)用里的模型類通常就是我們創(chuàng)建的定制類筋现。應(yīng)用的全部模型對象組成了模型層。**視圖對象知道如何在屏幕上繪制自己以及如何響應(yīng)用戶的輸入箱歧,如用戶的觸摸等矾飞。
一個(gè)簡單的經(jīng)驗(yàn)法則是,凡是能夠在屏幕上看見的對象呀邢,就是視圖對象洒沦。Android 默認(rèn)自帶了很多可配置的視圖類。當(dāng)然价淌,也可以定制開發(fā)自己的視圖類申眼。應(yīng)用的 全部視圖對象組成了視圖層瞒津。控制對象含有應(yīng)用的邏輯單元,是視圖與模型對象的聯(lián)系紐帶括尸。
控制對象響應(yīng)視圖對象 觸發(fā)的各類事件巷蚪,此外還管理著模型對象與視圖間的數(shù)據(jù)流動(dòng)。 在 Android 的世界里濒翻,控制器通常是 Activity 屁柏、Fragment 或 Service 的一個(gè)子類。
上圖展示了在響應(yīng)用戶單擊按鈕等事件時(shí)有送,對象間的交互控制數(shù)據(jù)流淌喻。注意,模型對象與 視圖對象不直接交互雀摘÷闵荆控制器作為它們之間的聯(lián)系紐帶,接收對象發(fā)送的消息届宠,然后向其他對象發(fā)送操作指令烁落。
隨著應(yīng)用功能的持續(xù)擴(kuò)展,應(yīng)用往往會(huì)變得過于復(fù)雜而讓人難以理解豌注。把 Java 類以模型伤塌、視圖和控制層進(jìn)行分類組織,也有助于我們設(shè)計(jì)和理解應(yīng)用轧铁。這樣每聪,我們就可以按層而非一個(gè)個(gè)類來考慮設(shè)計(jì)開發(fā)了。
使用 MVC 模式還可以讓類的復(fù)用更加容易齿风。相比功能多而全的類药薯,功能單一的專用類更加有利于代碼復(fù)用。
盡管 GeoQuiz 應(yīng)用不復(fù)雜救斑,但以 MVC 分層模式設(shè)計(jì)它的好處還是顯而易見的童本。舉例來說,模型類 Question 與用作顯示問題的組件毫無代碼邏輯關(guān)聯(lián)脸候。這樣穷娱,就很容易在應(yīng)用里按需使用 Question 類。假設(shè)現(xiàn)在想顯示所有地理知識問題列表运沦,很簡單泵额,直接復(fù)用 Question 對象逐條顯示就可以了。
2. 具體實(shí)現(xiàn)
- GeoQuiz 的模型層由 Question 類組成携添。
- GeoQuiz 應(yīng)用的視圖層是由 activity_quiz.xml 文件中定義的各類組件構(gòu)成的嫁盲。
- GeoQuiz 應(yīng)用的控制層僅由 QuizActivity 類組成。
構(gòu)建模型層 Question 類烈掠,成員有文本的資源 ID 變量 mTextResId 和標(biāo)記問題答案是否正確的 mAnswerTrue 變量羞秤。重寫構(gòu)造方法缸托,添加了兩個(gè)成員變量的 Getter 與 Setter 函數(shù)。
Tip: 如何在 Android Studio 中優(yōu)雅地生成 Getter 和 Setter
使用快捷鍵 Cmd + N
- 修改視圖層锥腻,增加 Next 按鈕嗦董。
修改控制層母谎,增加題目庫 mQuestionBank 數(shù)組瘦黑、 updateQuestion() 函數(shù)與 checkAnswer() 函數(shù)。并完成實(shí)現(xiàn)邏輯
添加箭頭的圖標(biāo)資源放在 Next 按鈕右側(cè)奇唤。
3. 挑戰(zhàn)
本章挑戰(zhàn)的難度較低幸斥,難點(diǎn)主要在于添加 Prev 按鈕時(shí)要注意數(shù)組越界的問題∫龋可以有以下幾種實(shí)現(xiàn):
- 單獨(dú)拎出越界的情況
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.reibang.com/u/723da691aa42