Conway’s Law (กฎของ Conway)

ย้อนกลับไปในช่วงปลายทศวรรษ 1960 Melvin Conway ได้ตั้งข้อสังเกตซึ่งต่อมาเป็นที่รู้จักกันในชื่อ Conway’s Law :

องค์กรที่ออกแบบระบบ...ถูกจำกัดให้ผลิตงานออกแบบที่เป็นสำเนาของโครงสร้างการสื่อสารขององค์กรเหล่านั้น

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

ข้อสังเกตที่เกี่ยวข้องกันซึ่งบัญญัติขึ้นโดย Jonny Leroy จาก Thoughtworks คือ Inverse Conway Maneuver ซึ่งเสนอแนะให้พัฒนาโครงสร้างของทีมและองค์กรไปพร้อม ๆ กันเพื่อส่งเสริม architecture ที่ต้องการ แนวคิดนี้ต่อมาเป็นที่รู้จักกันทั่วไปในชื่อ team topologies .

องค์กรต่าง ๆ เริ่มตระหนักแล้วว่า team topologies สามารถส่งผลกระทบอย่างมีนัยสำคัญต่อแง่มุมสำคัญหลายอย่างในธุรกิจของตน รวมถึง software architecture ด้วย ในบทถัด ๆ ไปที่เน้นแต่ละ style เราจะพูดถึงผลกระทบของแต่ละ architecture style ต่อทีมแต่ละประเภทเหล่านี้

หนึ่งในความแตกต่างพื้นฐานระหว่าง architecture pattern ต่าง ๆ คือประเภทของ top-level partitioning ที่แต่ละแบบรองรับ ในบทถัดไปที่เจาะจงแต่ละ style เราจะพูดถึงความแตกต่างนี้สำหรับแต่ละ pattern top-level partitioning ยังส่งผลกระทบอย่างมากต่อการที่สถาปนิกจะตัดสินใจระบุ component ในตอนแรกตามเทคนิคหรือตาม domain ด้วย

สถาปนิกที่ใช้ technical partitioning จะจัดระเบียบ component ของระบบตามความสามารถเชิงเทคนิค ได้แก่ presentation, business rules, persistence และอื่น ๆ หนึ่งในหลักการจัดระเบียบของ layered architecture คือ separation of technical concerns ซึ่งสร้างระดับของ decoupling ที่มีประโยชน์ ตัวอย่างเช่น ถ้า Service layer เชื่อมต่อเฉพาะกับ Persistence layer ที่อยู่ด้านล่างและ Business Rules layer ที่อยู่ด้านบนเท่านั้น การเปลี่ยนแปลงใน persistence ก็จะส่งผลกระทบแค่กับ layer เหล่านั้นเท่านั้น การ decouple แบบนี้ช่วยลดโอกาสที่จะเกิดผลกระทบข้างเคียงลุกลามไปยัง component ที่พึ่งพากันได้

การจัดระเบียบระบบด้วย technical partitioning นั้นสมเหตุสมผลอย่างแน่นอน แต่เช่นเดียวกับทุกอย่างใน software architecture ก็ย่อมมี trade-off อยู่ การแบ่งแยกที่ technical partitioning บังคับใช้ช่วยให้นักพัฒนาหาโค้ดในหมวดหมู่ต่าง ๆ ได้อย่างรวดเร็ว เพราะมันถูกจัดระเบียบตามความสามารถ แต่ระบบซอฟต์แวร์ในโลกจริงส่วนใหญ่ต้องการ workflow ที่ตัดผ่านความสามารถเชิงเทคนิคหลาย ๆ อย่าง

ใน technically partitioned architecture ที่แสดงใน Figure 9-4 ลองพิจารณา business workflow ที่พบได้ทั่วไปอย่าง CatalogCheckout โค้ดที่จัดการ CatalogCheckout ใน technically partitioned architecture จะปรากฏอยู่ในทุก layer พูดอีกอย่างคือ domain ถูกกระจายเกลี่ยไปทั่วทุก technical layer

Figure 9-4. ตำแหน่งที่ domain/workflow ปรากฏใน technically partitioned architecture และ domain-partitioned architecture

ในทางตรงข้าม domain-partitioned architecture ที่แสดงใน Figure 9-4 สถาปนิกได้สร้าง component ระดับบนสุดขึ้นรอบ ๆ workflow และ domain component แต่ละตัวอาจมี subcomponent รวมถึง layer อยู่ภายใน แต่ top-level partitioning จะเน้นที่ domain เป็นหลัก ซึ่งสะท้อนถึงประเภทของการเปลี่ยนแปลงที่เกิดขึ้นบ่อยที่สุดในโปรเจกต์ได้ดีกว่า

