5 วิธี ทำให้ Code ของคุณ ใช้งานได้ยาวนาน และทันสมัยอยู่

01-มี.ค.-19

คัมภีร์เทพ IT

หากคุณเป็น Developer คุณอาจเคยชินกับ Framework, Library และเทคโนโลยีที่เกิดขึ้นใหม่อยู่ตลอดเวลา ทำให้ต้องหา Tool และ Pattern ใหม่อยู่เสมอ ซึ่งนั่นหมายถึง Code ที่เขียนไว้มีแนวโน้มที่จะถูกคิดว่ามันเก่าไปแล้ว แต่ในบทความนี้จะบอกถึง 5 วิธี ทำให้ Code ของคุณ ใช้งานได้ยาวนาน และทันสมัยอยู่เสมอ เรามาดูกันว่าทำอย่างไรบ้าง

1. แบ่ง Code ของคุณตาม หัวข้อ ไม่ใช่ตามเทคโนโลยี

หนึ่งในคำถามแรกๆ ที่คุณอาจมี เมื่อเริ่ม Project ใหม่คือ คุณควรจะจัด Structure อย่างไรดี โดยทั่วไปที่นิยมใช้กัน เราสามารถแบ่งออกเป็น 2 แบบคือ แบ่ง File ของเราตามเทคโนโลยี หรือตามหัวข้อเรื่องนั้นๆ

สมมติว่า คุณกำลังเริ่มต้น Project โดยมีเป้าหมายที่เฉพาะเจาะจง (เช่น หา Bug, เพิ่มหรือลบ Feature หรืออื่นๆ) คุณต้องหา Code ที่เหมาะสม, ดูรายละเอียด File ที่เกี่ยวข้อง, ดูในเรื่องการ Test และเมื่อคุณรู้สึกมั่นใจเพียงพอ ถึงจะทำการเปลี่ยนแปลงลงใน Codebase

ในฐานะของ Developer แล้ว Process นี้ถือเป็นเรื่องที่ต้องทำกันอยู่เสมออยู่แล้ว ดังนั้น เราจึงควรทำให้มันมีประสิทธิภาพ

คำถามคือ อะไรจะ Maintain ง่ายกว่ากัน ระหว่าง Codebase ที่มี 10 File กับ Codebase ที่มี 100 File?

การแยก Code ตามหัวข้อ จะช่วยให้คุณสามารถ Focus ไปที่ส่วนเล็กๆ ของ Codebase ของคุณได้ ในขณะที่การทำโดยแบ่งตามดทคโนโลยี อาจทำให้คุณต้องดู Code ในหลายไฟล์จากหลายๆที่ ซึ่งเป็นเรื่องที่ลำบาก

2. จัดหา Public API สำหรับหัวข้อของคุณ

ลองนึกภาพว่า Project ของคุณมี Payments Directory ที่คุณใช้เก็บ Code ที่เกี่ยวข้องกับเงินๆ ทองๆ ทั้งหมด เรามีชุด Component เพื่อจัดเก็บ Payments ของเราใน Database หรือเชื่อมต่อกับ 3rd party Services อย่าง Stripe

Component เหล่านั้นมีเพื่อทำให้ Public API สามารถทำงานได้อย่างตามที่ตกลงกันไว้ หรือ พูดอีกอย่างก็คือ เพื่อให้แน่ใจว่า Code ของ payments ทำงานอย่างที่มันควรจะเป็น

เพื่อความชัดเจน เราจะไม่ได้พูดถึง HTTP API ที่ Mobile App ของคุณจะเรียกเพื่อ Charge ผู้ใช้ แต่เรากำลังพูดถึง Internal API ที่จะเปลี่ยน Payments Directory ของคุณให้เป็น “Microservice” ของตัวเอง

คุณอาจ ถามว่าทำไม? เนื่องจาก การมี API ที่ชัดเจน จะทำให้:

  • เห็นภาพที่ชัดเจนของพฤติกรรมที่คาดหวัง
  • ขอบเขตการ Test เบื้องต้น ที่ทุกคนเห็นด้วย และสามารถยอมรับได้
  • อิสระในการเปลี่ยนแปลงอะไรก็ตามจากการ Implementation

