Evolutionary Architecture คืออะไร?

jo@sabotender
KBTG Life
Published in
7 min readSep 6, 2023
มีระเบิดเวลาอยู่ในระบบของคุณไหม? (Image by macrovector on Freepik)

ผมว่าใครก็ตามที่มีโอกาสได้ทำงานอยู่กับซอฟต์แวร์ โปรเจค หรือระบบใดระบบหนึ่งมานานมากพอ น่าจะเคยประสบพบเหตุประมาณว่า… ณ จุดแรกเริ่มเดิมทีที่เรา Roll out, Deploy หรือ Go-Live ระบบออกไปครั้งแรก แม้จะมีปัญหาบ้าง ไม่นานทุกอย่างก็เริ่มเข้าที่เข้าทาง ดูแล้วท่าจะไปได้สวย แต่พอเวลาผ่านไปสักพัก มีการปรับปรุงดูแลแก้บั๊ก อัพเกรดเวอร์ชันอันนี้ เพิ่มฟีเจอร์อันนั้นเข้าไปเรื่อย ๆ กลายเป็นว่าซอฟต์แวร์เราเริ่มมีปัญหาทีละนิด ทำงานช้าลงบ้าง มีช่องโหว่บ้าง รับโหลดได้น้อยลง ตัวซอร์สโค้ดเองก็เริ่มซับซ้อนและอ่านเข้าใจได้ยากขึ้น กลายเป็นสิ่งที่ผมได้ยินหลายคนเรียกว่า “ระเบิดเวลา”

ในโลกปัจจุบันที่ Agile และ DevOps เข้ามามีบทบาทสำคัญ เรา Embrace Changes เข้ามาทำกันบ่อยขึ้นและ Deploy กันถี่ขึ้น ผมเห็นคนที่ตระหนักถึงระเบิดเวลาได้ก่อนมักจะจัดเทศกาล Re-Architecture บ้าง เทศกาล Non-Functional Test บ้าง จุดมุ่งหมายก็เพื่อรีเซ็ทตัวนับของระเบิดเวลานั้นให้กลับมาเป็นศูนย์ ตั้งต้นนับใหม่ แล้วตัวนับก็มาถึงจุดที่ต้องจัดเทศกาลครั้งใหม่ แต่ละครั้งใช้ Resource มากมาย เป็นแบบนี้วนไป วัฏจักรอีหรอบนี้ดูไม่เข้ากับวิถี Agile กับ DevOps เอาเสียเลย

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

ในโลกปัจจุบันที่ Agile และ DevOps เป็นที่แพร่หลาย ทำอย่างไรเราจะสามารถ Embrace Change เข้ามาทำได้อย่างต่อเนื่อง โดยที่ยังรักษาคุณสมบัติที่ดีของระบบหรือซอฟต์แวร์ของเราเอาไว้ได้ เปรียบได้กับการ “วิวัฒนาการ” ไปข้างหน้า และนี่คือแนวคิดเริ่มต้นของ Evolutionary Architecture ที่เป็นสาระสำคัญของบทความในวันนี้

ช่วงนี้ตัวผมเองและผองเพื่อนกำลังง่วนอยู่กับโจทย์ใหม่ที่ได้รับ คือการพลิกโฉม (Transformation) การออกแบบระบบของบริษัทให้ดีขึ้น พวกผมเลยกำลังทดลองหลายสิ่งหลายอย่างกันอยู่ และถึงแม้ว่าเราจะยังไม่มีคำตอบสำหรับโจทย์นี้ แต่มันก็ดลใจให้ผมไปค้นเอาหนังสือเล่มนี้ขึ้นมาอ่าน (ที่ต้องค้นเพราะบ้านรกมากน่ะครับ)

เล่มนี้ของผมเอง ปกยับเหมือนหยิบอ่านบ่อย แต่เปล่าเลย ยับตั้งแต่ขนส่งมาแล้ว

Building Evolutionary Architectures — Automated Software Governance

สังเกตหน้าปกจะเห็นว่ามีผู้แต่งหลายคนทีเดียวครับ Neal Ford, Rebecca Parsons, และ Patrick Kua & Pramod Sadalage

เล่มนี้เป็น 2nd Edition ที่ออกมาเมื่อเดือนธันวาคม 2022 ดองมาก็เกินครึ่งปีละ (ตัว 1st Edition ออกเมื่อปี 2017 ต้องบอกแบบอาย ๆ ว่าผมอ่านช้าไป 5 ปีกว่าเลยทีเดียว) หนังสือไอทีนี่ยิ่งทิ้งไว้นาน ยิ่งเซ็งเป็ดครับ ถ้าเนื้อหาไม่ตกยุคไปก่อน ก็อาจจะมี Edition ใหม่ออกมาแทน อ๊ะ ทำไมผมไม่อ่านออนไลน์น่ะเหรอ? ก็เพราะถ้าออนไลน์ผมจะไม่ได้อ่านครับ มันจะพาลไปเล่นอย่างอื่นตลอดเลย

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

Evolutionary Architecture คือสิ่งใหม่?

ย้อนอดีตไปตอนผมเรียนการเขียนโปรแกรมแบบ OOP (Object Oriented Programming: การเขียนโปรแกรมเชิงวัตถุ) ใหม่ ๆ ผมยังจำได้ว่าตำราหลายเล่มมีการเปรียบเปรยการสร้างซอฟต์แวร์กับการสร้างตึกรามบ้านช่อง แต่มีบางเล่มเท่านั้นที่ให้แง่คิดกับผมว่าศาสตร์ของคอมพิวเตอร์นั้นมีอายุน้อยกว่าศาสตร์ในการสร้างที่อยู่อาศัยมาก เราเพิ่งมีคอมพิวเตอร์ใช้ได้ไม่นาน แต่ในทางกลับกันเราสามารถสร้างสิ่งก่อสร้างที่ใหญ่โตมโหฬารและซับซ้อนได้ตั้งแต่อดีตกาลนานมาแล้ว พอทราบดังนั้นผมก็ใช้เวิร์บทูเดาเหมาเอาเลยว่า คำศัพท์คำว่า “Architecture” ที่ใช้กันอยู่ในวงการคอมพิวเตอร์นี่มันน่าจะหยิบยืมมาจากวงการสิ่งก่อสร้างอย่างแน่นอน

