ข้ามไปยังเนื้อหาหลัก

ขับเคลื่อนด้วยความต้องการ (Needs driven)

TL;DR

— คุณระบุเป้าหมายไม่ได้เหรอว่าฟีเจอร์ใหม่นี้จะแก้ปัญหาอะไร? หรือปัญหาคือตัวโจทย์เองก็ยังไม่ได้ตั้งมาให้ชัด? ประเด็นคือ Methodology นี้ช่วยดึงเอานิยามของงานและเป้าหมายที่เป็นปัญหาออกมาให้เห็นชัดขึ้น

— โปรเจกต์ไม่ได้อยู่นิ่งๆ - Requirement และฟังก์ชันการทำงานเปลี่ยนตลอดเวลา นานวันเข้า โค้ดก็เละตุ้มเป๊ะ เพราะตอนเริ่ม โปรเจกต์ถูกออกแบบมาแค่ตามความต้องการแรกเริ่ม และหน้าที่ของสถาปัตยกรรมที่ดีคือต้องพร้อมรับมือกับเงื่อนไขการพัฒนาที่เปลี่ยนแปลงไป

ทำไม? (Why?)​

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

@sergeysova: ระหว่างการพัฒนา เราพยายามตั้งชื่อให้แต่ละ Entity หรือ Function เพื่อสะท้อนความตั้งใจและความหมายของโค้ดที่กำลังทำงานอยู่ให้ชัดเจน

เพราะถ้าไม่เข้าใจโจทย์ ก็เป็นไปไม่ได้เลยที่จะเขียน Test ที่ถูกต้องและครอบคลุมเคสสำคัญๆ, ใส่ Error handling ที่ช่วยผู้ใช้ในจุดที่ถูกต้อง, หรือแม้แต่เรื่องพื้นฐานอย่างการไม่ขัดจังหวะ Flow ของผู้ใช้เพียงเพราะ Error เล็กๆ น้อยๆ ที่แก้ได้

เรากำลังพูดถึงโจทย์อะไร?​

Frontend พัฒนาแอปพลิเคชันและอินเตอร์เฟสสำหรับผู้ใช้ปลายทาง (End users) ดังนั้นเราจึงแก้โจทย์ของผู้บริโภคเหล่านี้

เมื่อคนคนนึงมาหาเรา เขาต้องการแก้ความเจ็บปวดบางอย่าง หรือตอบสนองความต้องการบางอย่าง

หน้าที่ของ Managers และ Analysts คือการระบุความต้องการนี้ออกมา และให้นักพัฒนา Implement โดยคำนึงถึงธรรมชาติของการทำเว็บ (เน็ตหลุด, Backend error, พิมพ์ผิด, จิ้มพลาด)

เป้าหมายนี้แหละ ที่ผู้ใช้มาหาเรา คือโจทย์ของนักพัฒนา

ปัญหาเล็กๆ หนึ่งข้อที่ถูกแก้ คือหนึ่ง Feature ในระเบียบวิธี Feature-Sliced Design — คุณต้องหั่น (Cut) ขอบเขตงานทั้งหมดของโปรเจกต์ออกเป็นเป้าหมายเล็กๆ

มันส่งผลกับการพัฒนายังไง?​

การแตกงาน (Task decomposition)​

เมื่อนักพัฒนาเริ่ม Implement งาน เพื่อให้เข้าใจและดูแลโค้ดได้ง่าย เขาจะ หั่นมันออกเป็นระยะๆ ในหัว:

  • ก่อนอื่น แบ่งเป็น Top-level entities และ Implement พวกมัน
  • จากนั้น Entities พวกนี้ ก็ถูกแบ่งย่อยลงไปอีก
  • และทำแบบนี้ไปเรื่อยๆ

ในกระบวนการแบ่งเป็น Entities นักพัฒนาจะถูกบังคับให้ตั้งชื่อที่สะท้อนไอเดียของเขา และช่วยให้คนอ่านโค้ดเข้าใจว่าโค้ดนี้แก้โจทย์อะไร ในขณะเดียวกัน เราก็ไม่ลืมว่าเรากำลังพยายามช่วยลดความเจ็บปวดหรือตอบสนองความต้องการของผู้ใช้

เข้าใจแก่นของงาน (Understanding the essence of the task)​

แต่การจะตั้งชื่อที่ชัดเจนให้ Entity ได้ นักพัฒนาต้องรู้มากพอเกี่ยวกับจุดประสงค์ของมัน

  • เขาจะใช้ Entity นี้ยังไง
  • มัน Implement ส่วนไหนของโจทย์ผู้ใช้, เอาไปใช้ที่อื่นได้อีกมั้ย
  • มันเอาไปใช้กับโจทย์อื่นได้รึเปล่า
  • และอื่นๆ

