Từ Ý Tưởng đến Code: Giải phẫu hệ thống qua các biểu đồ UML & ERD
Đã bao giờ bạn vừa nhận một yêu cầu làm web, chưa kịp nghĩ ngợi nhiều đã vội gõ ngay npm create vite@latest, hì hục dựng UI bằng Tailwind CSS, để rồi vài ngày sau đành ngậm ngùi "đập đi xây lại" vì logic database chằng chịt và luồng dữ liệu (data flow) quá rối rắm?
Thiết kế hệ thống không chỉ là code. Nó giống như việc vẽ ra bản thiết kế của một ngôi nhà trước khi đặt viên gạch đầu tiên. Trong bài viết này, chúng ta sẽ cùng đi qua toàn bộ vòng đời phân tích một hệ thống thực tế — Website bán đồ điện tử (Electronic Shop) — từ lúc nhận yêu cầu đến lúc chốt cấu trúc Database thông qua các biểu đồ UML và ERD nhé!
Phần 1: Nhìn từ trên cao – Hệ thống có ai và làm gì?
Khi bắt đầu một dự án, sai lầm lớn nhất của Developer là lao ngay vào việc thiết kế database hoặc chia component. Khoan đã! Bạn không thể xây nhà nếu chưa biết mảnh đất đó giáp với đường nào, nhà ai, và ai sẽ là người ở trong đó.
Phần 1 này sẽ giúp bạn định hình "bức tranh toàn cảnh" thông qua 3 bước phân tích nền tảng nhất.
1. Biểu đồ Tổng quát (System Context Diagram)
Bản chất: Đây là Level 0 của hệ thống. Nó ép bạn phải lùi lại một bước, coi toàn bộ cục code (website, app, database) của bạn chỉ là một Hộp đen (Black Box) duy nhất nằm ở chính giữa. Mục tiêu duy nhất ở bước này là trả lời câu hỏi: Hệ thống của chúng ta giao tiếp với những thực thể (actor/system) nào bên ngoài?
Phân tích cho hệ thống Electronic Shop:
Khi thiết kế một website bán đồ điện tử, hệ thống của bạn không đứng một mình. Nó là trung tâm điều phối thông tin giữa các bên:
- Hệ thống chính (Trung tâm): Cửa hàng Điện tử (Electronic Shop System).
- Thực thể 1 - Khách hàng (Customer): Người trực tiếp tương tác với UI để xem laptop, điện thoại, đặt hàng.
- Thực thể 2 - Quản trị viên (Admin/Manager): Người vào trang Dashboard để thêm sản phẩm mới, kiểm tra kho, xem doanh thu.
- Thực thể 3 - Hệ thống Thanh toán (Payment Gateway): Website của bạn không tự xử lý tiền trong thẻ ngân hàng của khách. Nó phải gọi API sang bên thứ 3 (như VNPay, MoMo, Stripe).
- Thực thể 4 - Đơn vị Vận chuyển (Shipping Provider): Khi có đơn, hệ thống cần đẩy thông tin sang Giao Hàng Nhanh hoặc Viettel Post để họ đến lấy hàng.
💡 Tip thực chiến: Rất nhiều bạn sinh viên khi làm đồ án quên mất hai thực thể bên thứ 3 (Thanh toán và Vận chuyển), dẫn đến việc thiếu hụt luồng API khi bước vào giai đoạn code Backend.

