Architectural Decision Antipatterns (Antipattern ในการตัดสินใจด้าน Architecture)

โปรแกรมเมอร์ Andrew Koenig ให้คำจำกัดความของ antipattern ว่าเป็นสิ่งที่ดูเหมือนไอเดียดีตอนเริ่มต้น แต่กลับพาไปสู่ปัญหา อีกคำจำกัดความหนึ่งของ antipattern คือ กระบวนการที่ทำซ้ำได้แต่ให้ผลลัพธ์ในแง่ลบ antipattern ในการตัดสินใจด้าน architecture ที่พบได้บ่อยที่สุดสามแบบ ซึ่งมักจะเกิดขึ้น (และมักเกิดขึ้นจริง) เมื่อสถาปนิกตัดสินใจ ได้แก่ Covering Your Assets antipattern, Groundhog Day antipattern และ Email-Driven Architecture antipattern antipattern ทั้งสามนี้มักจะเกิดขึ้น ตามลำดับ นั่นคือ การเอาชนะ Covering Your Assets antipattern จะนำไปสู่ Groundhog Day antipattern และการเอาชนะอันนั้นจะนำไปสู่ Email-Driven Architecture antipattern การตัดสินใจด้าน architecture ที่มีประสิทธิภาพและแม่นยำต้องอาศัยการเอาชนะทั้งสาม antipattern นี้

The Covering Your Assets Antipattern (Antipattern แบบ Covering Your Assets)

Covering Your Assets antipattern เกิดขึ้นเมื่อสถาปนิกหลีกเลี่ยงหรือเลื่อนการตัดสินใจด้าน architecture ออกไปเพราะกลัวว่าจะเลือกผิด มีสองวิธีที่จะเอาชนะปัญหานี้ได้ วิธีแรกคือรอจนถึง last responsible moment ก่อนจะตัดสินใจด้าน architecture ที่สำคัญ นั่นคือเมื่อมีข้อมูลเพียงพอที่จะให้เหตุผลและยืนยันการตัดสินใจ แต่ก็ไม่นานเกินไปจนทำให้ทีมพัฒนาต้องรอ หรือทำให้สถาปนิกตกไปอยู่ใน Analysis Paralysis antipattern ที่ติดอยู่กับการวิเคราะห์การตัดสินใจไปตลอดกาล วิธีที่ดีในการหา last responsible moment คือ ถามว่าเมื่อไหร่ที่ต้นทุนของการเลื่อนการตัดสินใจจะสูงเกินความเสี่ยงที่มาจากการตัดสินใจนั้น ดังแสดงใน Figure 21-1 จะสังเกตได้ว่าในช่วงแรกของ time scale การตัดสินใจ ต้นทุน (แสดงด้วยเส้นทึบ) จะต่ำ เพราะใช้เวลากับการ ตัดสินใจน้อย แต่ความเสี่ยง (แสดงด้วยเส้นประ) จะสูง เพราะยังรู้เกี่ยวกับปัญหาหรือ solution น้อย การใช้เวลาเลื่อนการตัดสินใจออกไปมากขึ้นจะเพิ่มต้นทุน แต่ก็ลดความเสี่ยงลงด้วย เพราะสถาปนิกสามารถ วิเคราะห์ปัญหาและทางเลือกที่เป็นไปได้ได้ครบถ้วนมากขึ้น เวลาที่เหมาะสมในการตัดสินใจคือจุดที่ปัจจัย ทั้งสองนี้ตัดกัน และต้นทุนที่เพิ่มขึ้นมีค่ามากกว่าความเสี่ยงที่ลดลง

Last responsible moment

Figure 21-1. Last responsible moment

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

