C4 Model: เล่า Software Architecture จากภาพใหญ่ไปถึง Code

Posted on:October 3, 2026

เคยเปิด Architecture Diagram แล้วต้องถามคนวาดไหมครับว่า “กล่องนี้หมายถึง Application, Database หรือระบบอีกตัวหนึ่ง?” บางรูปมีลูกศรเชื่อมกันเต็มไปหมด แต่ไม่บอกว่าข้อมูลเดินทางไปทางไหนหรือใช้วิธีอะไร คนที่ไม่ได้อยู่ในห้องตอนวาดจึงต้องเดาเอาเอง

ปัญหาแบบนี้ไม่ได้แก้ด้วยการเปลี่ยนสีหรือหารูป icon ให้สวยขึ้นอย่างเดียวครับ ก่อนวาดเราต้องตกลงกันให้ได้ก่อนว่า กล่องแต่ละชนิดแทนอะไร และ รูปนี้กำลังตอบคำถามข้อไหน แล้วค่อยเลือกรูปร่างและสัญลักษณ์มาแสดงความหมายนั้น

หนังสือ The C4 Model ของ Simon Brown ใช้โจทย์ Internet Banking มาช่วยเล่าเรื่องนี้ได้ดี ลูกค้าต้องการดูข้อมูลบัญชีและทำรายการผ่านเว็บ ระบบใหม่ต้องเชื่อมกับ Core Banking ที่มีอยู่แล้ว และส่ง Email แจ้งลูกค้า เราจะเริ่มจากขอบเขตของระบบ แล้วค่อยเปิดดูส่วนประกอบและการทำงานภายในทีละระดับ

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

C4 Model คืออะไร

C4 Model เป็นแนวทางสำหรับอธิบาย Software Architecture โดยใช้ Abstraction หรือระดับความละเอียดที่ตกลงความหมายร่วมกัน ชื่อ C4 มาจาก 4 ระดับของ Static Structure ได้แก่ Context, Container, Component และ Code เรามองระบบจากข้างนอกก่อน แล้วค่อยซูมเข้าไปในส่วนที่สนใจ

คำหลักสี่คำนี้ช่วยตอบว่าเรากำลังมองอะไรอยู่:

ขอเน้นคำว่า Container สักนิดนะครับ ใน C4 มันไม่ได้แปลว่า Docker Container เสมอไป แต่หมายถึง Application หรือ Data Store ที่เป็นส่วนหนึ่งของ Software System และมีหน้าที่ชัดเจน Browser UI, Backend service และ MySQL database ต่างก็อาจเป็น Container ได้ ส่วน Docker เป็นเทคโนโลยีหนึ่งที่อาจถูกใช้ตอน Deploy Container เหล่านั้น

อีกเรื่องที่ควรจำคือ C4 ไม่ได้บังคับให้ทำงานเรียงสี่ขั้นหรือวาดครบทั้งสี่ระดับทุกครั้ง เราเลือกมุมมองตามคำถามที่ต้องการตอบ ถ้าคุยเรื่องขอบเขตระหว่างทีม อาจหยุดที่ Context; ถ้าต้องดูว่าแอปพลิเคชันคุยกับ Database อย่างไร ก็ดู Container; ถ้าจะอธิบายโครงสร้างภายในหรือเส้นทางของ Use Case ค่อยซูมลึกลงไป

System Context Diagram

เริ่มด้วยคำถามง่าย ๆ ก่อนครับ: Internet Banking System อยู่ตรงไหนในโลกของธนาคาร และใครหรือระบบใดต้องติดต่อกับมัน?

Intent: อธิบายว่าระบบที่เราสนใจคืออะไร ใครใช้งาน และต้องพึ่งพาระบบอื่นใดโดยตรง

Scope: โฟกัส Software System หนึ่งระบบ พร้อม People และระบบภายนอกที่เกี่ยวข้องโดยตรง

Content: ตัวอย่างนี้มีลูกค้าธนาคาร, Internet Banking System, Core Banking System และบริการส่ง Email ยังไม่ต้องเปิดดู Backend, Database หรือ Framework ที่ใช้

System Context Diagram แสดงลูกค้าธนาคาร Internet Banking System, Core Banking System และ Amazon Simple Email Service

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