ไม่มี style ไหนในสอง style นี้ที่ถูกต้องกว่ากันเลย (ให้ย้อนกลับไปดู First Law of Software Architecture) กระนั้นก็ตาม เราสังเกตเห็นแนวโน้มที่ชัดเจนในอุตสาหกรรมช่วงไม่กี่ปีที่ผ่านมาว่าเอนเอียงไปทาง domain partitioning ทั้งใน architecture แบบ monolithic และแบบ distributed (เช่น microservices) ดังที่เราได้กล่าวไปแล้ว นี่เป็นหนึ่งในการตัดสินใจแรก ๆ ที่สถาปนิกต้องทำ

Kata: Silicon Sandwiches—Partitioning (Kata: Silicon Sandwiches—การแบ่งพาร์ทิชัน)

ลองพิจารณากรณีของหนึ่งใน kata ตัวอย่างของเรา คือ “Kata: Silicon Sandwiches” เริ่มต้นด้วยการพิจารณาความเป็นไปได้แรกจากสองแบบสำหรับ Silicon Sandwiches นั่นคือ domain partitioning ซึ่งแสดงใน Figure 9-5 .

Figure 9-5. การออกแบบแบบ domain-partitioned สำหรับ Silicon Sandwiches

ใน Figure 9-5 สถาปนิกได้ออกแบบโดยยึด domain (workflow) เป็นหลัก โดยสร้าง component แยกกันสำหรับ Purchase , Promotion , MakeOrder , ManageInventory , Recipes , Delivery และ Location ภายใน component หลายตัวเหล่านี้มี subcomponent อยู่เพื่อจัดการกับการปรับแต่ง (customization) ทั้งแบบ common และแบบ local variation

Figure 9-6. การออกแบบแบบ technically partitioned สำหรับ Silicon Sandwiches

การออกแบบอีกแบบหนึ่งจะแยกส่วน common และ local ออกเป็นพาร์ทิชันของตัวเอง ดังที่แสดงใน Figure 9-6 . Common และ Local เป็นตัวแทนของ component ระดับบนสุด ในขณะที่ Purchase และ Delivery ยังคงอยู่เพื่อจัดการ workflow

แบบไหนดีกว่ากัน? ก็แล้วแต่กรณี! การแบ่งพาร์ทิชันแต่ละแบบมีข้อดีและข้อเสียที่แตกต่างกันไป

Domain partitioning (การแบ่งพาร์ทิชันตาม Domain)

Domain-partitioned architecture จะแยก component ระดับบนสุดตาม workflow และ/หรือ domain

Advantages

  • จำลองใกล้เคียงกับวิธีที่ธุรกิจดำเนินงานมากกว่าที่จะยึดตามรายละเอียดการ implement

  • สร้างทีมข้ามสายงาน (cross-functional team) รอบ ๆ domain ได้ง่ายกว่า

  • สอดคล้องกับ modular monolith และ microservices architecture style มากกว่า

  • การไหลของ message สอดคล้องกับ problem domain

  • ย้ายข้อมูลและ component ไปยัง distributed architecture ได้ง่าย

Disadvantage

  • โค้ดสำหรับการปรับแต่ง (customization) ปรากฏอยู่ในหลายที่

Technical partitioning (การแบ่งพาร์ทิชันตามเทคนิค)

Technically partitioned architecture จะแยก component ระดับบนสุดตามความสามารถเชิงเทคนิคแทนที่จะเป็น workflow ที่แยกจากกัน สิ่งนี้อาจปรากฏในรูปของ layer ที่ได้แรงบันดาลใจจากการแยกแบบ Model-View-Controller หรือการแบ่งพาร์ทิชันเชิงเทคนิคแบบเฉพาะกิจอื่น ๆ architecture ที่แสดงใน Figure 9-6 แยก component ตาม การปรับแต่ง (customization) .

Advantages

  • แยกโค้ดสำหรับการปรับแต่งออกจากกันได้อย่างชัดเจน

  • สอดคล้องกับ layered architecture pattern มากกว่า

Disadvantages

  • มี global coupling ในระดับที่สูงกว่า การเปลี่ยนแปลง component Common หรือ Local มีแนวโน้มที่จะส่งผลกระทบต่อ component อื่น ๆ ทั้งหมด

  • นักพัฒนาอาจต้องทำซ้ำแนวคิดของ domain ทั้งใน Common layer และ Local layer

  • โดยทั่วไปแล้วจะมี coupling ที่สูงกว่าในระดับข้อมูล ในระบบแบบนี้ application architect และ data architect มักจะร่วมมือกันสร้างฐานข้อมูลเดียว ซึ่งรวมทั้ง customization และ domain ต่าง ๆ เข้าไว้ด้วยกัน ซึ่งจะสร้างความยากลำบากในการแกะความสัมพันธ์ของข้อมูลออกจากกันในภายหลัง หากสถาปนิกต้องการย้ายระบบไปเป็น distributed system ในที่สุด ยังมีปัจจัยอื่น ๆ อีกมากมายที่มีผลต่อการเลือก architecture style ดังที่เราจะกล่าวถึงใน Part II .