ยิ่งไปกว่านั้น มันเป็นสิ่งสำคัญสำหรับ API นี้ ที่จะรู้น้อยที่สุดเท่าที่เป็นไปได้ของ External Concept อย่างเช่น users, permissions หรือ environments ซึ่งสิ่งเหล่านี้ไม่ได้เป็นส่วนหนึ่งของ Domain และนี่คือวิธีที่เราแก้ปัญหาด้วย Communication Layer (Public HTTP Endpoint นั้นไม่มีความปลอดภัย) หรือ Development Workflow ของเรา

อย่างเช่น เราสามารถที่จะจินตนาการได้ว่ามี:

  • API ที่เป็นสาธารณะ จะเปิดเผย Domain Behavior บางอย่าง และควบคุม Authentication และ Authorization
  • Private Admin API + panel จะช่วยให้ Customer Support เป็นเรื่องที่ทำได้ง่ายขึ้นและค้นหา Bug โดยไม่ต้องวุ่นวายกับ Database หรือ Console ใดๆ
  • วิธีที่ง่ายในการเขียน Fixtures, Examples และ Migrations

3. ใช้ Interface ที่มีขนาดเล็กและหน้าที่ชัดเจน

วิธีนี้ค่อนข้างได้รับความนิยม ในฐานะของ Developer พวกเรามักเตือนตัวเองอยู่เสมอให้ใช้ Abstractions แทนการใช้ concrete implementations รวมทั้งให้ใช้เทคนิค Segregate Interfaces และ Invert Dependencies ใน Code ของเรา

คุณสามารถค้นหาเนื้อหามากมายที่ครอบคลุมไปถึงทฤษฎีได้อย่างง่ายดาย ดังนั้น เราจะมา Focus ไปที่ตัวอย่างที่เป็นประโยชน์กัน Payments App ของเราอาจจำเป็นต้องสื่อสารกับ Interface เหล่านี้:

  • Event Publisher
  • Event Subscriber
  • Credit Card Charger
  • Email Sender

Interface ทั้งหมดเหล่านี้ มีบทบาทที่เจาะจงและชัดเจน ต่อมาเราจะดูถึงการนำไป Implement ที่เฉพาะเจาะจงมากขึ้น:

อย่างที่คุณเห็น Interface ที่มีขนาดเล็กจะช่วยให้เราสามารถสร้าง Test และเลือก Strategy ที่ดีที่สุดสำหรับการกระทำแต่ละอย่างซึ่งขึ้นอยู่กับ Environment ในทางกลับกัน เรามักจะเขียนการ Implement โดยขึ้นอยู่กับ Technology ที่เฉพาะเจาะจง เพื่อรวบรวมความรู้และ Function ตัวช่วยเข้าด้วยกัน

4. แยก Data ของคุณออกจาก Storage Strategy

มาทำความเข้าใจกันก่อน: เรามักคิดว่า ORMs นั้นผิด (หรืออาจเป็นเพราะคน ที่ทำผิดไปก็ได้) ดู Code ของ Ruby on Rails นี้:

เรามาเริ่มแกะ Code กันดีกว่า

ก่อนอื่นเราสังเกตว่า Object นี้อธิบายถึง Relationships, Cascade Deletion และ Nullable Attributes ซึ่งเป็นสิ่งที่คุณคาดหวังจาก Object-Relational Mapper

ต่อไป เราพิจารณากันว่า อะไรเป็นสิ่งสำคัญสำหรับเราจากสิ่งที่เห็นจาก Class Article:

  • เราควรใช้ประโยชน์จากภาษาที่เราใช้อย่างเต็มประสิทธิภาพ เช่น เมื่อเราใช้ Java เราต้องการที่จะสามารถใช้ OO Patterns และ Inheritance ได้อย่างอิสระ หรือเมื่อเราใช้ Haskell เราต้องการใช้ Union Types และ Records
  • เราควรจะสามารถเก็บข้อมูลของเราใน Formats และ Databases ที่แตกต่างกันได้ สิ่งนี้ช่วยให้เราใช้ ElasticSearch สำหรับ Performant Searches, PostgreSQL สำหรับ Consistent State และ Redis เพื่อให้ Autosave Feature ของเรานั้นเร็วมากพอ