Audience: ใช้คุยกับทั้งคนเทคนิคและไม่ใช่เทคนิค เช่น Product, Operations, Support และผู้เกี่ยวข้องทางธุรกิจ

ควรวาดเมื่อไร: มักเป็นจุดเริ่มต้นที่ดีเมื่อเริ่มระบบใหม่ หรือเมื่อต้องตกลง Scope และการเชื่อมต่อกับระบบอื่น ไม่จำเป็นต้องวาดใหม่ทุกครั้งที่มีการแก้ code

Container Diagram

พอขอบเขตชัดแล้ว ค่อยถามต่อว่า ภายใน Internet Banking System มี Application และ Data Store อะไรบ้าง และแต่ละส่วนคุยกันอย่างไร?

Intent: แสดงโครงสร้างระดับ Application และ Data Store พร้อมหน้าที่, Technology และการสื่อสารระหว่างส่วนต่าง ๆ

Scope: ยังคงเป็น Internet Banking System เดิม แต่ซูมเข้ามาดู Containers ภายใน โดยแสดงคนและระบบภายนอกเท่าที่จำเป็นเพื่อให้เข้าใจความสัมพันธ์

Content: ตัวอย่างมี Static Content, UI ที่ทำงานใน Browser, Backend, MySQL schema สำหรับข้อมูลผู้ใช้และ Access Logs และ S3 Statement Store สำหรับ PDF ที่สร้างไว้ นอกจากนี้ยังเห็น Core Banking และบริการ Email ภายนอก

Container Diagram แสดง Static Content, UI, Backend, MySQL Database และ S3 Statement Store ภายใน Internet Banking System

ลูกค้าโหลดหน้าเว็บจาก Static Content แล้วใช้งาน UI ใน Browser; UI เรียก Backend ผ่าน JSON/HTTP; Backend อ่านหรือเขียนข้อมูลใน MySQL และเรียก Core Banking ผ่าน XML/HTTPS ส่วน Statement Store ใช้เก็บ PDF ที่สร้างขึ้น และบริการ Email รับการแจ้งเตือนจาก Backend

การใส่ Technology และ Protocol ที่สำคัญช่วยให้คนอ่านไม่ต้องเดาความหมายของเส้น ตัวอย่างเช่น ถ้า Browser ติดต่อ MySQL โดยตรง เราอาจต้องกลับไปตรวจการออกแบบเรื่องการยืนยันตัวตนและการเข้าถึงข้อมูล แต่ไม่จำเป็นต้องใส่รายละเอียดทุก Port หรือทุก Configuration ลงในภาพ

ส่วน Database ก็ต้องระบุให้ชัดว่าหมายถึงอะไร ในภาพนี้กล่องคือ MySQL schema ที่ระบบใช้ ไม่ใช่เครื่อง Database Server ทั้งเครื่อง ความชัดเจนนี้สำคัญเพราะการพูดว่า “สองระบบแชร์ Database” อาจหมายถึงแชร์ Server, Schema หรือตารางคนละแบบกัน

Audience: Developer, Architect, Operations และ Support ใช้ทำความเข้าใจว่าจะต้องพัฒนา เชื่อมต่อ และดูแลส่วนใด

ควรวาดเมื่อไร: เหมาะกับระบบส่วนใหญ่เมื่อเริ่มออกแบบหรือมีคนใหม่เข้าทีม เป็นภาพที่ให้รายละเอียดเพิ่มจาก Context โดยยังไม่เปิดระดับ code

Component Diagram

เราเห็นแล้วว่า Backend เป็น Container หนึ่งตัว แต่ถ้าทีมได้รับงานเพิ่ม Sign-in หรือ Statement ควรไปดู code ส่วนไหน? Component Diagram ช่วยแสดงการแบ่งความรับผิดชอบภายใน Container

Intent: อธิบายว่า Container หนึ่งตัวประกอบด้วย Components ใด แต่ละส่วนรับผิดชอบอะไร และพึ่งพากันอย่างไร

Scope: จำกัดไว้ที่ Container เดียว ในตัวอย่างคือ Backend ส่วนระบบภายนอกหรือ Container อื่นแสดงเฉพาะที่ช่วยให้เข้าใจบริบท