2. Biểu đồ Use Case Tổng quát
Bản chất: Sau khi biết "Ai" (Actor) ở bên ngoài, chúng ta bắt đầu "mở hộp đen" ra một chút để xem mỗi người đó có thể làm được "Hành động gì" (Use Case) bên trong hệ thống.
Ở mức độ phân tích hệ thống chuyên sâu, biểu đồ Use Case không chỉ là liệt kê tính năng, mà còn phải thể hiện được mối quan hệ giữa các tính năng đó. Hai quan hệ bạn bắt buộc phải nắm rõ:
<<include>>: Hành động bắt buộc phải có. (VD: Muốn Thanh toán thì bắt buộc phải Đăng nhập).<<extend>>: Hành động mở rộng, có cũng được không có cũng được. (VD: Đang Thanh toán có thể Nhập mã giảm giá).
Phân tích cho hệ thống Electronic Shop:
-
Nhóm Actor: Khách hàng (Customer)
- Quản lý tài khoản cá nhân (Đăng ký, Đăng nhập, Cập nhật hồ sơ).
- Khám phá sản phẩm (Tìm kiếm laptop theo tên, Lọc điện thoại theo mức giá).
- Quản lý giỏ hàng (Thêm/Sửa/Xóa sản phẩm trong giỏ).
- Thanh toán đơn hàng (Checkout).
-
Nhóm Actor: Quản trị viên (Admin)
- Quản lý danh mục và Sản phẩm (Thêm mới một chiếc Macbook, Cập nhật giá, Ẩn sản phẩm hết hàng).
- Quản lý Đơn hàng (Xác nhận đơn, Cập nhật trạng thái giao hàng).
- Thống kê & Báo cáo (Xem doanh thu tháng).
3. Đặc tả Use Case (Use Case Specification)
Bản chất: Vẽ hình thì ông sếp hay khách hàng nhìn vào gật gù là hiểu, nhưng đưa cho Developer và Tester thì họ... "khóc". Hình vẽ không nói lên được khi nào báo lỗi, khi nào thành công. Đó là lúc ta cần Đặc tả Use Case – biến hình vẽ thành văn bản chi tiết. Đây chính là "hợp đồng" để dev cứ thế mà code, tester cứ thế mà viết test case.
Hãy cùng phân tích một Use Case phức tạp bậc nhất trong e-commerce: Thanh toán giỏ hàng (Checkout). Thay vì gạch đầu dòng lộn xộn, chúng ta phải đưa nó vào một format chuẩn chỉnh.
Đặc tả Use Case: UC-05 Thanh toán đơn hàng
| Tên trường | Chi tiết |
|---|---|
| Tên Use Case | Thanh toán đơn hàng (Checkout) |
| Tác nhân (Actor) | Khách hàng |
| Mục đích | Cho phép khách hàng hoàn tất việc đặt mua các sản phẩm đang có trong giỏ hàng. |
| Điều kiện kích hoạt (Trigger) | Khách hàng bấm nút “Thanh toán” tại trang Giỏ hàng. |
| Tiền điều kiện (Pre-conditions) | 1. Khách hàng đã đăng nhập vào hệ thống. 2. Giỏ hàng có ít nhất 1 sản phẩm. |
| Luồng sự kiện chính (Main Flow) | 1. Hệ thống hiển thị giao diện thanh toán (gồm thông tin nhận hàng, danh sách sản phẩm, tổng tiền). 2. Khách hàng điền hoặc xác nhận thông tin giao hàng (Tên, SĐT, Địa chỉ). 3. Khách hàng chọn phương thức thanh toán (ví dụ: COD - Thanh toán khi nhận hàng). 4. Khách hàng bấm nút "Xác nhận đặt hàng". 5. Hệ thống gửi request tạo đơn, kiểm tra lại số lượng tồn kho của các sản phẩm. 6. Hệ thống tạo đơn hàng thành công và trừ số lượng tồn kho tương ứng. 7. Hệ thống làm trống giỏ hàng, hiển thị thông báo thành công và chuyển hướng sang trang chi tiết đơn hàng vừa tạo. |
| Luồng sự kiện thay thế (Alternate Flows) | Luồng thay thế 1 (Thanh toán qua ví điện tử/ngân hàng): - Tại bước 3, khách hàng chọn thanh toán Online (VNPay/MoMo). - Tại bước 5, hệ thống tạo đơn nháp và chuyển hướng người dùng sang cổng thanh toán. - Khách hàng thanh toán thành công, hệ thống nhận callback, cập nhật trạng thái đã thanh toán và tiếp tục bước 6. Luồng thay thế 2 (Thiếu thông tin): - Tại bước 4, nếu các trường bắt buộc (Tên, SĐT, Địa chỉ) bị bỏ trống hoặc sai định dạng. - Hệ thống hiển thị lỗi validation ngay tại form, bôi đỏ các ô thiếu và yêu cầu người dùng bổ sung trước khi đi tiếp. |
| Luồng sự kiện ngoại lệ (Exception Flows) | Ngoại lệ 1 (Hết hàng đột ngột): - Tại bước 5, nếu hệ thống phát hiện sản phẩm trong giỏ đã hết hàng (do khách khác vừa mua xong). - Hệ thống từ chối tạo đơn, báo lỗi "Sản phẩm [Tên] không đủ số lượng" và yêu cầu khách quay lại cập nhật giỏ hàng. Ngoại lệ 2 (Lỗi giao dịch Online): - Trong Luồng thay thế 1, nếu giao dịch tại cổng thanh toán bị lỗi hoặc khách hàng bấm hủy. - Hệ thống đưa khách trở lại trang checkout, báo lỗi "Thanh toán thất bại, vui lòng thử lại" và đơn hàng không được ghi nhận. |
| Hậu điều kiện (Post-conditions) | - Một bản ghi Đơn hàng (Order) mới được lưu vào cơ sở dữ liệu với trạng thái "Chờ xử lý". - Dữ liệu Giỏ hàng (Cart) của tài khoản đó được làm sạch. |
Phần 2: Luồng chạy của hệ thống diễn ra như thế nào?
Đã bao giờ bạn gặp cảnh Frontend và Backend cãi nhau chí chóe vì luồng API không khớp, hoặc khi mang dự án đi review/bảo vệ đồ án, người chấm hỏi: "Thế luồng thanh toán của em chạy qua những bước nào?" và bạn phải lúng túng mở từng file code ra để giải thích chưa?
Đó là lúc bạn cần đến Biểu đồ Hoạt động và Biểu đồ Tuần tự. Chúng là "ngôn ngữ chung" để chuẩn hóa luồng chạy của hệ thống.
4. Biểu đồ Hoạt động (Activity Diagram) – Bản đồ tư duy của luồng nghiệp vụ
Bản chất: Nếu bạn đã từng học qua lưu đồ thuật toán (Flowchart) với các khối hình thoi rẽ nhánh Yes/No, thì Activity Diagram chính là phiên bản "tiến hóa" của nó dùng cho phân tích nghiệp vụ.
Để đọc hiểu biểu đồ này, bạn chỉ cần nhớ 4 ký hiệu "quyền lực" sau:
- Điểm bắt đầu & Kết thúc: Vòng tròn đen đặc (Bắt đầu) và Vòng tròn đen có viền ngoài (Kết thúc).
- Khối Hành động (Action Node): Hình chữ nhật bo góc, chứa cụm động từ (VD: Kiểm tra tồn kho).
- Khối Rẽ nhánh (Decision Node): Hình thoi, dùng khi luồng đi có điều kiện (If/Else).
- Làn bơi (Swimlanes): Đây chính là điểm "ăn tiền" nhất. Nó chia không gian bản vẽ thành các cột dọc/ngang, giúp phân định rõ ràng trách nhiệm của từng Actor/Hệ thống trong một quy trình chéo.
Phân tích quy trình "Xử lý đơn hàng" cho Electronic Shop:
Thay vì viết một mớ text dài ngoằng hay cãi nhau xem ai làm bước nào, hãy chia biểu đồ của bạn làm 4 cột (4 swimlanes): Khách hàng, Hệ thống, Quản trị viên (Admin), và Đơn vị vận chuyển. Dòng thời gian sẽ trôi từ trên xuống dưới:
- [Lane Khách hàng]: Bắt đầu luồng bằng hành động bấm "Xác nhận đặt hàng".
- [Lane Hệ thống]: Tiếp nhận request và đi vào khối Rẽ nhánh (Decision) kiểm tra phương thức thanh toán:
- Nhánh COD: Chuyển thẳng trạng thái đơn thành "Chờ xử lý".
- Nhánh Online (VNPay/MoMo): Gọi API sang cổng thanh toán. Nếu Thành công -> Chuyển "Chờ xử lý". Nếu Thất bại -> Hủy đơn và kết thúc luồng.
- [Lane Hệ thống]: Khi đơn ở trạng thái "Chờ xử lý", hệ thống tiến hành trừ số lượng tồn kho tạm thời (để tránh bán vượt mức - overselling).
- [Lane Quản trị viên]: Admin nhận được thông báo đơn mới, tiến hành nhặt hàng, đóng gói và in vận đơn.
- [Lane Đơn vị vận chuyển]: Shipper đến lấy hàng và đi giao. Tại đây ta có thêm một khối Rẽ nhánh thực tế:
- Nhánh Giao thành công: Hệ thống cập nhật trạng thái "Hoàn thành", Khách hàng nhận hàng -> Kết thúc luồng.
- Nhánh Giao thất bại (Bom hàng): Hệ thống cập nhật trạng thái "Hoàn trả", Admin tiến hành nhận lại hàng và cộng lại số lượng tồn kho.
💡 Lời khuyên thực chiến: Rất nhiều developer khi vẽ luồng mua hàng thường quên mất bước xử lý "Bom hàng / Hoàn hàng", dẫn đến việc kho thực tế thì còn hàng mà kho trên website lại báo hết (do đã trừ ở bước 3 mà không cộng lại). Activity Diagram sẽ giúp bạn "lấp" những lỗ hổng logic này ngay từ trên giấy!