ORM Models ไม่มีแบบนั้น เพราะมันเป็นเพียงแค่วิธีที่จะ Interface กับ SQL Database เรายังต้องแสดงและจัดการกับข้อมูลของเราที่อื่นด้วย ปัญหาคือ หากคุณยอมรับสิ่งนี้ การใช้ ORM ดูเหมือนจะมีความยุ่งยากและไม่สะดวกมากนัก และนี่คือสิ่งที่เรากำลังหมายถึง:

สิ่งสำคัญที่สุดคือ: คุณสามารถใช้ ORM ได้ แต่อย่าใช้พวกมันเพื่อแสดงและจัดการข้อมูลของคุณเพียงอย่างเดียว เพราะมันยังห่างไกลจากวัตถุประสงค์ที่แท้จริงของมันอยู่

5. ใช้ Events เพื่อทำให้ส่วนต่างๆ ของ Application ติดต่อกันได้โดยเกิด Dependency น้อยที่สุด

หากมีการเชื่อมต่อ Application 2 ส่วนเข้าด้วยกัน Code ก็ควรต้องเชื่อมต่อกันด้วยใช่ไหม

Event-Driven Programming เป็นสิ่งที่ช่วยทำให้ App ของคุณเชื่อมต่อกันได้ แต่ Code ของคุณยังคงง่ายต่อการเขียนและ Maintain อยู่ ในความเป็นจริง มันทำงานได้ดีมากซึ่งแนวคิดคล้ายๆ กันนี้ กำลังแพร่หลายใน Mobile และ Frontend Development ภายใต้ชื่อ Reactive Programming และในโลกของการ Operation มี Cloud Providers และ บริษัทหลายแห่ง ต่างก็วางเดิมพันอย่างหนักในเรื่องนี้

แนวคิดพื้นฐานก็คือ ทุกการเปลี่ยนแปลงที่เกิดขึ้นใน Domain ของคุณ จะถูกแสดงเป็น Atomic Event

Event ทั้งหมดจะถูกเผยแพร่ผ่าน Event Bus บางประเภทและ Random Observers สามารถ Subscribe และตอบสนองต่อ Event ที่น่าสนใจโดยไม่รบกวน Component อื่นๆ มากเกินไปนัก

มันต้องใช้ความพยายามเป็นพิเศษในช่วงแรก เนื่องจากคุณต้องวางรากฐานสำหรับ Event Bus และคิดถึง Properties และ atomicity ของแต่ละ Event แต่ในระยะยาวมันคุ้มค่าอย่างแน่นอน

นี่คือตัวอย่างบางส่วนของ Feature ที่ง่ายในการ Implement ด้วย event-driven architectures แต่ในทางกลับกัน มันยากที่จะนึกถึง และยากที่จะ Maintain:

  • ส่ง welcome email ให้กับ User ใหม่
  • แจ้งผู้ที่เขียนบทความนั้นๆ ว่ามีความคิดเห็นใหม่เข้ามา

ลองจินตนาการดูว่า คุณจะทำแต่ละงานเหล่านี้ด้วย Imperative Way หรือ Reactive Way ดี

Event-Driven Programming จะหลีกเลี่ยง Function ที่ยาวๆ ด้วย Side Effects ต่างๆ เป็นจำนวนมาก และทำให้การ Test ของคุณดีขึ้น และสามารถแบ่งแยกได้สะดวกขึ้น

เชื่อว่าตอนนี้คุณคงมีแนวทางในการทำให้ Code ของคุณสามารถใช้งานได้ยาวนานขึ้น และยังทันสมัยใช้งานได้อยู่เสมอ

ที่มา:  https://medium.com/

 

 

รับตำแหน่งงานไอทีใหม่ๆ ด้วยบริการ IT Job Alert

 

อัพเดทบทความจากคนวงในสายไอทีทาง LINE ก่อนใคร
อย่าลืมแอดไลน์ @techstarth เป็นเพื่อนนะคะ

เพิ่มเพื่อน

 

บทความล่าสุด