1. 事前準備
在這個課程中,您已瞭解一般內容、不同類型的類別、集合和高階函式。善用所學的內容,您將可以協助團隊改善全新的事件追蹤應用程式。每個步驟的操作說明描述了應用程式目前的狀態,以及您應該要完成的任務。
建議使用 Kotlin Playground 來解決這些練習的問題。
必要條件
軟硬體需求
- 可上網的電腦
- 使用 Kotlin Playground
2. 應用程式總覽
您是事件追蹤應用程式團隊中最新的軟體工程師。這款應用程式的目的在於讓使用者可以追蹤自己的事件。您的團隊會為您指派任務,協助您建構應用程式的功能。
每項任務結束時,請比較您的解決方案與我們提供的解決方案。達到想要功能的方法有很多種,因此,如果您的程式碼與提供的解決方案程式碼不完全相同,請不用擔心。
使用上一項任務中提供的解決方案程式碼,做為下一個任務的起始程式碼,以便從相同的起點著手。
3. 任務 1
其他軟體工程師已經完成應用程式部分概略的工作,而您則負責實作相關細節。
您必須實作 Event
類別。這個類別可用來保存使用者輸入的事件詳細資料。(提示:這個類別無須定義任何方法或執行任何動作)。
這項任務需要建立一個名為 Event
的資料類別。
這個類別的執行個體應要可以儲存:
- 以字串的形式儲存事件標題。
- 以字串的形式儲存事件說明 (可以是空值)。
- 以字串的形式儲存事件時段。我們只需追蹤事件是在早上、下午還是晚上發生。
- 以分鐘 (整數) 為單位儲存事件時間長度。
在繼續往下之前,請試著自行撰寫程式碼。
使用程式碼,利用以下資訊建立執行個體:
- 標題:學習 Kotlin
- 說明:每天至少投入 15 分鐘學習 Kotlin。
- 時段:晚上
- 時間長度︰15 分鐘
請嘗試列印物件,確認是否得到以下輸出內容:
Event(title=Study Kotlin, description=Commit to studying Kotlin at least 15 minutes per day., daypart=Evening, durationInMinutes=15)
完成任務或盡可能嘗試完成任務後,請點選「下一步」,瞭解我們如何編寫程式碼。
4. 任務 1 解決方案
您的解決方案程式碼應該是類似這樣的寫法:
data class Event(
val title: String,
val description: String? = null,
val daypart: String,
val durationInMinutes: Int,
)
5. 任務 2
為了保持專案進度,您的主管決定使用我們提供的資料類別程式碼。
您的團隊成員在使用 Event
類別一段時間後,資深團隊成員發現以字串的方式使用時段並不理想。
有些開發人員儲存的值是「Morning」,有些則使用「morning」,而其他則使用「MORNING」。
這種情況造成很多問題。
您的任務是透過執行重構來修正這個問題。重構意指在功能維持不變的情況下,改善程式碼的過程。有些是簡化邏輯,或是將重複的程式碼移至別的函式。
哪種類別可用來模擬一組有限的值,以協助修正這個問題?
您的團隊想要您修改時段的程式碼,改為使用列舉類別。一旦使用列舉類別,您的小組成員就必須強制選擇其中一種提供的時段值,以避免發生這類問題。
列舉類別應命名為 Daypart
。其中應有三個值:
MORNING
AFTERNOON
EVENING
您要如何建立這個列舉類別?
您要如何重構才能使用 Event
類別?
建議您現在編寫解決方案的程式,再繼續往下。
點選「下一步」即可查看我們如何編寫程式碼。
6. 任務 2 解決方案
enum class Daypart {
MORNING,
AFTERNOON,
EVENING,
}
重構的 Event
資料類別現在使用了列舉類別:
data class Event(
val title: String,
val description: String? = null,
val daypart: Daypart,
val durationInMinutes: Int,
)
7. 任務 3
您的同事很喜歡使用重構的 Daypart
,但他們有其他問題。
以下程式碼是他們目前建立及儲存使用者事件的方式。
val event1 = Event(title = "Wake up", description = "Time to get up", daypart = Daypart.MORNING, durationInMinutes = 0)
val event2 = Event(title = "Eat breakfast", daypart = Daypart.MORNING, durationInMinutes = 15)
val event3 = Event(title = "Learn about Kotlin", daypart = Daypart.AFTERNOON, durationInMinutes = 30)
val event4 = Event(title = "Practice Compose", daypart = Daypart.AFTERNOON, durationInMinutes = 60)
val event5 = Event(title = "Watch latest DevBytes video", daypart = Daypart.AFTERNOON, durationInMinutes = 10)
val event6 = Event(title = "Check out latest Android Jetpack library", daypart = Daypart.EVENING, durationInMinutes = 45)
他們建立了大量的事件,而每個事件目前都需要用到自身的變數。隨著越來越多的事件產生,要追蹤所有事件變得更為困難。在這種做法下,系統在判斷使用者排定的事件數量時難度為何?
您能否想到可以更妥善管理儲存這些事件的方法?
如何將所有事件儲存在單一變數中?(注意:由於系統可能會加入更多活動,因此必須具有彈性。同時也必須有效傳回儲存在變數中的事件數量。)
您會使用哪個類別或資料類型?可以透過什麼方式新增更多活動?
現在輪到您實作這項功能。請先嘗試編寫程式碼,再點選「下一步」查看我們提供的解決方案。
8. 任務 3 解決方案
val events = mutableListOf<Event>(event1, event2, event3, event4, event5, event6)
9. 任務 4
您的主管很滿意應用程式的表現,但是決定使用者應該要能夠根據事件的持續時間,查看「短」事件的摘要。例如:「你有 5 個短的事件」。
「短」事件是指不到 60 分鐘的事件。
若使用上一個任務解決方案中的 events
變數程式碼,可以如何做到這一點?
點選「下一步」即可查看我們提供的解決方案。
10. 任務 4 解決方案
我們可以透過多種方法達成這個目標,以下是我們決定使用的方法:
val shortEvents = events.filter { it.durationInMinutes < 60 }
println("You have ${shortEvents.size} short events.")
11. 任務 5
您的團隊成員肯定應用程式的表現,但他們希望使用者能夠看到所有事件及其時段的摘要。
畫面上應該會顯示類似以下的輸出內容:
Morning: 3 events Afternoon: 4 events Evening: 2 events
若使用上一步驟的 events
變數程式碼,可以如何做到這一點?
點選「下一步」即可查看解決方案程式碼。
12. 任務 5 解決方案
以下是我們提供的解決方案,但也可以採取其他做法。
val groupedEvents = events.groupBy { it.daypart }
groupedEvents.forEach { (daypart, events) ->
println("$daypart: ${events.size} events")
}
13. 任務 6
目前,您的同事是透過索引尋找並顯示最後一個項目。使用的程式碼為:println("Last event of the day: ${events[events.size - 1].title}")
。
您的管理員建議查看 Kotlin 說明文件,找到可以簡化這個程式碼的函式。
您發現什麼函式?
請嘗試使用並確認您得到相同的顯示結果。
點選「下一步」即可查看解決方案。
14. 任務 6 解決方案
println("Last event of the day: ${events.last().title}")
15. 任務 7
所屬團隊很喜歡您設計的資料類別,但發現每次需要以字串形式表示事件的持續時間時,都要重複編寫程式碼:
val durationOfEvent = if (events[0].durationInMinutes < 60) {
"short"
} else {
"long"
}
println("Duration of first event of the day: $durationOfEvent")
雖然您可以直接在類別中新增一個方法修正此重複問題,但由於其他團隊已開始在他們的應用程式中使用您的事件類別,因此這不是理想的做法。如果類別改變,他們必須重新測試所有程式碼,以確保所做的變更不會造成問題。
在不直接變更資料類別的情況下,要如何撰寫一個擴充功能屬性,來傳回與上述程式碼相同的值?
正確實作之後,您便能使用以下程式碼,並產生出這項任務開始時所產生的相同程式碼。
println("Duration of first event of the day: ${events[0].durationOfEvent}")
點選「下一步」即可查看解決方案。
16. 任務 7 解決方案
val Event.durationOfEvent: String
get() = if (this.durationInMinutes < 60) {
"short"
} else {
"long"
}
17. 其他練習
如果想取得更多有關 Kotlin 語言的練習內容,請查看 JetBrains Academy 的 Kotlin 核心概念課程。如要跳到特定主題,請前往知識地圖,瀏覽課程所涵蓋主題的清單。