5. Biểu đồ Tuần tự (Sequence Diagram) – Chân ái của những kẻ viết API
Bản chất: Nếu Activity Diagram chú trọng vào luồng công việc tổng thể, thì Sequence Diagram đi sâu vào thứ tự thời gian và cách các đối tượng giao tiếp với nhau. Nó trả lời chính xác câu hỏi: Thành phần A gọi thành phần B lúc nào? Gửi đi tham số gì? Và nhận lại kết quả gì?
Để đọc và vẽ Sequence Diagram như một Senior, bạn chỉ cần nắm 4 "vũ khí" sau:
- Đường đời (Lifeline): Các cột dọc đại diện cho các thành phần tham gia (VD: Client, Server, Database, 3rd Party).
- Thông điệp đồng bộ (Synchronous Message): Mũi tên nét liền, đầu đặc. (Gọi xong phải đứng chờ phản hồi rồi mới làm tiếp).
- Thông điệp trả về (Return Message): Mũi tên nét đứt. (Kết quả trả về sau khi xử lý xong).
- Khung tương tác (Combined Fragments): Các khối hộp bọc lấy luồng xử lý. Hay dùng nhất là alt (if-else rẽ nhánh) và opt (khối tùy chọn - có thể xảy ra hoặc không).
Phân tích trình tự "Thanh toán đơn hàng qua VNPay":
Đây là một luồng khá phức tạp vì có sự tham gia của hệ thống bên ngoài. Hãy tưởng tượng các Lifelines của chúng ta từ trái sang phải gồm: Client (Frontend) ➡️ Controller (Backend) ➡️ Service ➡️ Database ➡️ VNPay Gateway.
[Luồng khởi tạo thanh toán]
- Client gửi request
POST /api/checkoutkèm thông tin giỏ hàng sang Controller. - Controller tiếp nhận, gọi hàm
processCheckout()của Service. - Service truy vấn Database:
Kiểm tra tồn kho. - [Khung
alt- Rẽ nhánh]:- Nhánh [Hết hàng]: Service trả lỗi về Controller -> Controller trả HTTP 400 (Bad Request) về Client -> Kết thúc luồng.
- Nhánh [Còn hàng]: * Service gửi lệnh
INSERTtạo đơn hàng trạng thái Pending xuống Database.- Service gọi API
Create Payment URLsang VNPay Gateway kèm số tiền và mã đơn hàng.
- Service gọi API
- VNPay Gateway xử lý và trả về một đường link thanh toán (URL).
- Controller gói URL này trả về cho Client.
- Client nhận URL và thực hiện thao tác chuyển hướng (Redirect) người dùng sang trang web của VNPay.
[Luồng nhận kết quả (Webhook / IPN)]
Luồng này xảy ra độc lập sau khi khách hàng đã nhập thẻ và bấm thanh toán trên VNPay.
8. VNPay Gateway ngầm bắn một request POST /api/vnpay-ipn (gọi là Webhook) báo kết quả giao dịch về Controller của chúng ta.
9. Controller gọi Service để xác thực chữ ký (Signature) đảm bảo đây đúng là request từ VNPay.
10. Service cập nhật trạng thái đơn hàng thành Paid (Đã thanh toán) xuống Database.
11. Controller trả về HTTP 200 cho VNPay để xác nhận "Tôi đã nhận được thông báo".
💡 Tại sao developer lại "cuồng" biểu đồ này? Bạn thấy đấy, chỉ cần nhìn vào biểu đồ tuần tự, Frontend sẽ biết chính xác lúc nào gọi API, lúc nào nhận link để redirect. Backend thì biết rõ mình phải viết bao nhiêu API (ở đây là 2: một cái cho Client gọi tạo đơn, một cái cho VNPay bắn Webhook về). Mọi thứ minh bạch, không ai phải cãi nhau về flow hệ thống nữa!