แต่คอมพิวเตอร์นั้นพัฒนาไปไวมาก ๆ หนังสือได้ให้ความเห็นไว้ว่าการมาของคู่หู Agile และ DevOps ทำให้เราเริ่มเห็นได้ชัดว่าการพัฒนาซอฟต์แวร์นั้นไม่เหมือนกับการสร้างบ้านเสียแล้ว แต่หากเทียบเคียงได้กับคำว่า “วิวัฒนาการ” หรือ “Evolution” ซึ่งผมว่าพวกเรามักจะได้ยินคำนี้ในแวดวงแบบพันธุวิศวกรรม ชีววิทยา อะไรประมาณนี้ ถ้าพูดถึงคำว่า Evolution หัวผมก็จะนึกถึงการเปลี่ยนแปลงที่เกิดขึ้นทีละเล็กทีละน้อย อย่างต่อเนื่องยาวนานจนถึงจุด ๆ หนึ่ง เกิดเป็นของที่มีหน้าตาหรือคุณสมบัติแตกต่างไปจากเดิมมาก เช่น คนมีวิวัฒนาการมาจากลิง อะไรประมาณนั้น หนังสือบอกว่านี่แหละสอดคล้องกับสิ่งที่เราปฏิบัติกันในปัจจุบัน เราซอย Change บนซอฟต์แวร์เราออกเป็นชิ้นเล็ก ๆ พัฒนายิก ๆ ทดสอบเยอะ ๆ และ Deploy บ่อย ๆ และจะยิ่งบ่อยขึ้น ถี่ขึ้นอีกในอนาคต

แมงกะพรุนเป็นสัตว์ที่มักถูกยกเป็นตัวอย่างเมื่อพูดถึงวิวัฒนาการในระดับเซลล์ (Photo by Capture Blinks)

ทีนี้ผมก็พอเข้าใจว่า การที่จะเรียกว่า “วิวัฒน์” ได้นั้นก็ต้องพัฒนาไปในทางที่ดีขึ้นใช่ไหมล่ะครับ ไม่ใช่ค่อย ๆ ถอยหลังลงคลอง หนังสือจึงให้มุมมองไว้ว่า

ในขณะที่เราแก้ไขปรับปรุงซอฟต์แวร์ของเราทีละเล็กละน้อยแต่บ่อย ๆ นั้น ซอฟต์แวร์ของเราต้องเกิดการเปลี่ยนแปลงไปในทิศทางที่ถูกต้อง

คำว่า “การเปลี่ยนแปลง” ในที่นี้ ผู้แต่งหนังสือไม่ได้หมายถึงฟีเจอร์หรือฟังก์ชันของระบบครับ แต่หมายถึง “Architectural Characteristics” ของระบบ ถ้าผมพยายามแปลตรงตัวก็จะแปลว่า “คุณลักษณะทางสถาปัตยกรรม” อาจจะฟังดูยากหน่อย เอาเป็นว่าใน KBTG เราเรียกเจ้าคุณลักษณะทางสถาปัตยกรรมนี้ว่า “Non-Functional Requirements” ครับ นั่นก็คือพวก Performance, Scalability, Security, Maintainability เหล่านี้นั่นแหละ บางตัวคุ้นน้อยหน่อย เช่น Legality, Auditability ฯลฯ ในหนังสือเรียกรวมคำศัพท์พวกนี้ว่า “ -ilities ” (เพราะศัพท์ภาษาอังกฤษของคำพวกนี้มักลงท้ายด้วย -ility) และบอกอีกว่ามันมีอยู่เยอะแยะ เราต้องจัดลำดับความสำคัญว่าอะไรสำคัญกับซอฟต์แวร์ของเรา

พอได้รู้ความหมาย ผมเลยรู้สึกว่าสิ่งนี้ไม่ใช่สิ่งประดิษฐ์ชิ้นใหม่แบบเอี่ยมอ่อง 100% แต่เป็นการจับเอาสิ่งที่เกิดขึ้นในปัจจุบันออกมาในมุมมองใหม่ แล้วนิยามเป็นคำศัพท์เฉพาะขึ้นมาเพื่อสื่อสารมุมมองนั้น และนั่นคือ “Evolutionary Architecture” สถาปัตยกรรมที่ทำให้เราวิวัฒนาการไปในทิศทางที่ถูกต้อง

คำศัพท์ที่สำคัญอีกคำหนึ่งที่หนังสือนิยามไว้ก็คือ “Fitness Functions” ซึ่งไม่เกี่ยวอะไรกับยิมหรือฟิตเนสที่เราไปออกกำลังกายนะครับ ในหนังสือบอกว่าได้ยืมศัพท์คำนี้มาจากวิชา Evolutionary Computing อีกทีหนึ่ง ผมเองก็ไม่รู้จักวิชานี้ ไม่รู้ว่าบ้านเรามีสอนไหมนะครับ แต่เอาเป็นว่าการที่เราจะสร้าง Evolutionary Architecture ได้นั้น เราต้องมีเจ้า Fitness Functions นี่แหละเป็นกุญแจสำคัญ

Fitness Functions คือสิ่งใหม่?

ผมเองไม่คุ้นกับคำ ๆ นี้เลย แม้ว่าหนังสือ Edition แรกจะออกมาเกิน 5 ปีแล้ว ไม่แน่ใจเหมือนกันว่ามันถูกใช้แพร่หลายหรือไม่อย่างไร แต่จากที่ได้อ่านดู ผมมั่นใจเลยแหละว่ามันเป็นเครื่องมือที่หลายคนเคยใช้ ใช้อยู่ และใช้ต่อ แต่ด้วยความหลากหลายของมัน ผู้แต่งหนังสือบอกว่าที่เขาให้นิยามมันใหม่ว่าเป็น Fitness Functions เพื่อที่จะจัดกลุ่มเครื่องมืออันหลากหลายพวกนี้เข้ามาใช้ในจุดประสงค์ใหญ่เดียวกัน นั่นคือการสร้าง Evolutionary Architecture

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

ถ้าเราว่ากันที่นิยาม เอาเป็นว่าถ้ามีคนถามผม ผมก็จะตอบว่า