สรุปได้ไม่ยาก: ในขณะที่นักพัฒนากำลังไตร่ตรองชื่อของ Entities ภายใต้กรอบของ Methodology เขาจะสามารถเจอโจทย์ที่ตั้งมาไม่ชัดเจนได้ตั้งแต่ก่อนเริ่มเขียนโค้ดด้วยซ้ำ

จะตั้งชื่อ Entity ยังไงถ้ายังไม่เข้าใจดีพอว่ามันแก้โจทย์อะไรได้บ้าง, แล้วจะแบ่งงานเป็น Entities ได้ยังไงถ้ายังไม่เข้าใจมันดีพอ?

จะกำหนดยังไงดี? (How to formulate it?)​

เพื่อกำหนดโจทย์ที่ถูกแก้ด้วย Features คุณต้องเข้าใจตัวโจทย์เองก่อน และนี่เป็นความรับผิดชอบของ Project Manager และ Analysts

Methodology ทำได้แค่บอกนักพัฒนาว่าโจทย์ไหนที่ Product Manager ควรให้ความสำคัญ

@sergeysova: Frontend ทั้งหมดโดยหลักการคือการแสดงผลข้อมูล, Component ใดๆ ก็ตาม อย่างแรกสุดคือแสดงผล, ดังนั้นโจทย์แค่ "ให้แสดงอะไรบางอย่างให้ผู้ใช้ดู" จึงไม่มีคุณค่าในทางปฏิบัติ

แม้จะไม่นับรวมธรรมชาติของ Frontend ก็ยังถามได้ว่า "ทำไมฉันต้องแสดงให้คุณดู", ถามไปเรื่อยๆ จนกว่าจะเจอความเจ็บปวดหรือความต้องการของผู้บริโภค

ทันทีที่เราเข้าถึงความต้องการพื้นฐานหรือจุดเจ็บปวด (Pain points) เราก็สามารถย้อนกลับมาดูได้ว่า Product หรือ Service ของคุณจะช่วยผู้ใช้ให้บรรลุเป้าหมายได้อย่างไร

งานใหม่ๆ ใน Tracker ของคุณมุ่งเป้าไปที่การแก้ปัญหาทางธุรกิจ และธุรกิจก็พยายามแก้ปัญหาของผู้ใช้ในขณะเดียวกันก็หาเงินจากมันด้วย นั่นหมายความว่าแต่ละงานมีเป้าหมายบางอย่าง แม้ว่าจะไม่ได้เขียนไว้ในคำอธิบายก็ตาม

นักพัฒนาต้องเข้าใจอย่างชัดเจนว่างานนี้มีเป้าหมายอะไร, แต่ไม่ใช่ทุกบริษัทจะสามารถสร้างกระบวนการที่สมบูรณ์แบบได้ (ถึงแม้นั่นจะเป็นอีกเรื่องนึง) แต่อย่างน้อย นักพัฒนาก็สามารถ "Ping" หา Manager ที่เกี่ยวข้องเพื่อหาคำตอบและทำงานในส่วนของตัวเองให้มีประสิทธิภาพได้

แล้วประโยชน์คืออะไร? (And what is the benefit?)​

ทีนี้มาดูกระบวนการทั้งหมดตั้งแต่ต้นจนจบกัน

1. เข้าใจโจทย์ของผู้ใช้​

เมื่อนักพัฒนาเข้าใจ Pain point และวิธีที่ธุรกิจจะตอบโจทย์นั้น เขาสามารถเสนอ Solution ที่ธุรกิจอาจนึกไม่ถึงเนื่องจากข้อจำกัดทางเทคนิคของการทำเว็บ

แต่แน่นอน ทั้งหมดนี้จะเวิร์คก็ต่อเมื่อนักพัฒนาไม่ได้เมินเฉยต่อสิ่งที่กำลังทำและเหตุผลที่ทำ ไม่งั้น จะมี Methodology และแนวทางต่างๆ ไปทำไม?

2. การจัดโครงสร้างและลำดับ​

ด้วยความเข้าใจในโจทย์ โครงสร้างที่ชัดเจนจะเกิดขึ้นทั้งในหัว ใน Task งาน และในโค้ด

3. เข้าใจ Feature และส่วนประกอบของมัน​