เพื่ออธิบายประเด็นนี้ให้ชัดขึ้น สมมติว่าคุณในฐานะสถาปนิกตัดสินใจว่าข้อมูล product-related reference ทั้งหมด (เช่น product description, weight และ dimensions) ควร cache ไว้ใน service instance ทุกตัวที่ต้องการข้อมูลนั้น คุณตัดสินใจว่าจะทำสิ่งนี้ด้วย read-only replicated cache โดยมี primary cache เป็นเจ้าของโดย Catalog service (cache แบบ replicated หรือ in-memory หมายความว่าถ้ามีการเปลี่ยนแปลงข้อมูลผลิตภัณฑ์หรือเพิ่มผลิตภัณฑ์ใหม่ Catalog service จะ update cache ของตัวเอง แล้วจึง replicate ไปยัง service อื่น ๆ ที่ต้องการข้อมูลนั้นผ่าน replicated cache product) เหตุผลของคุณสำหรับการตัดสินใจนี้คือเพื่อลด coupling ระหว่าง service และแชร์ data ได้อย่างมีประสิทธิภาพโดยไม่ต้องเรียก interservice call อย่างไรก็ตาม ทีมพัฒนาที่ implement การตัดสินใจด้าน architecture นี้พบว่า เนื่องจากข้อกำหนดด้าน scalability ของบาง service การตัดสินใจนี้ จะต้องใช้ในหน่วยความจำแบบ in-process มากกว่าที่มีอยู่ เพราะคุณทำงานร่วมกับทีมเหล่านี้อย่างใกล้ชิด คุณจึงรู้ปัญหานี้ได้อย่างรวดเร็วและปรับการตัดสินใจด้าน architecture ของคุณให้เหมาะสม

Groundhog Day Antipattern (Antipattern แบบ Groundhog Day)

Groundhog Day antipattern เกิดขึ้นเมื่อผู้คนไม่รู้ว่าทำไมสถาปนิกถึงตัดสินใจแบบนั้น จึงถกเถียงเรื่องนี้ ซ้ำแล้วซ้ำเล่าโดยไม่เคยได้ข้อสรุปหรือข้อตกลงสุดท้าย ชื่อ antipattern นี้มาจากภาพยนตร์ปี 1993 เรื่อง Groundhog Day ซึ่งตัวละครของ Bill Murray ต้องใช้ชีวิตวันที่ 2 กุมภาพันธ์ซ้ำไปซ้ำมาทุกวัน

antipattern นี้เกิดขึ้นเพราะสถาปนิกไม่ได้ให้เหตุผลรองรับการตัดสินใจของตัวเอง (หรือให้เหตุผลไม่ครบถ้วน) การให้เหตุผลรองรับการตัดสินใจด้าน architecture ทั้งในแง่เทคนิคและแง่ธุรกิจนั้นสำคัญมาก

ตัวอย่างเช่น สมมติว่าคุณตัดสินใจแยก monolithic application ออกเป็น service ต่าง ๆ เหตุผลของคุณคือ เพื่อ decouple ด้าน functional ของ application เพื่อให้แต่ละส่วนของ application ใช้ virtual machine resource น้อยลง และสามารถดูแลรักษาและ deploy แยกกันได้ แม้นี่จะเป็นเหตุผลเชิงเทคนิคที่ดี แต่สิ่งที่ขาด หายไปคือเหตุผลเชิง ธุรกิจ —กล่าวอีกนัยหนึ่งคือ ทำไมธุรกิจถึงต้องจ่ายเงินให้กับการ refactor ด้าน architecture นี้? เหตุผลเชิง ธุรกิจที่ดีสำหรับการตัดสินใจนี้อาจเป็นการส่งมอบ business functionality ใหม่ได้เร็วขึ้น จึงช่วยปรับปรุง time to market อีกเหตุผลหนึ่งอาจเป็นการลดต้นทุนที่เกี่ยวข้องกับการพัฒนาและปล่อยฟีเจอร์ใหม่

การให้เหตุผลเชิงคุณค่าทางธุรกิจสำคัญมากเวลาให้เหตุผลรองรับการตัดสินใจด้าน architecture มันยังเป็น litmus test ที่ดีในการตัดสินว่าควรจะตัดสินใจด้าน architecture นั้นตั้งแต่แรกหรือไม่ ถ้ามันไม่ได้ให้ คุณค่าทางธุรกิจเลย บางทีสถาปนิกควรพิจารณาการตัดสินใจนั้นใหม่

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