Fitness Functions คืออะไรก็ได้ที่เราเอามาใช้ประเมิน Architectural Characteristics หรือ Non-Functional Requirements หรือที่หนังสือเรียกอีกอย่างว่า -ilities ทั้งหลาย เพื่อที่จะรักษาระดับของมันให้เป็นไปตามที่เราต้องการ นั่นคือถ้าเราอยากให้สิ่งใด วิวัฒน์พัฒนา เราก็ต้องตรวจวัด ต้องประเมิน ต้องควบคุมป้องกันไม่ให้สิ่งนั้นถอยหลังลงคลอง

ผมชอบการเปรียบเปรยที่ผู้แต่งให้ไว้ในหนังสือประมาณนี้ครับ มันเห็นภาพชัดดี ผมสรุปไว้ให้ตามด้านล่าง

ถ้าเราแบ่งคุณลักษณะของซอฟต์แวร์เป็น Functional (หรือเรียกว่า Domain) และ Non-Functional (หรือ Architectural Characteristics) เราเขียน Unit Tests เพื่อควบคุมคุณภาพเชิง Functional ของระบบฉันใด เราก็สร้าง Fitness Functions เพื่อควบคุมคุณภาพเชิง Non-Functional ของระบบฉันนั้น

“ -ilities ” ในมาตรฐาน ISO 25010 ที่ว่าด้วย Software Quality Model

หนังสือได้แบ่งประเภทของ Fitness Functions ไว้หลายแบบตามคุณลักษณะที่แตกต่างกัน แต่ผมว่ามันทฤษฎีจ๋ามากไปหน่อย เลยขอยกเอาตัวอย่างที่หนังสือให้ไว้มาชวนคุยเลย ให้เห็นว่า Fitness Functions แท้จริงไม่ใช่สิ่งใหม่ครับ และที่สำคัญคืออยากให้เห็นความหลากหลายของมันอย่างที่กล่าวไว้ข้างบน

ตัวอย่างแรกคือการเทสครับ ไม่ว่าจะเป็น Unit Test, Functional Test, การทดสอบแบบ Manual โดย QAs ตลอดจนการทดสอบตามหลักการ BDD (Behavior-Driven Development) ล้วนถือเป็น Fitness Functions ได้ทั้งสิ้น ในส่วนนี้ผมเองกลับรู้สึกว่ามันไม่ค่อยสอดคล้องกับที่ผู้เขียนบอกไว้ตั้งแต่ต้นครับว่า Fitness Functions โฟกัสไปที่การทดสอบ Architectural Characteristics เพราะผมว่าการทดสอบพวกนี้โฟกัสไปที่การทดสอบ Functional Domain ซะมากกว่า

ถัดมามีการกล่าวถึงเทคนิคการทำ Synthetic Transactions ซึ่งหมายถึงการทำ Transactions ปลอม ๆ ให้วิ่งเข้าสู่ระบบ แล้วทำการเฝ้าดู (Monitor) ว่าทำงานถูกต้องหรือไม่ โดย Transactions ปลอมอาจจะสร้างโดยการติด Flag อะไรบางอย่างไว้เพื่อให้ระบบทราบว่านี่คือของปลอมแล้วไม่ต้องประมวลผลหรือบันทึกลงฐานข้อมูลจริง ผู้แต่งหนังสือยังเน้นว่าการ Monitor เพียงอย่างเดียวไม่ถือว่าเป็น Fitness Functions แต่ต้องมีการ Alert เมื่อตรวจพบสิ่งผิดปกติด้วย จึงจะเรียกได้ว่าเป็น Fitness Functions ทั้งยังกล่าวเชื่อมโยงไปถึงเทคนิค MDD (Monitoring-Driven Development) ซึ่งตัวผมเองชอบ ODD (Observability-Driven Development) มากกว่า และผมเองไม่ใช่แฟนของ Synthetic Transactions สักเท่าไร ผมว่ามันมีความเสี่ยงในการใช้งานอยู่พอสมควร โดยเฉพาะใน KBTG ที่เราทำงานกับ Financial Transactions กันเยอะมาก

ผมตกใจเล็กน้อยเมื่ออ่านไปเจอกับคำว่า Fitness Function-Driven Architecture พลางคิดว่าหนังสือน่าจะอธิบายต่อไปในบทหลัง ๆ ซึ่งอาจจะเป็นโชคดีที่ผมยังอ่านไปไม่ถึง ศัพท์ใหม่ ๆ มาอีกแล้ว

เครื่องมืออื่น ๆ ที่ถูกกล่าวถึงอีกก็มี Dependabot กับ Synk สำหรับใช้ในการตรวจสอบ Release, Version, Security Issue ต่าง ๆ ของซอฟต์แวร์หรือ Library ต่าง ๆ โดยผมเองใช้ Snyk เป็นการส่วนตัวอยู่ครับ ตัวแรกไม่เคยใช้ แต่ก็พอจะคุ้น ๆ อยู่เหมือนกัน

เครื่องมือในงาน APIs ก็มีการกล่าวถึงด้วยเช่นเดียวกัน

  • OpenAPI.Tools ชุดเครื่องมือสำหรับงาน APIs แทบจะครอบจักรวาล จัดไว้เป็นหมวดหมู่ตามการใช้งาน
  • Spectral เป็น Linter สำหรับงาน APIs ช่วยในการบังคับใช้ Style Guide กับ APIs ของเรา

หนังสือยังกล่าวถึงการทดสอบระบบตามหลักการ Consumer-Driven Contracts ในโลกของ Microservices และเครื่องมือที่ใช้ในการทดสอบชื่อ Pact

การทำงานของ Pact.io ตามหลักการ Consumer-Driven Contracts