Content: Backend มี Sign-in API, Accounts Summary API, Statement API, Security, Core Banking System Adapter, Statement และ Email ซึ่งสะท้อนกลุ่ม code ที่ทำงานอยู่จริง

Component Diagram แสดง Components ภายใน Backend เช่น Sign-in API, Security, Core Banking System Adapter และ Statement

ลองตามคำขอ Statement หนึ่งครั้ง: UI ส่งคำขอมาที่ Statement API; API ให้ Security ตรวจ token; ส่วน Statement ตรวจว่ามี PDF ใน S3 แล้วหรือยัง; ถ้ายังไม่มี ก็เรียกข้อมูลผ่าน Core Banking System Adapter เพื่อสร้าง Statement แล้วบันทึกไว้ใน Store

Component ใน C4 ไม่จำเป็นต้องตรงกับคำว่า Component ของ Framework ที่ใช้ เช่น Spring Component โดยตรง แต่ควรสะท้อนโครงสร้างและความรับผิดชอบที่ทีม implement จริง ถ้า code แบ่งเป็น Layer ก็อาจแสดง Layer; ถ้าออกแบบแบบ Ports and Adapters ก็ควรทำให้ขอบเขตเหล่านั้นเห็นได้

Audience: หลัก ๆ คือ Developer และ Architect ที่กำลังทำงานกับ Container นั้น

ควรวาดเมื่อไร: ใช้เมื่อ Container มีความซับซ้อนหรือทีมต้องสื่อสารว่า Feature หนึ่งเกี่ยวข้องกับ code ส่วนไหน ถ้าแอปเล็กและแบ่งหน้าที่ชัดอยู่แล้ว ภาพนี้อาจเพิ่มภาระดูแลมากกว่าความเข้าใจที่ได้

Code Diagram

ถ้า Component ยังมีรายละเอียดที่อธิบายยาก เราค่อยซูมดูโครงสร้าง code ของมัน เช่น Interface, Class และการพึ่งพากัน ตัวอย่างนี้เลือก Core Banking System Adapter

Intent: อธิบายรายละเอียดใน Component หนึ่งตัวเท่าที่จำเป็นต่อการเข้าใจการออกแบบหรือกลไกสำคัญ

Scope: จำกัดอยู่ที่ Component เดียว ไม่ใช่ผัง Class ทั้ง Application

Content: แสดง Interface ที่ส่วนอื่นเรียก, Implementation ที่ทำงานเบื้องหลัง, Connection สำหรับสื่อสารกับ Core Banking และ Class ที่สร้างหรือแปลง XML Request/Response

Code Diagram แสดง Interface และ Class ภายใน Core Banking System Adapter สำหรับสร้าง XML Request และแปลง XML Response

ภาพแสดง CoreBankingSystemAdapter เป็น Interface ที่เปิดให้ส่วนอื่นเรียก ส่วน Implementation ใช้ Connection ส่ง XML Request และรับ Response โดย BankAccountsRequest ช่วยจัดรูปคำขอ และ BankAccountsResponse แปลงผลลัพธ์กลับเป็นข้อมูลที่ Application เข้าใจ

Code Diagram มีประโยชน์เมื่อต้องอธิบาย Pattern หรือจุดซับซ้อน แต่ code เปลี่ยนบ่อยกว่าภาพระดับ Context และ Container มาก ถ้าวาดทุก Class, Method และ Property แล้วไม่มีคนดูแล ภาพจะล้าสมัยเร็วกว่าที่ช่วยทีม

Audience: Developer ที่พัฒนาและดูแล Component เป็นหลัก

ควรวาดเมื่อไร: วาดเป็นครั้งคราวเพื่ออธิบาย Component สำคัญ, ขอบเขต Interface หรือแนวทางที่ทีมต้องเข้าใจร่วมกัน ไม่จำเป็นต้องสร้างเพื่อให้มีภาพครบทุกระดับ

Dynamic Diagram

Context, Container, Component และ Code แสดงโครงสร้างที่มีอยู่ แต่บางคำถามเกี่ยวกับลำดับการทำงาน เช่น ตอนลูกค้ากด Sign-in แล้วใครเรียกใครก่อน? จะตอบได้ง่ายกว่าด้วย Dynamic Diagram

