Flutter — สร้าง Boilerplate Project ที่สมบูรณ์แบบตั้งแต่เริ่มต้น ส่วนที่ 2: จุดปวด
![](https://post.nghiatu.com/assets/images/m/max/724/1*p3nlp3RayU6hnGMbs343lQ.png)
เครดิต: 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 ประการ:
- หาก BE ได้รับการออกแบบมาไม่ดี FE ก็จะได้รับผลกระทบไปด้วย โค้ดนั้นยากที่จะแมปกับ UI ต้องใช้การคำนวณอย่างมากเพื่อแมปกับ UI เช่นเดียวกับภาพด้านบน Json Response จะอยู่ทางขวามือ ในโมเดลการจองจะมีโมเดลห้อง และในโมเดลห้องก็มีโมเดลการจองซึ่งวนเวียนซ้ำไปซ้ำมาไม่มีสิ้นสุด
- FE จะต้องปรับให้เข้ากับ BE แต่คลาสโมเดลจะถูกนำเข้าในหลายคลาสเช่น UI และ Bloc การแก้ไขจะนำไปสู่การแก้ไขคลาสจำนวนมากที่ขึ้นอยู่กับคลาสนั้น
- นักพัฒนา BE สองคนในทีมสามารถมีรูปแบบการเขียนโค้ดที่แตกต่างกันได้สองแบบ ดังนั้นพวกเขาจึงสามารถส่ง
UserData
การตอบสนองที่แตกต่างกันมากขึ้นอยู่กับ API ตัวอย่างเช่น ในfetchUsers
API ส่งคืนage
ฟิลด์ประเภทint?
แต่ในfetchUserDetail
API ส่งคืนฟิลด์String?
ประเภทint?
จะเกิดอะไรขึ้นถ้า ฉันประกาศประเภทฟิลด์อายุ แอปของฉันจะหยุดทำงานเมื่อเรียกfetchUserDetail
API ดังนั้นเราจึงต้องประกาศage
ฟิลด์ประเภทdynamic
แม้ว่าประเภทนี้จะถือว่าไม่ปลอดภัยเนื่องจากสามารถทำให้เกิดข้อผิดพลาดรันไทม์ได้ง่าย กรณีนี้เป็นเรื่องปกติมากเมื่อทำงานเป็นฟรีแลนซ์เมื่อสมาชิกในทีม BE ไม่เคยทำงานร่วมกันมาก่อน และไม่มีผู้นำและไม่มีใครตรวจสอบโค้ด - เพื่อความปลอดภัย ฟิลด์ทั้งหมดในคลาส Data Model จะต้องเป็นประเภท null ได้เสมอเช่น
int?
, อย่างไรก็ตาม สิ่งนี้อาจนำไปสู่ความเสี่ยงที่แอปของเราจะหยุด ทำงานString?
เนื่องจากNullPointerException
1.4. สร้างทั้งแอปบนอุปกรณ์เคลื่อนที่และแอป TV ในที่เก็บเดียว
ก่อนหน้านี้ ฉันได้เข้าร่วมในโครงการพัฒนาทั้งแอพมือถือและแอพทีวีอย่าง Youtube ในเวลานั้น ฉันต้องสร้างโมดูลแอป 2 โมดูล: mobile_app
, และtv_app
. เป็นมูลค่าการกล่าวขวัญที่นี่ว่าโมดูลทั้งสองนี้ใช้ API คำขอเดียวกันเช่นfetchVideos
, fetchVideoDetail
ดังนั้น หากต้องการใช้โค้ดของคำขอ API สำหรับทั้งสองโมดูลซ้ำ เราจำเป็นต้องออกแบบสถาปัตยกรรมเพื่อให้ส่วน API ถูกแยกออกเป็นโมดูลอื่นเพื่อใส่เข้าไปในโมดูลแอปทั้งสอง
1.5 เรื่องราวของเต่ากับกระต่ายและความเข้าใจผิดแบบคลาสสิกของผู้พัฒนา
ดูแผนภูมิสถิติสองรายการด้านบน นักพัฒนาสามารถเห็นเป็นเรื่องปกติเนื่องจากเป็นสิ่งที่เราพบเจอมามาก แต่สำหรับผู้จัดการ พวกเขาจะต้องกังวลอย่างแน่นอน พวกเขาต้องการใช้เงินมากขึ้นเพื่อสร้างรายได้และผลผลิตที่สูงขึ้นหลังจากการเปิดตัวแต่ละครั้ง แต่ชีวิตไม่สมบูรณ์แบบ ในความเป็นจริง โครงการต้องการเพียง 20% ของต้นทุนทั้งหมดเพื่อสร้าง 80% ของคุณสมบัติหลักของซอฟต์แวร์ อย่างไรก็ตาม ในรุ่นต่อๆ ไป การเพิ่มคุณสมบัติทีละเล็กละน้อยอาจก่อให้เกิดค่าใช้จ่ายจำนวนมาก ในบางกรณี อาจทำให้เกิดเหตุการณ์ร้ายแรงตามมาได้ สถาปัตยกรรมมีส่วนสำคัญในการทำให้เกิดปัญหานี้อย่างแน่นอน
จำบทเรียนเกี่ยวกับกระต่ายและเต่าที่เราได้เรียนรู้ในวัยเด็ก เราสามารถสอนสามบทเรียนสำหรับตัวเราเอง:
- ช้าและมั่นคงชนะการแข่งขัน
- ชัยชนะไม่ได้ขึ้นอยู่กับว่าคุณแข็งแกร่งหรือเร็วแค่ไหน
- ยิ่งเร่งความเร็วยิ่งน้อยลง
ข้อผิดพลาดทั่วไปของนักพัฒนาคือ “กำหนดเวลาของโครงการกำลังจะมาถึง เขียนโค้ดอะไรก็ได้ที่คุณต้องการ แล้วจึงปรับโครงสร้างใหม่ในภายหลัง” การคิดเช่นนี้จะนำมาซึ่งปัญหาใหญ่สองประการคือ
- ไม่มีเวลาสำหรับการปรับโครงสร้างใหม่ โดยส่วนตัวแล้ว ฉันเคยมีประสบการณ์และได้เห็นนักพัฒนารายอื่น ๆ หลายคนใช้เวลาว่างในช่วงสุดสัปดาห์เพื่อปรับเปลี่ยนคุณสมบัติใหม่ ๆ ที่เปิดตัวใน Sprint ล่าสุด นี่เป็นนิสัยการทำงานที่ไม่ดีต่อสุขภาพ
- ไม่มีการรับประกันว่า refactor จะทำงานและไม่สร้างข้อบกพร่องเพิ่มเติม
สรุปแล้ว นี่คือ Pain point 5 ข้อของผมที่เจอในช่วงที่เป็น Mobile Developer ในส่วนสุดท้าย ฉันจะเปิดเผย: Clean Architecture ช่วยฉันแก้ไขจุดบกพร่องเหล่านี้ได้อย่างไร