Consumer-Driven Contract Testing เป็นหลักการทดสอบที่นิยมใช้กับ Microservice Architecture โดยผู้ที่เป็นฝ่ายใช้บริการ หรือ Service Consumers จะเป็นฝ่ายจัดทำชุดสำหรับทดสอบให้กับผู้ที่เป็นฝ่ายให้บริการ หรือ Service Provider ซึ่งแต่ละ Consumer ก็จะส่งมอบชุดทดสอบที่ประกอบไปด้วยฟีเจอร์ที่ตนเองใช้งานหรือสนใจให้กับ Provider นำไปรันเพื่อทดสอบ Service ของตนเอง เมื่อ Consumer เป็นฝ่ายจัดทำชุดทดสอบเอง ก็จะมั่นใจได้ว่าชุดทดสอบนั้นทดสอบในสิ่งที่ตัวเองใช้งานและต้องการจริง ๆ ส่วน Provider ก็มีหน้าที่ทำให้ชุดทดสอบทั้งหมดที่ Consumers ให้มานั้นรันผ่านอยู่ตลอดเวลา

การทดสอบในลักษณะนี้ ผู้แต่งหนังสือเขาถือว่าเป็นรูปแบบหนึ่งของ Fitness Function และมีคำเก๋ ๆ เรียกว่า Engineering Safety Net ซึ่งผมก็เพิ่งเคยได้ยินอีกนั่นแหละ ถ้าแปลเป็นคำไทยแล้วคงให้ความรู้สึกแปลกพิลึก

ถึงตรงนี้จะเห็นว่าส่วนใหญ่จะเป็นเครื่องมือในการทดสอบ ตรวจสอบ ตรวจวัด ใจความสำคัญก็คือตรวจวัดแล้วต้อง Alert ต้อง Notify ให้ได้เมื่อพบข้อผิดพลาด อาจจะใช้คำว่า Continuous Verification ก็ได้เหมือนกัน ตัวอย่างที่หนังสือยกมายังมีอีกพอสมควรเลย รออ่านกันต่อในย่อหน้าที่ว่าด้วยเรื่องของการ Governance ครับ

Engineering Incremental Changes คือสิ่งใหม่?

สาระสำคัญอีกส่วนหนึ่งของ Evolutionary Architecture คือการที่เราสามารถทำการเปลี่ยนแปลงให้เกิดขึ้นทีละเล็กทีละน้อยได้อย่างต่อเนื่อง (ถ้าทำทีละน้อยแล้วยังใช้เวลานานอีก หรือนาน ๆ ทำที อันนี้อาจจะเรียกว่า อู้ หรือ ขี้เกียจ นะครับ) ดังนั้นหนังสือก็จะมีส่วนที่อธิบายถึง DevOps ที่ว่าด้วยเรื่องของ Continuous Integration (CI), Continuous Delivery (CD) และ Continuous Deployment (CD) ซึ่งในปัจจุบันผมว่าทุกคนต้องรู้จักกันอยู่แล้วไม่มากก็น้อยแหละ (แต่ตอนหนังสือ Edition แรกตีพิมพ์เมื่อห้าปีก่อนอาจจะยังไม่ค่อยมีคนรู้จักสักเท่าไร) ผู้แต่งหนังสือยังได้กล่าวต่อไปถึงการนำเอา Fitness Functions ที่เราได้สร้างขึ้นไปผูกไว้เป็น Stage หรือขั้นตอนหนึ่งของ DevOps Pipelines เพื่อให้เราได้ผลลัพธ์ของการรัน Fitness Functions กลับมาในลักษณะ Feedback Loop ที่รวดเร็วทันใจ

หนังสืออธิบายลากยาวไปถึง Changes ที่เกิดขึ้นในฝั่งของผู้ใช้งานระบบเลยทีเดียว อธิบายถึงกรณีที่ถึงเราจะสามารถ Deploy ระบบได้อย่างรวดเร็วด้วย Deployment Pipelines แต่เราอาจจะยังไม่อยากให้ผู้ใช้งานระบบใช้ฟีเจอร์หรือฟังก์ชันใหม่ที่เราเพิ่ง Deploy ไปในทันที ก็จะมีการแนะนำ Design Pattern อย่าง Feature Toggles มาใช้ร่วมด้วยเพื่อทำให้เราสามารถ “ปิด” ฟีเจอร์บางอย่างเอาไว้ก่อน พอถึงตรงนี้ผมก็อ้าปากกว้างมากกว่าเดิม ไม่ใช่เพราะกำลังหาวนะครับ แต่ด้วยเหตุที่ว่าขอบเขตของ Evolution Architecture นี่มันช่างกว้างขวาง สามารถเชื่อมโยงเอาเรื่องของ Design Patterns ต่าง ๆ เข้ามาได้อีก

Architectural Governance คือสิ่งใหม่?

ผมเองรู้จักกับพี่ ๆ เพื่อน ๆ Enterprise Architect มาเพียงพอที่จะรู้ว่าการ Governance ให้องค์กรขนาดใหญ่แบบ KBTG ที่ทำการพัฒนาและดูแลระบบงานมากมายให้มี Architecture ที่ดีนั้นเป็นโจทย์ที่ทั้งท้าทายและทรมาน :P

มันเป็นสิ่งที่เราทำและปรับปรุงมาอย่างต่อเนื่อง แต่เราก็ยังมีสิ่งที่ปรับปรุงให้ดีขึ้นได้อีกมาก ต้องบอกเลยว่าผมเองได้เปิดโลกทัศน์ใหม่ เมื่อหนังสือบอกผมว่า

จง Automate Governance ด้วย Fitness Functions สิ!

ผมขอสารรูป เอ้ย! สารภาพว่าผมไม่เคยคิดในมุมนี้มาก่อน พอได้คิดดี ๆ ก็ไม่แปลกใจเลย เพราะ Fitness Functions ก็คือ “การทดสอบและตรวจสอบ” นั่นเอง เหมือนเส้นผมบังภูเขา แต่ขอสปอยไว้ก่อนเลยว่า หลักการมันฟังดูง่าย แต่พอเอามาทำจริง ไม่ได้ง่ายดายขนาดนั้นครับ ต่อมาหนังสือได้อธิบายทฤษฎีเพิ่มเติมด้วยการกล่าวถึงประเภทของ Fitness Functions ที่สัมพันธ์กับระดับของการ Governance ออกเป็น 4 ระดับด้วยกัน ได้แก่

  1. Code
  2. Application
  3. Integration
  4. Enterprise

มาดูตัวอย่างของแต่ละระดับกันหน่อยครับ

Code-Level Fitness Functions

