Flutter — สร้าง Boilerplate Project ที่สมบูรณ์แบบตั้งแต่เริ่มต้น ส่วนที่ 2: จุดปวด

Dec 01 2022
เครดิต: Nguyễn Thành Minh (Android Developer) ในบทความนี้ ผมจะนำเสนอจุดอ่อน 5 ประการที่ผมประสบในขณะที่เป็นนักพัฒนามือถือ ฉันได้กำหนดเกณฑ์บางอย่างที่เราต้องการในสถาปัตยกรรม

เครดิต: Nguyễn Thành Minh (นักพัฒนา Android)

ในบทความนี้ ผมจะนำเสนอ 5 ประเด็นปัญหาที่ผมประสบในขณะที่เป็นนักพัฒนามือถือ ฉันได้กำหนดเกณฑ์บางอย่างที่เราต้องการในสถาปัตยกรรม สุดท้ายนี้ ผมจะเล่าให้คุณฟังว่า Clean Architecture ช่วยผมแก้ไขจุดบกพร่องเหล่านั้นได้อย่างไร

1. 5 จุดที่เจ็บปวดในอดีต

1.1. การตัดสินใจที่ยากลำบากของผู้นำ

ที่มา: Unsplash

Pain point ของผู้นำหรือสถาปนิกทุกคนมาจากการที่ต้องตัดสินใจ

ผู้นำต้องตัดสินใจว่าโครงการนี้ควรใช้เฟรมเวิร์ก ไลบรารี ฐานข้อมูล และเทคโนโลยีใด การตัดสินใจที่รีบร้อนหรือขาดวิสัยทัศน์จะนำไปสู่ผลลัพธ์ที่คาดเดาไม่ได้ในกระบวนการพัฒนาซอฟต์แวร์ ในฐานะหัวหน้าโครงการ ฉันมักจะมองหาสถาปัตยกรรมที่ช่วยให้ฉันชะลอการตัดสินใจให้นานที่สุดเท่าที่จะทำได้ แต่ยังคงทำให้แน่ใจว่าทีมไม่ต้องรอให้ฉันคิด ทีมของฉันนำหน้าเสมอ แม้ว่าทีมออกแบบจะยังไม่ได้วาดหน้าจอใด ๆ ทีมของเรายังสามารถทำตรรกะก่อนและเขียนการทดสอบหน่วยได้ตามปกติ

1.2. ระหว่างการบำรุงรักษาโครงการ การแก้ไขข้อบกพร่อง 1 รายการจะสร้างข้อบกพร่องใหม่ 10 รายการ

ที่มา: Unsplash

สิ่งนี้ไม่ใช่เรื่องปกติสำหรับนักพัฒนาเมื่อพวกเขาต้องปรับโครงสร้างใหม่หรือแก้ไขจุดบกพร่องในโครงการที่มี "สถาปัตยกรรมที่เหนียวมาก" คลาสและฟังก์ชันมีความสัมพันธ์กันอย่างใกล้ชิด ซึ่งเพียงแค่แก้ไขฟังก์ชันเล็กๆ เพียงหนึ่งฟังก์ชันก็เพียงพอแล้วที่จะทำให้โครงการทั้งหมดพังทลาย ในบางสถานการณ์ หลังจากแก้ไขข้อบกพร่อง 1 รายการ ผู้ทดสอบจะพบข้อบกพร่องอีก 10 รายการ ดังนั้นจึงอาจใช้เวลาหลายเดือนในการแก้ไขข้อบกพร่อง 1 รายการ สิ่งนี้ทำให้ค่าบำรุงรักษาโครงการสูงมาก ดังนั้นเราจึงต้องการสถาปัตยกรรมที่ช่วยแยกการพึ่งพาให้มากที่สุด เพื่อให้ทุกครั้งที่เราแก้ไขคลาสหรือฟังก์ชัน ระบบทั้งหมดจะไม่ได้รับผลกระทบ และคุณไม่ต้องแก้ไขโค้ดด้วยตนเอง

1.3. จุดอ่อนของนักพัฒนา FE อาจมาจากนักพัฒนา BE

นักพัฒนา FE ที่มีรหัสคลาสโมเดลตาม API Response ที่กำหนดโดยนักพัฒนา BE จะมีความเสี่ยง 4 ประการ:

  1. หาก BE ได้รับการออกแบบมาไม่ดี FE ก็จะได้รับผลกระทบไปด้วย โค้ดนั้นยากที่จะแมปกับ UI ต้องใช้การคำนวณอย่างมากเพื่อแมปกับ UI เช่นเดียวกับภาพด้านบน Json Response จะอยู่ทางขวามือ ในโมเดลการจองจะมีโมเดลห้อง และในโมเดลห้องก็มีโมเดลการจองซึ่งวนเวียนซ้ำไปซ้ำมาไม่มีสิ้นสุด
  2. FE จะต้องปรับให้เข้ากับ BE แต่คลาสโมเดลจะถูกนำเข้าในหลายคลาสเช่น UI และ Bloc การแก้ไขจะนำไปสู่การแก้ไขคลาสจำนวนมากที่ขึ้นอยู่กับคลาสนั้น
  3. นักพัฒนา BE สองคนในทีมสามารถมีรูปแบบการเขียนโค้ดที่แตกต่างกันได้สองแบบ ดังนั้นพวกเขาจึงสามารถส่งUserDataการตอบสนองที่แตกต่างกันมากขึ้นอยู่กับ API ตัวอย่างเช่น ในfetchUsersAPI ส่งคืนageฟิลด์ประเภทint?แต่ในfetchUserDetailAPI ส่งคืนฟิลด์ String?ประเภท int?จะเกิดอะไรขึ้นถ้า ฉันประกาศประเภทฟิลด์อายุ แอปของฉันจะหยุดทำงานเมื่อเรียกfetchUserDetailAPI ดังนั้นเราจึงต้องประกาศageฟิลด์ประเภทdynamicแม้ว่าประเภทนี้จะถือว่าไม่ปลอดภัยเนื่องจากสามารถทำให้เกิดข้อผิดพลาดรันไทม์ได้ง่าย กรณีนี้เป็นเรื่องปกติมากเมื่อทำงานเป็นฟรีแลนซ์เมื่อสมาชิกในทีม BE ไม่เคยทำงานร่วมกันมาก่อน และไม่มีผู้นำและไม่มีใครตรวจสอบโค้ด
  4. เพื่อความปลอดภัย ฟิลด์ทั้งหมดในคลาส Data Model จะต้องเป็นประเภท null ได้เสมอเช่นint?, อย่างไรก็ตาม สิ่งนี้อาจนำไปสู่ความเสี่ยงที่แอปของเราจะหยุด ทำงานString?เนื่องจากNullPointerException

