Domain driven design: ออกแบบให้สวยหรือออกแบบให้ตรง
Inspired by: https://verraes.net/2021/06/split-domain-across-bounded-contexts/
คุณเป็นโปรแกรมเมอร์ ทำระบบภายในให้บริษัทขายส่งแห่งหนึ่ง
ผ่านไป 2 ปี บริษัทขายส่งแห่งนี้ได้ทำการ acquire ซื้อกิจการบริษัทขายส่งอีกแห่งหนึ่งมา
ถึงแม้ว่าบริษัทลูกนี้จะมีโดเมน “ระบบการขาย” เหมือนบริษัทแม่ แต่บริษัทลูกนี้มีระบบการขายที่แตกต่างกับบริษัทแม่เป็นอย่างมาก การจัดการ Sales การจัดการสินค้าขาเข้า ทุกอย่างแตกต่างกันกับบริษัทแม่หมด
ในระบบเดิมเรามีคลาสที่ชื่อว่า Sales เรามี Shipping ในระบบของบริษัทลูกที่ใช้อยู่พอไปดู Source code ก็มีเหมือนกันทุกประการเลยทีเดียว
เมื่อเราต้องพัฒนาระบบงานขายให้บริษัทที่ควบรวมกันนี้ เรามีทางเลือกอะไรบ้างในฐานะนักพัฒนา
- จับรวมให้เหลือ Sales อันเดียว รองรับสองบริษัท จะได้ไม่วุ่นวาย
- แยกออกเป็นระบบ Sales สองระบบ มีสองคลาส ชื่อเหมือนกันทุกประการ แต่ทำงานคนละอย่างกัน
- บังคับให้บริษัทลูก Migrate เข้าระบบบริษัทแม่
- ตีวิเคราะห์สร้างระบบใหม่อีกครั้งนึงโดยเอาพนักงานบริษัทแม่และลูกมารวมกันจับทำเป็น user และเก็บ requirement
ทั้งสี่ข้อนี้มีข้อดีข้อเสียอย่างไรบ้าง
- หากเราจับรวมแล้วข้างหน้า requirement ใหม่หรือ bug ใหม่เข้ามาแล้วต้องใช้ได้ทั้งสองบริษัท การตัดสินใจนี้ทำให้ทำเรื่องพวกนี้ได้ง่ายขึ้น แต่ตรงข้าม ถ้า user บอกว่าอยากจะแก้แค่โฟลว์งานของบริษัทใดบริษัทหนึ่ง จับรวมทำให้แก้ยากขึ้น
- หากเราแยก ตรงข้ามกับข้อแรก การแก้แยกทำได้ง่าย การแก้ให้กระทบสองที่ทำได้ยาก
- ถ้าเราบังคับ migrate แน่นอนภาระไปตกอยู่กับ user ก็ต้องดูว่าในทางธุรกิจคุ้มมั้ย หรือในโฟลว์ของบริษัทลูกมีจุดขายอะไรพิเศษที่จำเป็นหรือเปล่า เช่น ระบบงานขายนี้อาจจะเป็นจุดตายที่ทำให้พนักงานขายมีโอกาสติดต่อกับลูกค้าได้ดีเพราะมีขั้นตอนบางอย่างเป็นพิเศษอยู่
- ถ้าเราสร้างใหม่ ก็เป็นการลงทุน
จะเห็นว่าการตัดสินใจตรงนี้เป็นการตัดสินใจทางธุรกิจ CEO อย่างจะบริหารงานอย่างไร อยากทำให้บริษัทสองบริษัทนี้ปรับขั้นตอนการทำงานภายในให้คล้ายกันมั้ย หรือเห็นว่าบริษัทลูกที่ไปซื้อมามีขั้นตอนที่มี Unique value proposition ของมันเอง ไม่ควรไปทำให้มันเหมือนบริษัทแม่
ในทางการออกแบบและในฐานะโปรแกรมเมอร์ หลายคนเชื่อว่าระบบที่สวยงามควรจะมี Sales อันเดียว ไม่มีโค้ดซ้ำซ้อนใดๆ ถ้ามันขายเหมือนกันมีชื่อเหมือนกันมาซ้ำซ้อนในระบบมันสับสนนะ แถมขั้นตอนหลายอย่างก็คล้ายกันด้วย ระบบที่สวยงามต้องจับมันรวมสิ
เราไม่ต้องการอะไรซ้ำซ้อน เราเคารพหลักการออกแบบ เราเคารพ DRY (Don’t repeat yourselves) เราเคารพ SRP อะไรก็ว่ากันไป
แต่ในทางธุรกิจจะเห็นว่าการจับรวมให้ได้ระบบที่สวยงาม อาจจะไม่ได้สะท้อนการตัดสินใจทางธุรกิจเสมอไปเลยนะ
การจับรวมสองอย่างนี้เพื่อให้ได้ระบบที่สวยงาม มันสะท้อนว่าธุรกิจต้องการรวมขั้นตอนการทำงานขายของบริษัทลูกให้ตรงกับแม่ ให้เหลือวิธีขายวิธีเดียว
หากเราในฐานะคนออกแบบระบบ เราจับรวม แต่กลายเป็นว่า ที่ไปซื้อบริษัทลูกมาเนี่ยเพราะวิธีขายของบริษัทลูกดีมาก ไม่อยากไปยุ่ง เขาดีของเขาแล้ว และทางธุรกิจเรามีทิศทางที่ต้องการให้แต่ละบริษัทมีขั้นตอนงานขายที่มีความเฉพาะตัวแตกต่างกัน จะได้เข้าถึงลูกค้าอย่าง Personalized
ความขัดแย้งลักษณะนี้อาจจะเกิดขึ้น
“เราต้องการแก้ระบบขายของบริษัทลูก ของบริษัทลูกตอนนี้ขายไม่ถึง 500,000 บาท ไม่ต้องให้ใครอนุมัติแล้ว”
“ผมรวม Sales.Approve ให้เหลือ Method เดียวแล้ว กว่าจะรื้อแยกนี่นานเลย กระทบเยอะไปหมด ผมต้องแยก Strategy pattern ต้องดักเคส แกะกันอีกยาวอ่ะครับ”
“โหย ไม่แก้ก็ได้”
จะเห็นว่าการออกแบบของเราขัดแย้งกับทิศทางธุรกิจ
ทำไปซักพักธุรกิจจะโดนระบบบีบบังคับให้ต้องทำตาม “ความสวยงามของระบบ” ที่เราสร้าง ต้องจับรวมทุกอย่างให้เหลือมาตรฐานเดียว สวยงามดูแลง่าย DRY ตรงหลักการออกแบบซอฟต์แวร์
และความสวยงามนี้ก็ทำให้ธุรกิจเสีย Competitive Advantage ของบริษัทลูกไปเลย ที่อุตส่าห์ไปซื้อมา หายไปหมดแล้ว ไม่ได้อะไรเลย
ดังนั้นผมจึงขอฝากคำถามว่า
“เราจะออกแบบระบบให้สวย หรือเราจะออกแบบระบบให้ตรง”