สำหรับระดับ Code หนังสือกล่าวถึงเครื่องมือที่ผมคิดว่าทุกคนน่าจะรู้จักกันดี อย่าง SonarQube และพวก Linters ทั้งหลาย เช่น Staticcheck สำหรับภาษา Go, SQL-lint สำหรับภาษา SQL ฯลฯ เครื่องมือเหล่านี้จะทำการสแกนโค้ดของเราเพื่อวิเคราะห์คุณลักษณะต่าง ๆ ออกมาว่าโค้ดของเราดีหรือไม่ดีอย่างไร เครื่องมืออีกตัวหนึ่งที่ใช้สแกนเหมือนกัน แต่เป็นการสแกนในระดับ Library ก็คือ Black Duck ครับ ทีนี้หันกลับมามอง KBTG บ้าง เรา Governance ในระดับ Code กันอย่างเข้มข้น เราสแกนกันหนักมาก น้ำตาจะไหล T_T

อีก Metric หนึ่งที่น่าสนใจในการวัดคุณภาพของโค้ดก็คือ Cyclomatic Complexity (CC) แปลง่าย ๆ หน่อยก็คือความซับซ้อนของโค้ด ซึ่งสะท้อนไปถึง Maintainability ของ Code ในแง่ที่ว่าเราสามารถทำความเข้าใจโค้ดนั้นได้ง่ายหรือไม่ ความเสี่ยงในการแก้ไขโค้ดที่เราไม่เข้าใจหรือเข้าใจมันได้ยากนั้นสูงหรือต่ำเพียงใด ตัวผมเองรู้สึกว่ามันก็คือส่วนหนึ่งของ Technical Debts ดี ๆ นี่เอง สำหรับภาษา Java หนังสือแนะนำเครื่องมือชื่อ Crap4j ที่เข้ามาช่วยตรงนี้ ผู้เขียนยังกล่าวถึง TDD (Test-Driven Development) ด้วยว่าเป็น Practice ที่ช่วยทำให้ค่า CC ต่ำ หรือลดความซับซ้อนของโค้ดได้ดี

หนังสือยังได้แนะนำเครื่องมือที่ชื่อ JDepend (สำหรับ Java) และ NDepend (สำหรับ .NET) ที่ใช้ในการวิเคราะห์ Dependency ในระดับ Packages เพื่อควบคุมสิ่งที่เรียกว่า Coupling ที่เกิดขึ้นไม่ให้มากเกินไป ผมเองเคยลองเล่นเครื่องมือพวกนี้อยู่บ้าง แต่สุดท้ายไม่ได้ใช้ เพราะรู้สึกว่าการวิเคราะห์ในระดับ Packages มันมีความยากและซับซ้อนในการทำความเข้าใจและตัดสินใจว่าแบบไหนดีหรือไม่ดี ถ้ามีวิธีใช้ที่ง่าย ๆ ได้ผลลัพธ์แบบชัด ๆ ก็อยากจะเอามาใช้จริงจังอยู่เหมือนกัน

กราฟ Distance of the Main Sequence สำหรับการวิเคราะห์ในระดับ Packages

Application-Level Fitness Functions

สำหรับ Fitness Functions ที่ใช้ Governance ในระดับของ Application จะมีเครื่องมือที่ชื่อ ArchUnit ที่เหมือนกับ JUnit แต่เอาไว้ทดสอบคุณสมบัติเชิง Architecture เช่น การทำ Package Dependency Checks, Class Dependency Checks, Inheritance Checks, Annotation Checks รวมไปถึง Layer Checks ยกตัวอย่างเช่น เวลาเราเขียน Spring Boot Application แล้วเราต้องการให้ Service Layer นั้นเป็น Layer เดียวที่สามารถเรียกใช้ Persistent Layer (DAOs หรือ Repositories) ได้ เราก็สามารถใช้ ArchUnit เขียนโค้ด เพื่อตรวจสอบว่ามีใครแอบไปเรียก Persistent Layer โดยตรงแบบไม่ผ่าน Service Layer หรือไม่ เป็นต้น ส่วนสาย .NET จะมี NetArchTest ที่ใช้ทำงานในลักษณะเดียวกันนี้

หนังสือยังให้ไอเดียการใช้ Fitness Functions ร่วมกับการทำ Canary Releases (Canary Releases คือการที่เราค่อย ๆ ปล่อยให้ผู้ใช้งานระบบเข้ามาใช้งานฟีเจอร์หรือฟังก์ชันใหม่ก่อนเพียงบางส่วน ถ้าทุกอย่างไปได้ดีก็ค่อย ๆ เพิ่มจำนวนผู้ใช้งานขึ้นเรื่อย ๆ) ผู้แต่งหนังสือก็เสนอว่าเราสามารถใช้ Fitness Functions ทำการตรวจวัดสิ่งที่ต้องการได้เลย ถ้าผลออกมาดี ก็ค่อยเพิ่มจำนวนผู้ใช้งานขึ้นไป กรณีนี้เป็นอีกครั้งที่ผมรู้สึกได้ถึงการโยงนำสิ่งที่มีอยู่ก่อนแล้วเข้ามาเป็นหนึ่งในพรีเซนเตอร์ของสิ่งใหม่ :P

น้อน Canary Bird ที่มาของชื่อ Canary Releases

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

Integration-Level Fitness Functions

เมื่อกล่าวถึงเรื่องของ Integration คงหลีกเลี่ยงไม่ได้ที่จะต้องพูดถึง Microservices แต่ผมไม่ค่อยอินกับตัวอย่างแรกที่หนังสือให้ไว้ในส่วนนี้สักเท่าไรครับ นั่นคือการเขียน Fitness Function ฝังเอาไว้ใน Common Images ที่ใช้ Build ออกมาเป็นแต่ละ Microservice เพื่อควบคุม Log Format ให้เป็นมาตรฐานเดียวกัน โดยเน้นว่าให้พ่น Logs ออกมาในจังหวะที่ทำ Integration (ก็คือตอนที่ Microservice หนึ่งมีการเรียกใช้ Microservices อื่น ๆ) และเขียน Fitness Function ขึ้นมาอีกอันหนึ่งทำหน้าที่อ่าน Logs นั้นเพื่อตรวจจับว่ามี Integration ที่ผิดไปจากกฎที่เราวางไว้หรือไม่

