annotation class ตัวช่วยไม่ให้ทีมหลงทางไปใส่ค่าผิดสำหรับชาว android
คือบางทีโปรเจกมันจะมีอารมณ์ประมาณว่า สมมุติ feature นึงมีการแสดงผลหลายๆ type และมี media หลายๆแบบ เราก็ใส่เป็น class constant กัน ทีนี้ทีมก็จะงงๆหล่ะ ว่าพี่ๆ อันนี้ต้องใส่ค่าอะไรหรอครับ ใช้กับ feature ไหนบ้าง และมีความเผลอในการใส่ค่าผิดด้วยหล่ะ
ดังนั้นปัญหาเหล่านี้เพื่อนร่วมทีมได้เสนอ solution ที่ชื่อว่า annotation นั่นเอง (เนื่องจากเขาไม่ได้ตั้งชื่อเรื่องมาให้นั่นเองเลยขอตั้งชื่อเรื่องไปแบบนี้แล้วกัน)
ที่มาที่ไป
สมมุติเนอะว่าเป็นแอพ Facebook จะมี post หลายๆ type ด้วยกัน
สมมุติว่า feed ของเรามี media ต่างๆ เช่น text, image, video, link เราก็สร้าง class constant เพื่อเอาไปใช้ในการส่ง media type ต่างๆไปหลังบ้าน ดังนี้
object MediaType {
const val TEXT = "text"
const val IMAGE = "image"
const val VIDEO = "video"
const val LINK = "link"
}
การเอาไปใช้ สมมุติว่าโพสต์นี้มีหลาย media สมมุติอีกว่าในนี้มีรูป เราก็จะใช้งานตัวนี้เป็น MediaType.IMAGE
ซึ่งก็ทำกันทั่วไป
แต่โปรเจกแต่ละโปรเจกที่ทำมาในชีวิตการเป็น Android Developer นั้น มีความใหญ่มหาศาลประมาณหนึ่ง แน่นอนว่ามันอาจจะมีการทำ class constant อื่นๆอีกมากมายก่ายกอง
แล้วววตัวแปรบางชุด ก็มีค่าเหมือนกันอีกจ้า ทีนี้จะงงหล่ะว่า ค่านี้ ของตัวแปรชุดไหนกันนะ
เช่น เราสามารถ search content ที่เป็น image และ video ได้ด้วยนะ
และถ้าคุยกันแล้วหลุด มันมีเหตุที่เอา constant มาใส่ผิดได้ และบางทีก็ถามกันในทีมว่า พี่ครับ อันนี้ใส่ค่าอะไรบ้างครับ?
ใช้ Annotation สิ!
annotation object เป็นตัวที่ช่วยเรา wrap ค่าต่างๆที่เป็น text เข้าด้วยกัน นั่นเอง
วิธีการใช้ Annotation นั้น ให้เราสร้าง class ใหม่ที่เป็น annotation ขึ้นมา
หน้าตา class นี้จะเป็นแบบนี้นะ เดี๋ยวเราจะมาอธิบายในแต่ละส่วนกัน
import androidx.annotation.StringDef
import com.mikkipastel.feed.constant.MediaType.Companion.TEXT
import com.mikkipastel.feed.constant.MediaType.Companion.IMAGE
import com.mikkipastel.feed.constant.MediaType.Companion.LINK
import com.mikkipastel.feed.constant.MediaType.Companion.VIDEO
@Retention(AnnotationRetention.SOURCE)
@StringDef(TEXT, IMAGE, VIDEO, LINK)
annotation class MediaType {
companion object {
const val TEXT = "text"
const val IMAGE = "image"
const val VIDEO = "video"
const val LINK = "link"
}
}
- ประกาศ
annotation class
ที่ชื่อว่าMediaType
เนอะ - ข้างในประกาศตัวแปร constant ต่างๆใน
companion object
@StringDef
เป็นการ define type ว่าก้อนนี้เป็น String นะเออ
@Retention
บอกว่าเจ้าตัวนี้เป็น source นะ อันนี้อธิบายไม่ค่อยถูกง่ะ แงงงงง
และต้องประกาศตัวแปร @StringDef
เป็นก้อน String อย่างเดียวหรือไม่? ไม่จำเป็น อาจจะเป็นอย่างอื่นก็ได้
อย่างใน document นี้นั้น จะมีการประกาศได้หลายๆแบบเช่นกัน เช่น IntDef
, LongDef
ตัวอย่าง อื้มมมมม ประยุกต์จากใน doc ของ IntDef
นิดหน่อยเนอะ เพราะนึกไม่ออกเนี่ยแหละ มุแงงงงงง
import androidx.annotation.IntDef
import com.mikkipastel.navigation.NavigationMode.Companion.MODE_STANDARD
import com.mikkipastel.navigation.NavigationMode.Companion.MODE_LIST
import com.mikkipastel.navigation.NavigationMode.Companion.MODE_TABS
@Retention(AnnotationRetention.SOURCE)
@IntDef(MODE_STANDARD, MODE_LIST, MODE_TABS)
annotation class NavigationMode {
companion object {
const val MODE_STANDARD = 0
const val MODE_LIST = 1
const val MODE_TABS = 2
}
}
การนำไปใช้งาน
เรานำ annotation ชื่อ class นี้ไปใส่ไว้ด้านหน้าชื่อตัวแปรที่เราต้องการ เช่น
data class MediaContent(
@SerializedName("type") @MediaType val type: String? = null,
@SerializedName("media_url") val mediaUrl: String? = null
)
ทีนี้เวลาใช้งาน developer ก็สามารถกลับไปดูได้ว่า field นี้ใส่ค่าอะไรได้บ้างเนอะ ก็จะ link กลับไปดูได้หล่ะ
ก็จะประมาณนี้เนอะ
สามารถ support ค่ากาแฟเจ้าของบล็อกได้ที่ปุ่มแดงส้มสุดน่ารักที่มุมซ้ายล่าง หรือกดปุ่มตรงนี้ก็ได้จ้า
กด follow Twitter เพื่อได้รับข่าวสารก่อนใคร เช่น สปอย content ใหม่ หรือสรุป content เร็วๆในนี้จ้า
ติดตามข่าวสารและบทความใหม่ๆได้ที่
download แอพอ่านบล็อกใหม่ของเราได้ที่นี่