1.4. สร้างทั้งแอปบนอุปกรณ์เคลื่อนที่และแอป TV ในที่เก็บเดียว

ก่อนหน้านี้ ฉันได้เข้าร่วมในโครงการพัฒนาทั้งแอพมือถือและแอพทีวีอย่าง Youtube ในเวลานั้น ฉันต้องสร้างโมดูลแอป 2 โมดูล: mobile_app, และtv_app. เป็นมูลค่าการกล่าวขวัญที่นี่ว่าโมดูลทั้งสองนี้ใช้ API คำขอเดียวกันเช่นfetchVideos, fetchVideoDetailดังนั้น หากต้องการใช้โค้ดของคำขอ API สำหรับทั้งสองโมดูลซ้ำ เราจำเป็นต้องออกแบบสถาปัตยกรรมเพื่อให้ส่วน API ถูกแยกออกเป็นโมดูลอื่นเพื่อใส่เข้าไปในโมดูลแอปทั้งสอง

1.5 เรื่องราวของเต่ากับกระต่ายและความเข้าใจผิดแบบคลาสสิกของผู้พัฒนา

ดูแผนภูมิสถิติสองรายการด้านบน นักพัฒนาสามารถเห็นเป็นเรื่องปกติเนื่องจากเป็นสิ่งที่เราพบเจอมามาก แต่สำหรับผู้จัดการ พวกเขาจะต้องกังวลอย่างแน่นอน พวกเขาต้องการใช้เงินมากขึ้นเพื่อสร้างรายได้และผลผลิตที่สูงขึ้นหลังจากการเปิดตัวแต่ละครั้ง แต่ชีวิตไม่สมบูรณ์แบบ ในความเป็นจริง โครงการต้องการเพียง 20% ของต้นทุนทั้งหมดเพื่อสร้าง 80% ของคุณสมบัติหลักของซอฟต์แวร์ อย่างไรก็ตาม ในรุ่นต่อๆ ไป การเพิ่มคุณสมบัติทีละเล็กละน้อยอาจก่อให้เกิดค่าใช้จ่ายจำนวนมาก ในบางกรณี อาจทำให้เกิดเหตุการณ์ร้ายแรงตามมาได้ สถาปัตยกรรมมีส่วนสำคัญในการทำให้เกิดปัญหานี้อย่างแน่นอน

จำบทเรียนเกี่ยวกับกระต่ายและเต่าที่เราได้เรียนรู้ในวัยเด็ก เราสามารถสอนสามบทเรียนสำหรับตัวเราเอง:

  • ช้าและมั่นคงชนะการแข่งขัน
  • ชัยชนะไม่ได้ขึ้นอยู่กับว่าคุณแข็งแกร่งหรือเร็วแค่ไหน
  • ยิ่งเร่งความเร็วยิ่งน้อยลง

ข้อผิดพลาดทั่วไปของนักพัฒนาคือ “กำหนดเวลาของโครงการกำลังจะมาถึง เขียนโค้ดอะไรก็ได้ที่คุณต้องการ แล้วจึงปรับโครงสร้างใหม่ในภายหลัง” การคิดเช่นนี้จะนำมาซึ่งปัญหาใหญ่สองประการคือ

  1. ไม่มีเวลาสำหรับการปรับโครงสร้างใหม่ โดยส่วนตัวแล้ว ฉันเคยมีประสบการณ์และได้เห็นนักพัฒนารายอื่น ๆ หลายคนใช้เวลาว่างในช่วงสุดสัปดาห์เพื่อปรับเปลี่ยนคุณสมบัติใหม่ ๆ ที่เปิดตัวใน Sprint ล่าสุด นี่เป็นนิสัยการทำงานที่ไม่ดีต่อสุขภาพ
  2. ไม่มีการรับประกันว่า refactor จะทำงานและไม่สร้างข้อบกพร่องเพิ่มเติม

สรุปแล้ว นี่คือ Pain point 5 ข้อของผมที่เจอในช่วงที่เป็น Mobile Developer ในส่วนสุดท้าย ฉันจะเปิดเผย: Clean Architecture ช่วยฉันแก้ไขจุดบกพร่องเหล่านี้ได้อย่างไร