อีกกรณีหนึ่งคือการตรวจสอบว่า Communication Messages ได้วิ่งผ่านแต่ละ Microservice ตามที่ได้ออกแบบไว้โดยไม่สูญหาย หรือมีการ Dropped ไปโดยที่เราไม่รู้หรือไม่ หนังสือกล่าวถึงการใช้ Correlation ID เข้ามาช่วย และแน่นอนว่าหนังสือแนะนำให้เขียนเป็น Fitness Function ขึ้นเพื่อตรวจสอบมัน

สาเหตุที่ผมไม่ค่อยอินในตัวอย่างที่กล่าวมาด้านบน เพราะปัจจุบันมันมีเครื่องมือทางด้าน Observability ที่ครอบคลุมความสามารถทั้งในด้าน Logging, Metrics, และ Tracing ที่ใช้งานได้ง่ายกว่าแต่ก่อนและเป็นเครื่องมือที่ถูกออกแบบมาให้เหมาะสมกับงานในแต่ละประเภท ผมยังตะหงิด ๆ อยู่ว่าการที่ไปอ่าน Logs เพื่อตรวจจับการ Integration ที่ผิดกฎนั้นเป็นวิธีที่เหมาะสมจริงหรือ? ส่วนเรื่องของการ Tracing ปัจจุบันมีเครื่องมือที่ใช้ง่ายและมีความสามารถมากกว่าการใช้งาน Correlation ID เช่น DynaTrace และ Jaeger เป็นต้น ส่วนใครที่สนใจเรื่อง Observability ผมแปะลิงก์บทความตอนที่ 1 ไว้ให้ด้านล่างนะครับ มีเป็นซีรีย์เลย เพื่อนผมเขียนเอง

ตัวอย่างที่ผมค่อนข้างจะซื้อก็มีครับ เพราะพบเจอได้บ่อยในการออกแบบ Microservice Architecture ที่มีลักษณะเป็นชั้นหรือ Layers ที่ทำงานร่วมกันของ Orchestration Services และ Domain Services โดยชั้นที่เป็น Orchestration Services จะทำหน้าที่ร้อยเรียงการเรียกใช้ Domain Services ให้เกิดเป็น Business Operation ที่สมบูรณ์ ซึ่งกลุ่มที่เป็น Domain Services นั้นจะทำหน้าที่ให้บริการ Business Functions ย่อย ๆ ที่เป็นอิสระต่อกัน โดยจะไม่มีการเรียกกันเองระหว่าง Domain Services ด้วยกัน การออกแบบในลักษณะนี้พบเห็นได้ใน KBTG ด้วยเช่นกันครับ ซึ่งในบางครั้งเราจะเจอว่ามีการละเมิดหลักการที่ได้ออกแบบกันไว้ เช่น มีการเขียนโปรแกรมให้ Domain Services ไปเรียกหากันเอง หรือแม้กระทั่งมีส่วนของ Front-end ที่ไปนัวเรียก Domain Services กันเองโดยไม่ผ่าน Orchestration Services (ทั้งหมดนี้เกิดเป็นการด้อยค่า Orchestration Services ครับ น่าเศร้าจริง ๆ) กรณีประมาณนี้ถ้าเกิดขึ้นเยอะ ๆ ก็จะทำให้โครงสร้างโดยรวมของระบบเสียไป ส่วนในเชิงของการ Integration อาจจะทำให้เกิดสิ่งที่เราเรียกว่าสปาเก็ตตี้ได้ในที่สุด ดังนั้นการที่จะมีเครื่องมืออะไรสักอย่างที่คอยเตือนเวลามีการละเมิดกฎของการออกแบบเช่นนี้ ผมว่าน่าสนใจเลยทีเดียว

Netflix Chaos Monkey ลิงมีหลายประเภทด้วยนะ

ตัวอย่างที่อลังการที่สุดในระดับของการ Integration ที่หนังสือกล่าวถึงคือ Chaos Engineering ครับ ผมนับถือผู้แต่งเลยทีเดียวที่ก็สามารถดึงเอาเจ้าสิ่งนี้มาอยู่ภายใต้คอนเซ็ปต์ของ Fitness Functions ได้ ก็อย่างที่ผมกล่าวไว้ก่อนหน้านี้ครับ พอคอนเซ็ปต์หรือนิยามมันกว้าง เครื่องมือที่เอามาใช้ได้ก็จะหลากหลายสุด ๆ ตามไปด้วย

Enterprise-Level Fitness Functions

เมื่อตอนต้นปีผมได้มีโอกาสไปจอยโปรเจคยักษ์ใหญ่อันหนึ่งที่มีแผนการจะนำระบบงานใหม่มาทดแทนระบบงานที่ใช้อยู่ในปัจจุบันที่ค่อนข้างล้าสมัย ระบบงานนี้เป็นระบบที่สำคัญและมีขนาดค่อนข้างใหญ่ครับ ทีมงานของโปรเจคมีการหารือกันว่าการเปลี่ยนระบบเก่าเป็นระบบใหม่แบบ Big Bang โช้ะเดียวเลยนั้นมีความเสี่ยงสูงมาก ผมยังจำได้ว่าพี่ที่เป็น Senior Solution Architect ของโปรเจคนี้ได้นำเสนอไอเดียในการรันระบบเก่าและระบบใหม่ไปพร้อมกัน โดยมีหลักการว่าให้ Transaction แต่ละอันที่เข้ามานั้นวิ่งเข้าทั้งสองระบบไปเลย จากนั้นก็ทำการเปรียบเทียบกันว่าผลลัพธ์จากการทำงานของระบบใหม่และระบบเก่านั้นเหมือนกันและต่างกันอย่างถูกต้องตามที่ออกแบบไว้หรือไม่ ทำแบบนี้ไประยะหนึ่งจนมั่นใจแล้วว่าระบบใหม่สามารถทำงานได้แบบเนียน ๆ แล้วจึงหยุดการทำงานของระบบเก่าแล้วให้ระบบใหม่ทำงานแทนทั้งหมด ฟังก์ชันที่ทำการเปรียบเทียบผลลัพธ์ระหว่างระบบเก่าและระบบใหม่ในกรณีที่ผมเล่ามานี้ ก็ดันมาตรงกับคอนเซ็ปต์ของ Fitness Functions ในระดับของ Enterprise เสียนี่ โดยหนังสือใช้ศัพท์ว่า Fidelity Fitness Functions ครับ

