Quantcast
Channel: cc :: somkiat
Viewing all articles
Browse latest Browse all 1997

[Swift] ทำการ validate ข้อมูลด้วยแนวคิดของ Composite pattern

$
0
0

ios-refactory

ios-refactory วันนี้ทำการ review code ของ iOS app ที่พัฒนาด้วยภาษา Swift พบว่ามีส่วนการ validate หรือตรวจสอบข้อมูลจำนวนมาก และรูปแบบ code ที่เขียนบ่อย ๆ เป็นดังนี้
  • ค่าต้องไม่ว่าง
  • ข้อมูลต้องมีรูปแบบที่ถูกต้องเช่น email , ความยาวของข้อมูล, เป็นตัวเลข เป็นต้น
  • ข้อมูลของ password ซึ่งต้องมีทั้งตัวเลข ตัวพิมพ์เล็กและพิมพ์ใหญ่
  • และอื่น ๆ อีกมากมาย
คำถามก็คือ code ที่เขียนเป็นอย่างไร ? คำตอบก็คือ if-else-if-else ไปเรื่อย ๆ ไงล่ะ !!

คำถามต่อมาก็คือ

ถ้าต้องการให้ส่วนการแยกการ validate ข้อมูลแต่ละอย่างออกจากกัน เพื่อทำให้ง่ายต่อการเพิ่ม ลบ และเปลี่ยนแปลง แน่นอนว่า ต้องใช้งานง่ายอีกด้วย เราจะต้องทำอย่างไร ? ดังนั้นลองมาสร้างส่วนการ validate ข้อมูลใหม่กันหน่อย โดยละทิ้งแนวคิดแบบเดิม ๆ กันไปบ้าง

เริ่มต้นด้วยการกำหนดผลของการ validate ข้อมูล

ซึ่งมี 2 แบบคือ valid และ invalid สามารถเขียน code ได้ดังนี้ [gist id="a0c3e18ad68650afb3a6a2e6e190fc13" file="1.swift"]

ในตัวอย่างทำการ validate ข้อมูลของ username

ซึ่งมีการตรวจสอบ 3 กรณีคือ
  1. เป็นค่าว่าง
  2. สั้นเกินไป คือ ความยาวน้อยกว่า 5
  3. ยาวเกินไป คือ ความยาวมากกว่า 10
สามารถเขียน code เพื่อกำหนด error ทั้งสามกรณีได้ดังนี้ [gist id="a0c3e18ad68650afb3a6a2e6e190fc13" file="2.swift"]

สิ่งที่ต้องการคือ ในการ validate แต่ละกรณีให้แยกออกจากกัน

เพื่อทำให้แต่ละส่วนทำงานอย่างใดอย่างหนึ่งไปเลย (Single Responsibility) ทำให้แต่ละส่วนทำงานมีขนาดที่เล็ก แต่ยังต้องการให้มีรูปแบบและโครงสร้างเดียวกัน จึงทำการสร้าง protocol ของ Validator ไว้ดังนี้ [gist id="a0c3e18ad68650afb3a6a2e6e190fc13" file="3.swift"] จากนั้นทำการสร้าง Validator สำหรับการ validate ข้อมูลในแต่ละกรณีไป

กรณีที่ 1 ตรวจสอบค่าว่าง (Empty)

เป็น validator ที่ใช้สำหรับตรวจสอบค่าว่างของข้อมูล ตั้งชื่อไว้ว่า EmptyValidator เขียน code ได้ดังนี้ [gist id="a0c3e18ad68650afb3a6a2e6e190fc13" file="4.swift"]

กรณีที่ 2 ตรวจความยาวของ username ว่าสั้นเกินไปหรือไม่

เป็น validator เฉพาะของ username เท่านั้น ตั้งชื่อไว้ว่า UsernameTooShortValidator เขียน code ได้ดังนี้ [gist id="a0c3e18ad68650afb3a6a2e6e190fc13" file="5.swift"]

กรณีที่ 3 ตรวจความยาวของ username ว่ายาวเกินไปหรือไม่

เป็น validator เฉพาะของ username เท่านั้น ตั้งชื่อไว้ว่า UsernameTooLongValidator เขียน code ได้ดังนี้ [gist id="a0c3e18ad68650afb3a6a2e6e190fc13" file="6.swift"]

เมื่อได้ validator ครบทุกตัวแล้ว ก็มีปัญหาตามมาคือ จะใช้งานอย่างไรดีล่ะ ?

เพื่อให้ได้ตามที่ต้องการคือ สามารถเพิ่ม ลบ และแก้ไขได้ง่าย ดังนั้นจึงทำการสร้าง struct/class สำหรับใช้จัดการกลุ่มของ validator ทำให้สามารถจัดการได้ง่ายขึ้น เขียน code ได้ดังนี้ [gist id="a0c3e18ad68650afb3a6a2e6e190fc13" file="7.swift"] จากนั้นทำการสร้างตัวรวม validator สำหรับ username ขึ้นมา และใช้งานดังนี้ [gist id="a0c3e18ad68650afb3a6a2e6e190fc13" file="8.swift"]

พบว่าด้วยวิธีการนี้ ทำให้เราสามารถสร้างชุด validator ของข้อมูลได้ง่ายขึ้น

ทั้งการเพิ่ม ลบ และแก้ไข ที่สำคัญสามารถเขียนชุดการทดสอบได้ง่ายมาก ๆ อีกด้วย ถึงแม้จะแลกมาด้วยความซับซ้อนที่เพิ่มขึ้น (ควบคุมได้)
Simple not easy !!

Viewing all articles
Browse latest Browse all 1997

Trending Articles