Phần 3: Xương sống của ứng dụng – Cấu trúc dữ liệu
Nếu như Phần 1 và Phần 2 giúp chúng ta định hình được giao diện và luồng đi của dữ liệu, thì Phần 3 này chính là nơi chúng ta xây dựng phần cốt lõi nhất của hệ thống: Cấu trúc dữ liệu.
Một hệ thống chạy có mượt mà hay không, mở rộng (scale) sau này có dễ dàng hay không phụ thuộc hoàn toàn vào cách bạn thiết kế Biểu đồ Lớp (Class Diagram) và Biểu đồ Quan hệ Thực thể (ERD).
6. Biểu đồ Lớp (Class Diagram) – Hiện thực hóa Object-Oriented Programming (OOP)
Bản chất: Biểu đồ lớp là cầu nối trực tiếp giữa tài liệu phân tích và code ứng dụng. Nó mô tả cấu trúc tĩnh của hệ thống bằng cách hiển thị các lớp (Classes), thuộc tính (Attributes), phương thức (Methods). Khi nhìn vào Class Diagram, một Backend Developer (hoặc Frontend Developer dùng TypeScript) sẽ biết chính xác mình cần khởi tạo những đối tượng nào.
Đặc biệt, linh hồn của Biểu đồ Lớp nằm ở việc thể hiện mối quan hệ giữa các đối tượng. Trước khi đi vào ví dụ cụ thể, hãy cùng điểm qua 6 loại mối quan hệ kinh điển trong UML mà bạn buộc phải nắm vững:
- Kế thừa (Generalization): Mối quan hệ "Is-a" (Là một). Lớp con thừa hưởng toàn bộ đặc tính của lớp cha và có thể mở rộng thêm. (Ký hiệu: Mũi tên nét liền, đầu tam giác rỗng).
- Hiện thực hóa (Realization): Một lớp (Class) triển khai các phương thức đã được định nghĩa sẵn trong một Giao diện (Interface). (Ký hiệu: Mũi tên nét đứt, đầu tam giác rỗng).
- Kết hợp (Association): Mối quan hệ ngang hàng. Hai đối tượng có thể tương tác với nhau nhưng hoàn toàn độc lập về vòng đời. (Ký hiệu: Đường thẳng).
- Tập hợp (Aggregation): Mối quan hệ "Has-a" (Chứa đựng). Sợi dây liên kết lỏng lẻo: Nếu đối tượng cha bị hủy, đối tượng con vẫn tiếp tục tồn tại. (Ký hiệu: Hình thoi rỗng ở đầu lớp chứa).
- Cấu thành (Composition): Mối quan hệ "Part-of" (Là một phần của). Sợi dây liên kết sống còn: Nếu đối tượng cha bị hủy, đối tượng con bắt buộc phải bị tiêu hủy theo. (Ký hiệu: Hình thoi đặc ở đầu lớp chứa).
- Phụ thuộc (Dependency): Lớp này mượn/sử dụng tạm thời lớp kia trong một phương thức. Sự thay đổi của lớp được mượn có thể làm ảnh hưởng đến lớp mượn. (Ký hiệu: Mũi tên nét đứt).
Phân tích và áp dụng vào cấu trúc Electronic Shop:
Bây giờ, chúng ta sẽ mang các lý thuyết trên áp dụng vào bài toán Cửa hàng điện tử. Hệ thống sẽ quản lý các Class cốt lõi với cấu trúc và mối quan hệ như sau:
- Class
User:- Attributes:
- id: int,- email: string,- password: string - Methods:
+ login(),+ register()
- Attributes:
- Class
Product(Lớp cha):- Attributes:
- id: int,- name: string,- price: double
- Attributes:
- Class
Order:- Attributes:
- id: int,- totalAmount: double,- status: string - Methods:
+ createOrder(),+ updateStatus()
- Attributes:
Mối quan hệ giữa chúng được thể hiện như thế nào?
- Kế thừa (Generalization): Ta có Class
LaptopvàSmartphonekế thừa từ lớp chaProduct.Laptopsẽ có thêm thuộc tính riêng làram,cpu, cònSmartphonecó thêmbatteryCapacity. - Kết hợp (Association) 1-N: Giữa
UservàOrder. MộtUsercó thể đặt nhiềuOrder, nhưng nếu xóa mộtOrderđi thìUserđó vẫn tồn tại bình thường. - Tập hợp (Aggregation) 1-N: Giữa
Category(Danh mục) vàProduct. Một Danh mục "Đồ điện tử" chứa nhiều Sản phẩm. Nhưng giả sử Admin xóa danh mục này đi, các chiếc máy tính (Product) bên trong không bị xóa khỏi hệ thống, chúng chỉ chuyển thành "Chưa phân loại". (Cha chết con vẫn sống). - Cấu thành (Composition) 1-N: Giữa
OrdervàOrderItem(Chi tiết đơn hàng). Nếu một Đơn hàng bị hủy bỏ và xóa khỏi hệ thống, toàn bộ các Chi tiết sản phẩm nằm trong đơn hàng đó cũng vô giá trị và phải bị xóa theo. (Sống cùng sống, chết cùng chết).
💡 Tip phỏng vấn: Rất nhiều nhà tuyển dụng thích hỏi câu: "Sự khác biệt giữa Aggregation và Composition là gì?". Câu trả lời ăn điểm tuyệt đối chính là lấy ví dụ về vòng đời (Lifecycle) của Category - Product và Order - OrderItem như ở trên!