Email-Driven Architecture Antipattern (Antipattern แบบ Email-Driven Architecture)

เมื่อสถาปนิกตัดสินใจและให้เหตุผลรองรับอย่างครบถ้วนแล้ว architecture antipattern อีกแบบหนึ่งมักจะโผล่มา นั่นคือ Email-Driven Architecture antipattern นี้เกิดขึ้นเมื่อผู้คนทำการตัดสินใจด้าน architecture หายไปหรือลืมมันไป หรือแม้แต่ไม่รู้ด้วยซ้ำว่ามีการตัดสินใจนั้นเกิดขึ้น จึงเป็นไปไม่ได้ที่จะ implement มัน การเอาชนะ antipattern นี้ต้องอาศัยการสื่อสารการตัดสินใจด้าน architecture อย่างมีประสิทธิภาพ Email เป็นเครื่องมือที่ดีสำหรับการสื่อสาร แต่เป็นระบบเก็บเอกสารที่แย่มาก

โชคดีที่สถาปนิกสามารถหลีกเลี่ยง Email-Driven Architecture antipattern ได้ง่าย ๆ ด้วยการเรียนรู้วิธี สื่อสารการตัดสินใจด้าน architecture อย่างมีประสิทธิภาพ อย่างแรกคือ อย่าใส่การตัดสินใจไว้ในเนื้อหา อีเมล การทำแบบนั้นจะสร้าง system of record หลายชุดสำหรับการตัดสินใจนั้น เพราะแต่ละอีเมลจะมีสำเนาของ การตัดสินใจแยกกัน แทนที่จะมีอยู่ที่เดียว อีเมลจำนวนมากแบบนี้มักขาดรายละเอียดสำคัญเกี่ยวกับการตัดสินใจ (รวมถึงเหตุผลรองรับ) ซึ่งจะสร้าง Groundhog Day antipattern ขึ้นมาอีกครั้ง นอกจากนี้ ถ้าการตัดสินใจ ด้าน architecture นั้นถูกเปลี่ยนแปลงหรือถูกแทนที่ในภายหลัง ก็ยากที่จะรู้ว่าคนที่เกี่ยวข้องทั้งหมด ได้รับการตัดสินใจฉบับแก้ไขหรือไม่

วิธีที่ดีกว่าคือกล่าวถึงเฉพาะลักษณะและบริบทของการตัดสินใจในเนื้อหาอีเมล แล้วให้ link ไปยัง single system of record ที่เก็บการตัดสินใจด้าน architecture และรายละเอียดที่เกี่ยวข้อง (ไม่ว่าจะเป็น link ไปยังหน้า wiki หรือการอ้างอิงไปยังเอกสารในไฟล์ระบบ)

ลองพิจารณาอีเมลตัวอย่างเกี่ยวกับการตัดสินใจด้าน architecture ต่อไปนี้

“สวัสดีค่ะ Sandra ฉันได้ตัดสินใจเรื่องสำคัญเกี่ยวกับการสื่อสารระหว่าง service ซึ่งส่งผลกระทบโดยตรง กับคุณ กรุณาดูการตัดสินใจนี้ได้ที่ link ต่อไปนี้…​”

สังเกตว่า ในประโยคแรกช่วงต้น มีการกล่าวถึงบริบท (การสื่อสารระหว่าง service) แต่ไม่ได้กล่าวถึงการ ตัดสินใจจริง ๆ ส่วนที่สองของประโยคแรกก็สำคัญเช่นกัน ถ้าการตัดสินใจด้าน architecture ไม่ได้ส่งผลกระทบ โดยตรงต่อคนคนนั้น แล้วจะรบกวนเขาไปทำไม? นี่คือ litmus test ที่ดีในการตัดสินว่า stakeholder คนไหน (รวมถึงนักพัฒนา) ควรได้รับแจ้งการตัดสินใจด้าน architecture โดยตรง ประโยคที่สองในตัวอย่างนี้ให้ link ไปยังตำแหน่งเดียวของการตัดสินใจด้าน architecture ทำให้มี single system of record สำหรับการตัดสินใจ