Intent: เล่าความร่วมมือระหว่าง Elements ขณะทำงาน เพื่ออธิบาย Use Case หรือ Flow หนึ่ง

Scope: เลือกเฉพาะ Elements ที่เกี่ยวข้องกับเรื่องนั้น อาจเป็น Software Systems, Containers, Components หรือระดับ code ก็ได้

Content: ตัวอย่างนี้ตามเส้นทาง Sign-in จากลูกค้า ผ่าน UI, Sign-in API และ Security ไปยัง Database แล้วส่ง Authentication Token กลับมา

Dynamic Diagram แสดงลำดับการ Sign-in จากลูกค้า ผ่าน UI, Sign-in API และ Security ไปยัง Database

ลูกค้ากรอก Username และ Password ใน UI; UI ส่งคำขอ JSON/HTTP ไปยัง Sign-in API; API ขอให้ Security ตรวจสอบ Credentials; Security อ่านข้อมูลผู้ใช้จาก Database และตรวจ Password Hash; เมื่อผ่านการตรวจสอบ ระบบส่ง Token กลับไปยัง UI

Dynamic Diagram อาจวาดเป็น Sequence Diagram หรือ Collaboration Diagram ก็ได้ เป้าหมายคือช่วยให้คนอ่านเข้าใจ Interaction และลำดับของเหตุการณ์ ไม่ใช่จำลองรายละเอียด Runtime ทุกกรณี ภาพนี้เป็นตัวอย่าง Sign-in Flow สำหรับอธิบายแนวคิด ไม่ได้แทนเอกสาร Security Design หรือข้อกำหนด Authentication ทั้งหมด

Audience: ขึ้นอยู่กับระดับที่เลือกเล่า Flow ระดับระบบเหมาะกับผู้เกี่ยวข้องหลายกลุ่ม ส่วน Flow ภายใน Component เหมาะกับทีม Engineering

ควรวาดเมื่อไร: ใช้กับ Use Case ที่ซับซ้อน, มีลำดับสำคัญ หรือมีหลายส่วนที่ต้องประสานกัน ไม่ต้องทำครบทุก Feature ในระบบ

Deployment Diagram

Container Diagram บอกว่าแต่ละส่วนคืออะไร แต่ไม่ได้ตอบว่า ใน Development หรือ Production มันไปรันอยู่บน Infrastructure ไหน? เรื่องนี้เป็นหน้าที่ของ Deployment Diagram

Intent: แสดงการนำ Software System หรือ Container ไปวางบน Infrastructure ภายใน Environment หนึ่ง

Scope: โฟกัสระบบและ Environment ที่สนใจ เช่น Development, Test หรือ Production แยกมุมมองเมื่อ Topology ของแต่ละ Environment ต่างกันอย่างมีนัยสำคัญ

Content: ตัวอย่าง Development มี Browser, Nginx สำหรับ Static Content และ JVM สำหรับ Backend บนเครื่อง Developer; MySQL, MinIO และ Mock SES ทำงานเป็น Docker containers ในเครื่องเดียวกัน ขณะที่ Development instance ของ Core Banking อยู่ใน Data Center ของธนาคาร

Development Deployment Diagram แสดง Browser, Nginx, JVM และ Docker containers สำหรับ MySQL, MinIO และ Mock SES

Mock SES ช่วยให้การทดสอบบันทึก Email ไว้ในระบบจำลอง แทนการส่งไปหาลูกค้าจริง ส่วน MinIO ทำหน้าที่เป็น S3-compatible store ใน Development ขณะที่ Environment อื่นอาจใช้ S3 จริง ภาพ Deployment จึงช่วยให้เราเห็นความแตกต่างระหว่าง Technology เชิงตรรกะของระบบกับวิธีติดตั้งใน Environment หนึ่ง

Audience: Developer, Operations และ Support โดยเฉพาะคนที่ต้องเข้าใจ Infrastructure หรือแก้ปัญหาใน Environment นั้น

ควรวาดเมื่อไร: ทำเมื่อ topology, dependency หรือความแตกต่างระหว่าง Environment มีผลต่อการพัฒนา ทดสอบ หรือดูแลระบบ

System Landscape Diagram