Evolutionary Architecture คือมุมมองใหม่!

แต่ก่อนนี้ผมคิดว่าการออกแบบระบบให้ดีมีคุณภาพก็เรื่องหนึ่ง ส่วนการรักษาคุณภาพเหล่านั้นให้คงอยู่ไปเรื่อย ๆ ก็เป็นอีกเรื่องหนึ่ง ผมนึกถึงประโยคหนึ่งที่เขาพูดกันว่า “เป็นแชมป์ว่ายากแล้ว แต่การรักษาแชมป์นั้นยากกว่า” หนังสือเล่มนี้ได้เปิดมุมมองใหม่ที่เน้นย้ำให้ผมเห็นความสำคัญของการออกแบบระบบในยุคใหม่ที่นักออกแบบจะต้องเพิ่ม “Changeability” หรือ “Evolvability” เข้าไปใน Architecture ของตัวเอง และสร้างสิ่งที่จะใช้เป็นกลไกในการควบคุมคุณภาพของระบบไม่ให้ลดน้อยถอยลงเมื่อเวลาผ่านไป

การรักษาแชมป์จะไม่ได้เกิดหลังจากคุณได้แชมป์อีกต่อไป แต่คุณต้องคิดและเตรียมการเอาไว้ตั้งแต่แรก

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

หนังสือยังย้ำเตือนสติผมในแง่ของการทำงานแบบ Agile ที่ปัจจุบันเราต่างมุ่งทำงานที่อยู่ตรงหน้าในแต่ละ Sprint ให้สำเร็จลุล่วงไป Sprint แล้ว Sprint เล่า ในขณะที่เราทำ Sprint Review ซึ่งเกือบทั้งหมดเป็นการมุ่งเน้นไปที่ฟีเจอร์หรือฟังก์ชันของระบบ แต่มันยังมี Non-Functional Requirements หรือที่หนังสือเรียกว่า Architectural Characteristics ซ่อนอยู่เบื้องหลังที่เราจะต้องค่อย ๆ ให้มัน “วิวัฒนาการ” ไปอย่างถูกต้องและมี Feedback Loop กลับมาที่ผู้พัฒนาหรือผู้ออกแบบอย่างรวดเร็วเฉกเช่นเดียวกับที่ Product Owner ให้ Feedback เรื่องของฟังก์ชันและฟีเจอร์กับเราด้วยเช่นเดียวกัน

Expectation vs Reality (from monkeyuser.com)

หนังสือยังเน้นถึงความสำคัญของ “การออกแบบระบบ” ในการทำงานแบบ Agile ที่ผมเองก็พบเห็นอยู่บ่อยครั้ง ที่ทีมงานไปมุ่งเน้นที่ความรวดเร็วในการทำงาน รีบส่งมอบงาน จนกลายเป็นลักษณะ “โค้ดไปออกแบบไปภายใน Sprint” ผู้แต่งหนังสือได้เล่าถึงประสบการณ์ของเขาว่าคำถามหนึ่งที่เขามักเจอคือ “โปรเจคที่ใช้ Agile ต้องออกแบบ Architecture ด้วยหรือ?” นั่นแสดงให้ผมเห็นว่าต่างประเทศเขาก็มีความเข้าใจที่คลาดเคลื่อนคล้าย ๆ กับคนไทยเหมือนกันแฮะ ประมาณว่า Agile นั้นเน้นไปที่ความคล่องตัว (Agility) ดังนั้น Agile จะไม่ทำอะไรที่เป็น Overhead ไม่ทำอะไรที่ไม่จำเป็น และหนึ่งในของที่ไม่จำเป็นก็คือ “การ Design” นั่นเอง แต่จริง ๆ แล้วมันขึ้นกับความซับซ้อนของงาน ผู้แต่งหนังสือยกตัวอย่างเปรียบเทียบกับการสร้างบ้านว่า ถ้าบ้านที่จะสร้างนั้นเป็นบ้านของน้องหมาหลังเล็ก ๆ เราแค่จินตนาการภาพในหัวกับมีวัสดุอุปกรณ์ครบ ก็สามารถลงมือสร้างได้เลย แต่ถ้าเรากำลังจะสร้างตึกออฟฟิศ 50 ชั้น เราต้องมีแบบ มีแผน และเราต้อง “ทำการออกแบบ” ครับ ในงานไอทีการทำหน้า Web ง่าย ๆ ใช้บันทึกข้อมูลภายในแผนก กับการทำ Website สำหรับให้คนทั้งประเทศจองตั๋วคอนเสิร์ต ต้องการความเข้มข้นในงาน Design ที่แตกต่างกัน

ผู้แต่งหนังสือบอกว่าคำถามที่ถูกต้องคือ

เราจะทำอย่างไรเพื่อลดการ Design ที่ไม่จำเป็นออกจากโปรเจค และทำอย่างไรให้ทีมงานสามารถเริ่มทำงานตามที่ Design ออกมาได้เร็วที่สุด โดยไม่ต้องรอให้ Design เสร็จสมบูรณ์ 100% ทั้งยังรักษาทิศทางที่ถูกต้องเอาไว้ได้

ทำอย่างไรกันดีครับ? ช่วยเสนอแนะแชร์กันเข้ามาในเม้นได้นะครับ

ก่อนจะจบย่อหน้านี้ อยากจะยกประโยคหนึ่งในหนังสือที่ผมชอบมาให้อ่านกัน

The purpose of agile architecture isn’t no architecture; it’s no useless architecture

- Building Evolutionary Architectures 2nd Edition

บทบาทของนักออกแบบ

Evolution (Image by Freepik)

