Day 4 的時候跟大家分享在分析欄位的時候,可以思考物件如何設計。今天就正式進入我們怎麼把這些欄位放入物件裡面,首先,先給大家看一下星戰人物中,人物的描述完整的是長什麼樣子如下:
{
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"hair_color": "blond",
"skin_color": "fair",
"eye_color": "blue",
"birth_year": "19BBY",
"gender": "male",
"homeworld": "https://swapi.dev/api/planets/1/",
"films": [
"https://swapi.dev/api/films/2/",
"https://swapi.dev/api/films/6/",
"https://swapi.dev/api/films/3/",
"https://swapi.dev/api/films/1/",
"https://swapi.dev/api/films/7/"
],
"species": [
"https://swapi.dev/api/species/1/"
],
"vehicles": [
"https://swapi.dev/api/vehicles/14/",
"https://swapi.dev/api/vehicles/30/"
],
"starships": [
"https://swapi.dev/api/starships/12/",
"https://swapi.dev/api/starships/22/"
],
"created": "2014-12-09T13:50:51.644000Z",
"edited": "2014-12-20T21:17:56.891000Z",
"url": "https://swapi.dev/api/people/1/"
}
昨天也提到只想呈現某些資訊,這邊我再做個簡化,只針對以下幾個欄位去做物件解析:
{
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"birth_year": "19BBY",
"gender": "male"
}
首先,先針對性別寫一個 enum,直接針對這個字串去做轉換,將來如果需要擴增新的性別,就不用整個物件做很大的更動。
enum class Gender(val type: String) {
MALE("male"),
FEMALE("female"),
UNKNOWN("unknown"),
NONE("n/a")
}
接著建立 Profile 物件
data class Profile(
val name: String,
val height: String,
@SerializedName("mass") val weight: String,
private val gender: String,
@SerializedName("birth_year") val birthYear: String
) {
val genderType: Gender
get() {
values().forEach {
if (it.type == gender) {
return it
}
}
return UNKNOWN
}
}
當然建立物件之後,會想問那剛剛所使用的 enum 轉換正常嗎?其他欄位所輸出的資料是如預期呈現嗎?這時候在還沒建立網路層之前可以寫 unit test 驗證資料是否正確性。
class ProfileTest {
@Test
fun skyWalkerTest(){
val input = "\n" +
"{\n" +
" \"name\": \"Luke Skywalker\",\n" +
" \"height\": \"172\",\n" +
" \"mass\": \"77\",\n" +
" \"hair_color\": \"blond\",\n" +
" \"skin_color\": \"fair\",\n" +
" \"eye_color\": \"blue\",\n" +
" \"birth_year\": \"19BBY\",\n" +
" \"gender\": \"male\",\n" +
" \"homeworld\": \"https://swapi.dev/api/planets/1/\",\n" +
" \"films\": [\n" +
" \"https://swapi.dev/api/films/2/\",\n" +
" \"https://swapi.dev/api/films/6/\",\n" +
" \"https://swapi.dev/api/films/3/\",\n" +
" \"https://swapi.dev/api/films/1/\",\n" +
" \"https://swapi.dev/api/films/7/\"\n" +
" ],\n" +
" \"species\": [\n" +
" \"https://swapi.dev/api/species/1/\"\n" +
" ],\n" +
" \"vehicles\": [\n" +
" \"https://swapi.dev/api/vehicles/14/\",\n" +
" \"https://swapi.dev/api/vehicles/30/\"\n" +
" ],\n" +
" \"starships\": [\n" +
" \"https://swapi.dev/api/starships/12/\",\n" +
" \"https://swapi.dev/api/starships/22/\"\n" +
" ],\n" +
" \"created\": \"2014-12-09T13:50:51.644000Z\",\n" +
" \"edited\": \"2014-12-20T21:17:56.891000Z\",\n" +
" \"url\": \"https://swapi.dev/api/people/1/\"\n" +
"}"
val profile = Gson().fromJson(input, Profile::class.java)
// determine the data
Assert.assertEquals("Luke Skywalker", profile.name)
Assert.assertEquals("172", profile.height)
Assert.assertEquals("77", profile.weight)
Assert.assertEquals("19BBY", profile.birthYear)
Assert.assertEquals(Gender.MALE, profile.genderType)
}
}
在 class 按下 run test 就可以看看自己的資料是否正確,當然也可以隨意改 gender 的值來驗證這些 enum 是不是有超出預期的狀況發生。有興趣的朋友可以直接拉下程式碼自行玩玩看