7. Biểu đồ quan hệ thực thể (ERD - Entity Relationship Diagram) – Bản thiết kế Database hoàn chỉnh
Bản chất: Rất nhiều bạn mới học thường nhầm lẫn giữa Class Diagram và ERD vì trông chúng khá giống nhau. Tuy nhiên, mục đích của chúng hoàn toàn khác biệt:
- Class Diagram thiên về Code (OOP): Nó tồn tại trên RAM khi chương trình chạy, chứa các phương thức (hành động).
- ERD thiên về Lưu trữ (Database): Nó tồn tại trên ổ cứng vật lý (SQL), không có phương thức, mà chỉ tập trung vào cấu trúc Bảng (Tables), Cột (Columns), Khóa chính (Primary Key - PK) và Khóa ngoại (Foreign Key - FK) để đảm bảo tính toàn vẹn dữ liệu.
Trước khi bắt tay vào vẽ, hãy điểm qua cách Database xử lý các mối quan hệ:
- Quan hệ 1-1 (One-to-One): Ít dùng, thường dùng để tách bảng cho nhẹ. Ví dụ:
UsersvàUser_Details(chứa các thông tin ít khi truy xuất như sở thích, địa chỉ phụ). - Quan hệ 1-N (One-to-Many): Phổ biến nhất. Khóa chính (PK) của bảng "1" sẽ trở thành Khóa ngoại (FK) nằm trong bảng "N".
- Quan hệ N-N (Many-to-Many): Bắt buộc phải tạo thêm một bảng trung gian (Junction Table) để bẻ thành hai mối quan hệ 1-N. Trong SQL thực tế không thể thiết lập trực tiếp quan hệ N-N.
Phân tích và áp dụng thiết kế Database cho Electronic Shop:
Từ Class Diagram ở phần trước, chúng ta có mối quan hệ N-N giữa Order (Đơn hàng) và Product (Sản phẩm). Khi chuyển hóa xuống Database (ERD), chúng ta bắt buộc phải rã nó ra bằng một bảng trung gian. Cấu trúc cụ thể như sau:
- Bảng
users:id(PK, auto-increment)email,password_hash,role
- Bảng
products:id(PK, auto-increment)name,current_price,stock
- Bảng
orders:id(PK)user_id(FK - trỏ về bảngusers)status,created_at
- Bảng trung gian
order_items(Chi tiết đơn hàng):id(PK)order_id(FK - trỏ về bảngorders)product_id(FK - trỏ về bảngproducts)quantity(Số lượng mua)price_at_purchase(Giá tại thời điểm mua)
💡 Bẫy thực chiến cần lưu ý: Tại sao trong bảng trung gian
order_itemslại phải có cộtprice_at_purchasetrong khi bảngproductsđã có giá rồi? Hãy tưởng tượng, hôm nay chiếc Macbook giá 30 triệu, tuần sau shop chạy flash sale giảm còn 25 triệu (cập nhật ở bảngproducts). Nếu bạn không lưu cứng mức giá 30 triệu vào lúc khách đặt mua ở bảngorder_items, thì tuần sau khi khách mở lại lịch sử đơn hàng, tổng tiền đơn cũ của họ sẽ tự động bị tụt xuống theo giá mới! Đây là lỗi kinh điển mà rất nhiều hệ thống e-commerce non trẻ mắc phải.
[Chèn ảnh Biểu đồ ERD của bạn vào đây - Làm nổi bật các liên kết khóa ngoại PK - FK bằng các đường nối quan hệ 1-N rõ ràng]
Tổng kết
Việc hoàn thiện trọn bộ từ Biểu đồ tổng quát, Use Case, Đặc tả, Luồng chạy (Activity/Sequence) cho đến cấu trúc tĩnh (Class/ERD) chính là quy trình chuẩn chỉnh của một kỹ sư phần mềm thực thụ. Nó giúp bạn có một cái nhìn thấu suốt từ "vỏ bọc" bên ngoài cho đến từng "thớ thịt" bên trong hệ thống.
Nếu bạn đang làm đồ án tốt nghiệp hoặc chuẩn bị kick-off một dự án lớn cho khách hàng, hãy dành thời gian để vẽ hệ thống đàng hoàng. Bỏ ra 3-5 ngày để vẽ biểu đồ sẽ giúp tốc độ code sau này của bạn tăng gấp 3 lần, code đến đâu chuẩn đến đấy và không bao giờ phải ngậm ngùi "đập đi xây lại".
Bạn thường dùng tool gì để vẽ hệ thống? (Draw.io, PlantUML, hay StarUML?).
All Rights Reserved
