สิ่งเตือนใจของดรอยเดฟ "อย่าปล่อยให้แอปเติบโตไปในทางที่ผิดจนสายเกินแก้"
จดสรุปจาก "อย่าปล่อยให้แอปเติบโตไปในทางที่ผิดจนสายเกินแก้" ของทาง LMWN ที่มีกิจกรรม knowledge sharing ให้เราเข้าไปฟังผ่าน Zoom โดยคุณเอกจ้า ในวันศุกร์ที่ 4 มีนาคม 2565 เวลาเริ่มหกโมงเย็น ถึงทุ่มครึ่งนิดๆ เพราะคำถามช่วง Q & A เยอะจ้า
"อย่าปล่อยให้แอปเติบโตไปในทางที่ผิดจนสายเกินแก้"
เพราะการเขียนแอปใหม่ให้ดีกว่าเดิม ใคร ๆ ก็ทำได้ แต่การพัฒนาแอปเดิมที่มีอยู่ ให้ดีขึ้น รองรับฟีเจอร์ใหม่ ๆ ให้มากขึ้น และขยายทีมเพิ่มในอนาคตได้ง่ายขึ้น มันมีอะไรมากกว่าที่คิด และเป็นประสบการณ์ที่ไม่สามารถหากันได้ง่าย ๆ
.
วันศุกร์ที่ 4 มีนาคม 2565 เวลา 18.00 - 19.00 น. นี้ พบกับคุณเอก LMWN’s Staff Software Engineer - Android (GDE Android) ในหัวข้อ "สิ่งที่ไม่ควรมองข้ามเพื่อก้าวเข้าสู่ Large Scale App"
และไลฟ์ย้อนหลังจ้า
ก่อนที่พี่เอกมา ทางทีมงานเปิดเพลงจากเว็บนี้รอด้วยหล่ะ เหมาะกับการทำงานสุดๆ
คนอ่านหลายๆคนคงจะรู้จักแอพ LINE MAN กันอยู่แล้วเนอะ ซึ่งตอนนี้มี active user ต่อเดือนถึง 10 ล้าน user ด้วยกัน เมื่อแอพคนใช้เยอะ การจัดการหลังบ้านมีความซับซ้อนด้วย
ใน session นี้จะกล่าวถึงเรื่องที่ควรทำ และเรื่องควรระมัดระวัง ในการทำแอพพลิเคชั่นบนแอนดรอยด์นั่นเอง
เมื่อตอนที่แอพที่เราทำนั้น ยังเป็นแอพตัวน้อยๆอยู่ บางอย่างเราอาจจะรีบทำ และไม่ได้สนใจ ในการทำแอพในเริ่มแรก เมื่อพอแอพของเราเติบโตขึ้น จากเดิมที่เคยโอเค ก็ไม่โอเคแล้ว จึงต้องมีการปรับเปลี่ยน โดยแอพพลิเคชั่นที่มี scale ใหญ่จะมีปัญหาที่แตกต่างจากที่เราเจอ และในไทยเอง ก็มีหลายๆแอพพลิเคชั่นที่เติบโตมาในระดับนึง สิ่งที่คนดูจะได้กลับไปหลังฟังเสร็จ คือ ทำให้เรา scale มันได้ง่ายขึ้น
บริษัทมีจุดประสงค์ในการ scale ทีม เพื่อทำ product ตอบโจทย์ user หรือ business มากขึ้น
โดยแอพพลิเคชั่นมีการเติบโตตลอดเวลา จาก pilot แอพตัวน้อยๆ เติบโตขึ้นไปเรื่อยๆ เริ่มมี business และ featyre ที่ตอบโจทย์ user มากขึ้น มีการขยายฐาน user แล้วเพิ่ม revenue กลับมา
Factor ที่ทำให้แอพพลิเคชั่นเติบโตขึ้นมา
- Customer : ผู้ใช้งานแอพของเรา
- Feature : มี feature อะไรบ้าง และ business model ต่างๆ
- Codebase : source code ที่เราได้สร้างขึ้นมา
- Engineer : ผู้ที่เขียนโค้ดของแอพขึ้นมา
โดย factor เหล่านี้ จะโตตามกัน
Application ในระดับ large scale เป็นแอพที่ผู้ใช้งานในระดับโลกเยอะมาก เช่น Facebook, Twitter, YouTube, Gmail โดยโค้ดในแอพนั้นๆมีจำนวนหลักล้านบรรทัดขึ้นไป มี engineer หลักร้อย และมี code change หลักแสน
App Architecture
เราจะออกแบบ strecture ของโปรเจกเป็นแบบไหน?
แต่ละแบบสามารถใช้งานได้หมด (ยกเว้น MVC) ตราบใดที่เรายังไม่เจอปัญหา
แต่ถ้าตัดสินใจเลือก จะเลือกเป็น MVVM with Clean Architecture เนื่องจากทีม Android ของ Google แนะนำ เป็น pattern ที่ flexible สามารถใช้งานได้หลากหลาย
ตัวโครงสร้าง อันนี้เป็น basic ที่ใช้งานกันเนอะ
Modularization
การแบ่งโค้ดของเราเป็นหลายๆกลุ่ม ตาม feature ทำให้ลดโอกาสในการแก้โค้ดทับกัน ลดการกระทบในการแก้ feature อื่นๆ และใช้เวลาในการ build ลดลง เนื่องจากการที่ยัดโค้ดของเราทุกอย่างใน module เดียว เมื่อเปลี่ยนโค้ดเพียงบรรทัดเดียว จะใช้เวลาในการบิ้วนานมากๆ และเมื่อเราทำเป็น module แล้วจะแก้ปัญหาในการรอบิ้วนานได้ เนื่องจาก compile code บาง module ที่ chode change และทำ test ในบาง module ได้
และในรายละเอียดบางอย่างจะต้องคุยกัน เช่น มี module อะไรบ้าง และเราจะแบ่ง module ตามอะไร เช่น เราแยก by feature อย่าง payment หรือ authen และมีโค้ดที่เราต้องแชร์กันในแต่ละ module ด้วย ของแอพ LINE MAN และ Wongnai (ที่รีวิวร้านอาหารอ่ะ) มีแยก service มีเป็น module ย่อย และ module กลาง
Navigation
การเปลี่ยนหน้าในแอพเดียวกัน แต่ละ module จะรู้เรื่องได้อย่างไร และมีการเชื่อมกันเป็น dependency ไหม ซึ่งวิธีการทำก็จะมี Jetpack Navigation กับ Interface ที่ทาง LMWN ใช้ มี inject ว่าเปิด Activity ตัวไหน
Dependency Management
การจัดการ dependency ภายในโปรเจก เราสามารถใช้เป็น Dependency Injection หรือ Service Locator ตัวไหนก็ได้ แต่ต้อง concert เรื่อง dependency ที่มีทั้งหมดในแอพยังไง relate ตรงไหน และมีความมึนงงหรือสับสนตรงไหน
Localization
แอพของเรารองรับกี่ประเทศ ส่วนใหญ่ที่ต้องมีแน่ๆคือ ภาษาไทย และ ภาษาอังกฤษ ใช่ม้า และบางแอพเติบโตจนรองรับภาษาเพื่อนบ้านด้วยหล่ะ
Numeric Format
ไม่ได้ใช้เป็น standard เดียวกันทั่วโลก บางภาษาอาจจะใช้แบบจุดหรือ space แทนลูกนํ้านะ
LTR & RTL
ภาษาส่วนใหญ่เราจะอ่านจากซ้ายมาขวาเนอะ แต่ก็มีบางภาษาเช่นกันที่อ่านจากขวามาซ้าย ดังนั้นจะต้องทำ UI ให้รองรับด้วย บาง icon จะต้องดูด้วยว่าเราจะต้องกลับด้านมันหรือไม่
Custom Font
เพราะ font ในเครื่องเพราะไม่ค่อยสวยงามตาม branding ก็เลยใช้ custom font กัน (คือ font คนอื่นนั่นแหละในที่นี้) ซึ่งบาง font ที่เขาทำมาก็ไม่ได้รองรับทุกภาษา อย่างในสไลด์ก็จะเห็นว่า ภาษาจีน ภาษาญี่ปุ่น ภาษาเกาหลี และภาษาอารบิก เหมือนกันในทุก font เนื่องจากตัว font ไม่ได้รองรับภาษาเหล่านี้ไว้ จึงแสดง font ในเครื่องแทน บางแอพจึงทำ font ไว้ใช้ในแอพนั้นๆแทน
UI Components
design system คือ standard ที่ทำให้เราทำงานกันง่ายขึ้น และตัว requirement จะต้องล้อตาม design system ด้วยเช่นกัน เพราะทีมจะต้องใช้ด้วยกัน ไม่ว่าจะเป็น developer, designer อะเนอะ
Tracking / Analytics
แน่นอนว่าแต่ละแอพจพทำการทำ tracking บางอย่าง เพื่อทำ analytics ในบางแอพมีขนาดที่ใหญ่มาก ทำให้ตัวแอพถูก drive ด้วย data ทำให้ต้อง track เยอะถึง ส่งผลให้ code handle ได้ยากขึ้นเช่นกัน จากโค้ดที่ดูสวยในตอนแรก ถูกติด analytics บน code ทำให้โค้ดมีความสวยงามลดลง
Deep Linking
ไม่ได้กำหนดไว้แต่แรก เป็น url ที่กดแล้วเข้าแอพ ทำไปทำมาจะเจอจุดนึง คือเจอ business model ที่แปลกมาก เช่น กดลิ้งแล้ว user จะเจอหน้าร้านอาหาร ที่มี code ส่วนลดใส่มาให้ด้วย (มีอีกอย่างสองอย่าง จดไม่ทัน แต่ลิ้งมันแนบหลายอย่างอ่ะ)
ซึ่งการทำ deeplink เป็นพื้นฐานในการพัฒนาแอพ เพราะทำกันทุกแอพ
และการใช้ deeklink นั้น จะควบคู่กับการ tracking ด้วย เพื่อดูว่าหลังจาก user กด link แล้ว เขาทำอะไรต่อ
ทางทีม Engineer ของ LMWN ได้ทำ library เพื่อแก้ปัญหานี้ และในตอนนี้มีทั้งหมด 70 deeplink ตัวนี้ทำข้ึนเพื่อให้ทีมเขียนวิธีเดียวกัน และจัดการได้ง่ายนั่นเอง
สามารถไปฟังย้อนหลังของงาน Android Bangkok Conference 2020 หรืออ่านบล็อกเราที่สรุปเรื่องนี้ก็ได้นะ
Feature Flag / Experimental
ทำให้ user บางกลุ่มสามารถใช้บาง feature ได้ และมี condition บางอย่างในการ combine กัน ทำให้เกิด pattern บางอย่างที่มีความซับซ้อนในการเปิดปิด feature ดังนั้นจะต้องหาวิธีบางอย่างในการเปิดปิด feature แต่ละตัว และ QA สามารถนำไป test ได้
Third Party Libraries
เลือก library ที่มีคนใช้เยอะ, ตามใส่ใจแก้ไข issue ต่างๆ คือมีคนสร้าง issue แล้วมาตอบ, มีอัพเดตแก้ไขอยู่เรื่อยๆ
แต่ถ้าเราใช้แล้วเกิดปัญหาบางอย่าง และไม่สามารถแก้ไขได้ library ตัวนี้อาจจะถูกตัดออกจากโปรเจก หรือไม่ก็เอาไปทำใหม่ให้เหมาะสมกับการใช้งานในแอพของเรา
และแน่นอนว่าถ้ามีแอพตัวนึงพัง อาจจะต้องมี library สำรองด้วยเช่นกัน เมื่อตัวหลักมีปัญหา จึงมีการทำ feature flags เพื่อเปิดปิด library บางตัวด้วย เช่น Google Maps พัง user เข้าใจว่าแอพเรามีปัญหา ก็สามารถไปใช้ library map เจ้าอื่นในกรณีนี้ได้
การใช้ Firebase Config เวลาควบคุมอาจจะมีการผิดพลาดในเรื่องของ dependency
Force Update
เมื่อเกิด issue ที่ทำให้แอพพัง developer อย่างเราก็รีบแก้ไขและอัพขึ้น Play Store จากนั้นก็ให้มัน Force Update ซึ่งการทำ Force Update ควรจะอยู่ในแอพตั้งแต่แรก (อันนี้เห็นด้วยเลย) เป็นการช่วยบังคับให้ user นั้นทำการ update แอพ ซึ่งบางทีไม่ควรทำ เพราะทำให้ user เปิดความไม่พอใจ จนเลิกใช้แอพของเราได้เลยนะ
แล้วต้องทำไหมนะ? ก็ต้องทำอยู่ดี เอ๊ะยังไง?
ดังนั้นใช้ tool ช่วยในการ control ส่วนนี้ ถ้าเรามี data เพียงพอในการดูว่าที่แอพพังเกิดจาก flow ตรงไหน จะขึ้น popup ให้กับผู้ใช้กลุ่มนั้นในการ force update จ้า
CI/CD
เราจะต้องมีระบบ CI/CD ในการเขียนเทสแล้วช่วยตรวจให้, ทำระบบกลาง, test conflict, เอาแอพขึ้น Play Store
ทาง LMWN ใช้ Github ในการเก็บ code ต่างๆไว้ และทำ CI/CD ที่ pipeline มีการกำหนด job ในการทำงาน และควบคุม standard ของ code เช่นเปิด MR แล้วต้องทำอะไรบ้าง เราจะ review ยังไง มีการ approve กี่คน merge แล้วจะเกิดอะไรขึ้น ซึ่งไม่ได้มี pattern กลาง แล้วแต่บริบทของแต่ละโปรเจกและบริษัท
ซึ่งในบริษัทใหญ่ๆจะมีทีมใหญ่ในการดูแลโดยเฉพาะ ทำให้เราเจอปัญหาน้อยลง เช่นเจอปัญหาที่ CI/CD โดยตัว Unit Testing ของเราก็ test pass แต่อาจจะไปพังที่ตัวระบบ CI/CD เอง
Code Standardization
code quality หรือ code standard จะต้องคุยกับคนในทีมทั้งหมด แต่ละคนเชียนโค้ดไม่เหมือนกัน เช่น การตั้งชื่อตัวแปร การตั้งชื่อ view UI การ implement common feature ต่างๆ
ดังนั้นจะต้องมี resource กลาง เช่น document, wiki กลาง รวมไปถึง process ในการทำงานกันระหว่างทีม ผ่าน guideline กลาง
Onboarding
การ scale product จะต้องมีการ scale คนในทีมด้วย ทำให้คนมาใหม่ทำงานร่วมกันได้ โดยมี know-how ที่เหมือนกัน เป็นสิ่งสำคัญ
- process : เข้าทีมมาแล้ว ต้องทำอะไรบ้าง ช่วยให้คนมาใหม่ทำงานได้ง่ายขึ้น
- guideline : วิธีการเขียน code ต่างๆ
- resource : ตัวช่วยที่ทำให้เรียนรู้ได้เร็วขึ้น
จริงๆแอพ large scale ยังมีเรื่อง common หยิบย่อยที่หลายๆที่เจอกัน ไม่ว่าจะเป็นเรื่องของกฏหมาย หรือออกแบบสำหรับผู้พิการ
แล้วที่ LMWN มี tool ที่เขาทำกันเอง สำหรับ sync พวก wording ในแต่ละภาษาของแอพ โดยที่เราไม่ต้องไปแก้ใน string.xml
เอง developer เอา key มาใส่ในโค้ด โดยไม่ต้องสนใจ wording ข้างใน key นั้น
และการพัฒนาแอพที่เกิดเป็นคอขวด ทำให้พัฒนาแอพได้ช้า และ developer ไม่มีความสุขด้วยหล่ะ :(((((((
Q & A
ไม่ได้จดหมด เหน่ย 555
- เจอน้องคนแรก เรียนปีสาม ถามในมุม PM ต้องรู้อะไรบ้าง ก็คือ PM มีความรู้กว้าง (ว่า developer เขาทำอะไรกัน มีอะไรที่เขาต้องทำบ้าง) แต่ไม่ได้รู้ลึก (ว่าต้องทำแบบไหน ต้องเขียนโค้ดจริง) ซึ่งน้องเขาขยันแหละ
- ไม่ได้มีวิธีในการจัดการยิงโนติให้ตรงเวลา เนื่องจาก feature battery ของ device ก็เลยมาช้า อาจจะต้องมี tool ช่วยแก้ปัญหาในการยิงตรงนี้
- ใช้ Sonarqube ในการตรวจสอบ quality ของ code ซึ่งเป็นตัวที่คนนิยมใช้กันเยอะ
- การแยก module ให้แยกเป็นราย context ไม่ใช่ราย feature ถ้ามีของบางอย่างใช้ร่วมกัน อาจจะเป็นพวก logic หรือ UI บางอย่าง หรืออันที่ common หรือ business logic ที่ใช้เหมือนกันหรือต่างกัน ในทีมจะต้องคุยว่ามี layer อะไร แล้วจะต้องมี module อะไรบ้าง
- ไม่ควร over estimate ในการประเมิน task งานที่ต้องทำใน sprint นั้นๆ
- แหล่งข้อมูลเพิ่มเติมที่เกี่ยวข้อง ว่าอ่านหนังสือเล่มอะไรดีครับ เล่มนี้เห็น Android Developer อ่านกันเยอะ ชื่อว่า Building Mobile Apps at Scale ของ Gergely Orosz อันนี้เป็นแนวทางเนอะ เราอาจจะไม่ได้ใช้ตามหนังสือทั้งหมด จิ้มอ่านรายละเอียดเพิ่มเติมได้ด้านล่างเลย
ก็หวังว่าจะได้ประโยชน์กันเนอะ อย่างเราเห็นจากพี่เอก ก็เลยชวนน้องในทีม แปะชวนทีมรอบข้างมานั่งฟังด้วย แหะๆ
ส่วนกิจกรรมมนี้ไม่ได้มีวันเดียวจ้า ติดตามในหน้า event นี้เลย
สามารถ support ค่ากาแฟเจ้าของบล็อกได้ที่ปุ่มแดงส้มสุดน่ารักที่มุมซ้ายล่าง หรือกดปุ่มตรงนี้ก็ได้จ้า
กด follow Twitter เพื่อได้รับข่าวสารก่อนใคร เช่น สปอย content ใหม่ หรือสรุป content เร็วๆในนี้จ้า
ติดตามข่าวสารและบทความใหม่ๆได้ที่
Subscribe ช่อง YouTube ของเราได้ที่
download แอพอ่านบล็อกใหม่ของเราได้ที่นี่