ใน KBTG มีผู้ที่ทำงานเกี่ยวข้องกับการออกแบบซอฟต์แวร์ในหลายระดับ ไม่ว่าจะเป็น (1) Enterprise Architect ที่ทำงานในระดับภาพรวมของทั้งบริษัท (2) Solution Architect ที่ออกแบบระบบเพื่อตอบโจทย์ธุรกิจแบบครบวงจร หรือ End-to-End (3) Technical Lead ที่ออกแบบ Component ต่าง ๆ ภายในซอฟต์แวร์แต่ละตัวให้ทำงานร่วมกันอย่างมีประสิทธิภาพ รวมไปถึง (4) Developer ที่ต้องออกแบบลายมือเวลาเขียนโค้ดให้สวยงาม อ่านทำความเข้าใจได้ง่าย ผมว่านักออกแบบทั้งหลายเป็นทั้งผู้ Governance และผู้ถูก Governance ครับ พวกเรามีหลักการมีกฎบางอย่างที่ต้องทำตาม ในขณะเดียวกันเมื่อออกแบบเสร็จแล้ว พวกเราก็อยากให้สิ่งนั้นทำงานได้ตามที่ออกแบบไว้

ผู้แต่งหนังสือบอกว่า Architect มักจะเขียนนโยบาย หลักการ หรือคำแนะนำ ไว้ในสื่อประเภท Wikis และมักจะทุกข์ทรมานกับการบังคับใช้สิ่งเหล่านั้นที่มันไม่ค่อยได้ผล (อ่านตรงนี้แล้วรู้สึกเหมือนมีมีดมาปักหัวใจสักสองสามเล่ม ฉึก ฉึก ฉึก) แต่ปัจจุบันการที่เรามี DevOps เข้ามา ปัญหานี้จะถูกแก้ได้ด้วยการทำ Continuous Verification ด้วย Fitness Functions

ผู้แต่งหนังสือยังบอกอีกว่าผู้ที่ทำหน้าที่ตั้งต้น เขียนโค้ด ทำ Script ของ Fitness Functions นั้นควรเป็นตัว “Architect” เองนั่นแหละ พูดง่าย ๆ คือคนออกแบบเป็นคนที่รู้ดีที่สุดว่าควรตรวจ ควรควบคุมตรงไหนใช่ไหมล่ะ จากนั้น Developer ก็จะมีหน้าที่ร่วมกันกับ Architect ในการดูแล ปรับปรุง และรักษาผลการรัน Fitness Functions ให้ผ่านอยู่ตลอดเวลาไม่ว่าจะมี Change อะไรเกิดขึ้นกับระบบก็ตาม นอกจากนี้ผมเพิ่งรู้จากหนังสือว่าในต่างประเทศเขามีตำแหน่งงานประมาณ Evolutionary Architect ที่มีหน้าที่สร้าง Fitness Functions และทำให้เกิด Evolutionary Architecture ในองค์กร ผมเองยังไม่เคยเห็นตำแหน่งแบบนี้ในประเทศไทยเหมือนกัน

ผมชอบไอเดียที่ให้เขียนส่วนของการ Governance หรือรายละเอียดของ Fitness Functions เพิ่มเข้าไปใน Architecture Decision Record (ADR) ด้วย เพราะโดยปกติ เราจัดทำ ADR เพื่อบันทึกมูลเหตุของการตัดสินใจต่าง ๆ ที่เกิดขึ้นในการขั้นตอนการออกแบบระบบ การเพิ่มส่วนที่บอกว่าเราจะควบคุมให้การตัดสินใจนั้นคงอยู่ต่อไปได้อย่างไร หรือเราจะรู้ได้อย่างไรเมื่อมีคนละเมิดสิ่งที่ตกลงกันไว้นั้นน่าสนใจมากทีเดียว

ในเชิงของการสร้างหรือ Implement Fitness Functions หนังสือก็เน้นย้ำอยู่หลายครั้งว่า Fitness Functions ควรจะเป็นแค่ “Glue” Codes เท่านั้น (ผมเข้าใจว่าเขาหมายถึงโค้ดที่มีขนาดเล็ก ไม่ซับซ้อน และ “แปะ” ติดไปกับโค้ดหลักของระบบเหมือน “กาว”) แต่จากตัวอย่างหลาย ๆ อันที่หนังสือยกมา ผมว่ามันไม่ง่ายแค่ Glue Codes แล้ว น่าจะเหนื่อยเข้าขั้นเลยแหละ ตรงนี้ก็เป็นอีกจุดหนึ่งที่ผมรู้สึกว่าหนังสือมีเนื้อหาที่ค่อนข้างขัดแย้งกันเองอยู่นิดหน่อย

Architects and Developers Assemble! (Image by jcomp on Freepik)

การจะปรุง Evolutionary Architecture ที่มี Fitness Functions คอยตรวจสอบและนำพาให้ระบบของเรานั้นวิวัฒนาการไปได้อย่างอร่อยนั้น ซอสลับของเมนูนี้ก็หนีไม่พ้นการร่วมมือกันระหว่าง Architect และ Developer ที่ต้องเข้าใจและเห็นพ้องในจุดประสงค์เดียวกัน มีเป้าหมายเดียวกัน เพื่อที่จะออกแบบ สร้าง และดูแลรักษาให้ผลลัพธ์ของการรัน Fitness Functions นั้นเป็นไปตามที่ควรจะเป็นอยู่เสมอ

สุดท้ายแล้ว Architecture ที่สนับสนุนให้ Evolve ได้ง่ายหรือมี Evolvability สูงควรมีหน้าตาเป็นเช่นไร ผมเชื่อว่าท่านผู้อ่านคงพอจินตนาการได้อยู่บ้างจากคอนเซ็ปต์และตัวอย่างมากมายของ Fitness Functions ที่หนังสือได้ให้ไว้ บทความที่ยืดยาวนี้ยังเป็นแค่ส่วนแรกจากเนื้อหาสามส่วนของหนังสือเท่านั้น ไว้มีโอกาสเมื่อไรจะมาเขียนบอกเล่าในส่วนถัดไปให้ได้อ่านกันนะครับ

Happy Evolving Your Architecture!

สำหรับใครที่ชื่นชอบบทความนี้ อย่าลืมกดติดตาม Medium: KBTG Life เรามีสาระความรู้และเรื่องราวดีๆ จากชาว KBTG พร้อมเสิร์ฟให้ที่นี่ที่แรก

--

--

jo@sabotender
KBTG Life

principal DEVelopment eXcellence engineer — DEVX@KBTG / Full-time Daddy / Console Gamer & Gunpla Collector