มาลุยเขียน Extension ใน kotlin กันเลย
สังเกตว่าเราใช้ OR INVALIDATE เข้าไปด้วย เผื่อเราต้องการเช็คแค่ invalidate เท่านั้นโดยไม่สนเคสย่อย
โดยวัตถุประสงค์ของการ OR คือเราต้องการ group การ validate ตามโจทย์นั่นเอง
Email เราจะใช้ INVALIDATE_EMAIL
Mobile number เราจะใช้ INVALIDATE_MOBILE_NUMBER
NOTE: อย่าลืมกำหมด IntDef ด้วย
ต่อไปเริ่มเขียน logic ตามนี้
เราจะสังเกตเห็นว่ามี
@receiver:ValidateString
NOTE: สามารถเข้าไปอ่าน kotlin document ได้ [click]
เป็นที่มาว่าทำไมเราให้ใส่ IntDef annotation ไว้ ก็เพื่อให้เราสามารถเขียน extension เฉพาะ annotation ที่เรากำหนดนั่นเอง โค้ดเราจะเป็นระเบียบมากขึ้น
แต่จริงๆเราไม่จำเป็นต้องใช้ IntDef annotation ก็ได้แบบนี้
fun Int.isValidate(): Boolean = ...
แต่ int ทุกตัวในแอปสามารถใส่ “.isValidate” ได้ทุกตัว ซึ่งจริงๆไปควร
เราเลยสร้าง ValidateString annotation ขึ้นมา
fun @receiver:ValidateString Int.isValidate(): Boolean = …
คราวนี้จะต้องเป็น Int ที่อยู่ใน ValidateString annotation เท่านั้นถึงจะ “.isValidate” ได้
ส่วนการเช็ค validate group เราแค่ AND ง่ายๆเข้าไปตามโค้ดด้านบนได้เลย เพราะในบางกรณีเราไม่ได้ต้องการเช็คเคส invalidate ทั้งหมด เราแค่อยากรู้ว่ามัน invalidate หรือไม่แค่นั้น
ตัวอย่างการใช้งาน
ตัวอย่างการใช้ประมานนี้
val email = edtEmail.text.toString()
if(email.validateEmail().isInvalidateEmail()){
//do something with invalidate
}else
//do something with validate
}ตัวอย่างเช็คแต่ละเคสย่อย
val email = edtEmail.text.toString()
when(email.validateEmail()){
INVALIDATE_EMPTY -> toast("Email is empty.")
INVALIDATE_EMAIL_FORMAT -> toast("Email is wrong format.")
INVALIDATE_EMAIL_NOT_GMAIL -> toast("We allow gmail only.")
INVALIDATE_EMAIL_AT -> toast("Email is not contain @.")
}// validate!!
// do something
เพราะเราคิดว่า HEX มีทั้งหมด 15 ตัว นั่นเท่ากับว่า index หนึ่งสามารถมีได้ 15 เคสน่าจะเพียงพอสำหรับการ validate string 1 group
เช่น
Email: เราเลือกใช้ index ที่ 2 คือ 0x0F00
0x0100, 0x0200, 0x0300, 0x0400, …, 0x0F00 = 15 เคส สำหรับของการ validate อีเมลล์
Mobile number: เราเลือกใช้ index ที่ 3 คือ 0xF000
0x1000, 0x2000, 0x3000, 0x4000, …, 0xF000 = 15 เคส สำหรับของการ validate เบอร์โทร
เป็นต้น
HEX คือเลขฐาน 16 ซึ่งมันมี limit ของมันเช่นกัน
ถ้าเราเลือกใช้ตัวแปรที่เป็น int จะได้
val intHex: Int = 0xfffffff 7 group
ถ้าเราใช้ long จะได้
val longHex: Long = 0xfffffffffffffff 15 group
ซึ่งจะเป็นค่าที่มากที่สุดที่ primitive type รับได้เนาะ ถ้าใส่มากกว่านั้น IDE จะขึ้นด่าเราทันที่ว่าคุณใส่จำนวนเกินที่ int/long รับได้
แล้วถ้าแอปเราใช้มากกว่านั้นหละ?
คำตอบคือ คุณต้องออกแบบระบบ HEX ของแอปคุณเอง
ตัวอย่างการออกแบบ HEX ให้รองรับมากกว่า 15 group
val longHex: Long = 0xfffffffffffffff 15 ตัว
ตอนนี้ถ้าเราใช้ long มันจะแบ่ง 15 group และแต่ละ index จะแบ่งได้อีก 15 เคส ซึ่งบางคนบอกมันน้อยไป งั้นเรามาออกแบบกันใหม่
0x f f f f f f f f f f f f f f f
เรากำหนดว่า
0x f f f f f f f f f f f f f f f
ให้สองตัวสุดท้ายเป็นจำนวนเคส นั่นเท่ากับ F x F = 15 x 15 = 255 เคส (ใช้เกินให้มันรู้ไป 555)
0x f f f f f f f f f f f f f f f
ส่วนที่เหลือให้เป็น group ไปซะ คราวนี้ได้มากกว่า 15 group แบบเก่าแน่ๆ
เท่ๆประมานนี้ 😎
สรุป
การใช้ความสามารถของ bitwise operator มาทำ validate function เป็นอีกแนวทางหนึ่งที่เราสามารถนำมาปรับใช้กับโปรเจกต์เราได้
ทำให้โค้ด เรียกใช้ง่าย, ไม่รก, เขียน test ก็สบาย
โดยแรงบันดาลเราเอามาจากโค้ดของ android ในส่วนของการเซ็ต flag เพราะเขาก็ใช้ท่านี้ในการเช็คเช่นกัน
วันนี้ก็จบสั้นๆแค่นี้ เจอกันบล็อกหน้าครับ 😎