Context Diagram โฟกัส Software System หนึ่งตัว ถ้าต้องการถอยกล้องออกไปดู Internet Banking, Core Banking, ATM และระบบของพนักงานในขอบเขตธนาคารเดียวกัน เรากำลังมอง System Landscape แล้ว

Intent: แสดง Software Systems หลายตัวในขอบเขตที่เลือก และความสัมพันธ์ระหว่างระบบเหล่านั้น

Scope: อาจเป็น Product Area, Department หรือทั้งองค์กร โดยต้องระบุให้ชัดว่าขอบเขตของ Landscape คือส่วนไหน

Content: แสดง Systems ที่เกี่ยวข้องและ People หรือความสัมพันธ์สำคัญ ไม่จำเป็นต้องเปิดรายละเอียด Container หรือ Component ของทุกระบบ

Audience: ใช้สื่อสารภาพรวมกับทั้งทีมเทคนิคและผู้เกี่ยวข้องทางธุรกิจ โดยเฉพาะเมื่อมีผลกระทบข้ามระบบหรือข้ามทีม

ควรวาดเมื่อไร: เหมาะกับองค์กรหรือ Product Area ที่มีหลาย Software Systems และต้องการทำความเข้าใจการพึ่งพากัน ถ้ามีแค่ระบบเดียว Context Diagram มักเพียงพอกว่า

ถ้าใส่ทุกระบบของธนาคารลงใน Context Diagram ของ Internet Banking ภาพก็จะกว้างจนคนอ่านจับขอบเขตไม่เจอ การตั้งชื่อประเภทของ Diagram และระบุ Scope ให้ตรงกับสิ่งที่แสดงจึงช่วยป้องกันความเข้าใจผิดได้

ทำ Diagram ให้อ่านได้ด้วยตัวเอง

C4 แยกความหมายของ Abstraction ออกจาก Notation ที่ใช้วาด เราใช้กล่องสี่เหลี่ยม, UML, PlantUML หรือเครื่องมือของทีมก็ได้ แต่ควรใช้รูปแบบให้สม่ำเสมอและอธิบายสัญลักษณ์ที่มีความหมายพิเศษไว้ใน Legend

ก่อนส่งรูปให้คนอื่น ลองตรวจด้วยคำถามสั้น ๆ เหล่านี้:

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

C4 ก็ไม่ได้แทน Diagram ทุกชนิดหรือแทนเอกสารเหตุผลการตัดสินใจ ถ้าต้องอธิบาย Database Schema ใช้ ER Diagram; ถ้าต้องอธิบาย State Machine ใช้ State Diagram; ถ้าต้องบันทึกว่าทำไมทีมเลือก Architecture แบบหนึ่ง ให้ใช้ ADR หรือเอกสารประกอบ C4 เป็นแผนที่ของโครงสร้างและความสัมพันธ์ ไม่ใช่คำตอบของทุกคำถาม

เริ่มต้นใช้งานอย่างพอดี

ถ้าทีมยังไม่มี Architecture Diagram ให้เริ่มจาก System Context และ Container ก่อน สองภาพนี้ทำให้เห็นว่าระบบมีไว้เพื่อใคร เชื่อมกับอะไร และข้างในมี Application หรือ Data Store ใดบ้าง ค่อยเพิ่ม Component หรือ Code Diagram เมื่อมีคำถามเฉพาะที่ต้องการคำตอบ

แต่ละระดับเปลี่ยนเร็วไม่เท่ากัน Context มักเปลี่ยนช้ากว่า Component; Code Diagram อาจล้าสมัยได้เร็วตามการแก้ไข code เลือกวาดเฉพาะภาพที่มีคนใช้และมีเจ้าของดูแล ไม่อย่างนั้นเอกสารจะค่อย ๆ ห่างจากระบบจริง

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

สรุป

C4 Model ช่วยให้ทีมเล่า Internet Banking System จาก “ใครใช้และระบบเกี่ยวข้องกับใคร” ไปจนถึง “ส่วนภายในทำงานร่วมกันอย่างไร” โดยแบ่งความละเอียดเป็นระดับที่คนอ่านเลือกตามคำถามได้

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

อ่านเพิ่มเติม

Github Facebook Twitter LinkedIn YouTube Medium