หนึ่ง Feature คือหนึ่งฟังก์ชันที่มีประโยชน์สำหรับผู้ใช้

  • เมื่อหลาย Features ถูก Implement ใน Feature เดียว นี่คือ การละเมิดเส้นแบ่ง (Violation of borders)
  • Feature สามารถแบ่งไม่ได้และโตขึ้นเรื่อยๆ - อันนี้ไม่แย่
  • ที่แย่ - คือเมื่อ Feature ไม่ตอบคำถามที่ว่า "คุณค่าทางธุรกิจสำหรับผู้ใช้คืออะไร?"
  • จะไม่มี Feature ที่ชื่อ "map-office" (แผนที่-ออฟฟิศ)
    • แต่ booking-meeting-on-the-map (จองห้องประชุมบนแผนที่), search-for-an-employee (ค้นหาพนักงาน), change-of-workplace (เปลี่ยนที่นั่งทำงาน) - อันนี้ได้

@sergeysova: ประเด็นคือ Feature ควรมีแค่โค้ดที่ Implement ตัวฟังก์ชันการทำงานนั้นๆ, โดยไม่มีรายละเอียดที่ไม่จำเป็นและ Internal solutions (ในอุดมคตินะ)*

เปิดโค้ด Feature มา แล้วเห็นเฉพาะสิ่งที่เกี่ยวกับโจทย์ - ไม่มีอะไรเกินกว่านั้น

4. กำไร (Profit)​

ธุรกิจน้อยมากที่จะกลับลำ 180 องศา ซึ่งหมายความว่า ภาพสะท้อนของโจทย์ธุรกิจที่อยู่ในโค้ด Frontend คือกำไรที่สำคัญมาก

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

สิ่งที่เรียกว่า "Business Language" ใน Domain Driven Development


กลับสู่โลกความจริง (Back to reality)​

ถ้า Process ธุรกิจเป็นที่เข้าใจและมีการตั้งชื่อที่ดีในขั้นตอน Design - มันก็ไม่ยากเท่าไหร่ที่จะส่งต่อความเข้าใจและ Logic นี้ไปสู่โค้ด

อย่างไรก็ตาม ในทางปฏิบัติ งานและฟังก์ชันมักจะถูกพัฒนาแบบ "โคตร" Iterative (ทำไปแก้ไป) และ (หรือ) ไม่มีเวลามาคิดเรื่อง Design ให้ละเอียด

ผลก็คือ Feature ที่สมเหตุสมผลในวันนี้ ถ้าขยาย Feature นี้ในอีกหนึ่งเดือน อาจจะต้องรื้อโปรเจกต์ใหม่เลยก็ได้

[จากการอภิปราย]: นักพัฒนาพยายามคิดล่วงหน้า 2-3 step โดยคำนึงถึงความต้องการในอนาคต แต่ตรงนี้เขาก็ต้องพึ่งประสบการณ์ของตัวเอง

วิศวกรที่เก๋ามักจะมองข้ามช็อตไป 10 step ทันที และเข้าใจว่า Feature ไหนควรแบ่ง หรือควรรวมกับอันไหน

แต่บางครั้งก็เจองานที่ต้องงัดประสบการณ์มาสู้ และไม่รู้จะไปหาความเข้าใจมาจากไหนว่าจะ Decompose (แตกงาน) ยังไงให้ฉลาด และส่งผลเสียในอนาคตน้อยที่สุด

บทบาทของ Methodology​

Methodology ช่วยแก้ปัญหาของนักพัฒนา เพื่อให้ง่ายต่อการแก้ปัญหาของผู้ใช้

ไม่มี Solution ไหนที่แก้ปัญหาของนักพัฒนาเพื่อนักพัฒนาเท่านั้น

แต่เพื่อให้นักพัฒนาแก้โจทย์ของเขาได้ คุณต้องเข้าใจโจทย์ของผู้ใช้ - ถ้ากลับกัน (เข้าใจแต่โจทย์ตัวเอง) มันจะไม่เวิร์ค

ความต้องการของ Methodology​

เริ่มชัดเจนแล้วว่าเราต้องระบุความต้องการอย่างน้อยสองข้อสำหรับ Feature-Sliced Design:

  1. Methodology ควรอบอกว่า จะสร้าง Features, Processes และ Entities อย่างไร

    • ซึ่งหมายความว่ามันควรจะอธิบายอย่างชัดเจนว่า จะแบ่งโค้ดระหว่างพวกมันยังไง และนั่นหมายความว่าการตั้งชื่อ Entities เหล่านี้ควรถูกกำหนดไว้ใน Specification ด้วย
  2. Methodology ควรช่วยให้สถาปัตยกรรม ปรับตัวตาม Requirement ของโปรเจกต์ที่เปลี่ยนแปลงได้ง่าย

ดูเพิ่มเติม​