Trong kiến trúc MVC, một đối tượng đồ họa (GUI Component) bao gồm 3 thành phần cơ bản: Model, View, và Controller. Model có trách nhiệm đối với toàn bộ dữ liệu cũng như trạng thái của đối tượng đồ họa. View chính là thể hiện trực quan của Model, hay nói cách khác chính là giao diện của đối tượng đồ họa. Và Controller điều khiển việc tương tác giữa đối tượng đồ họa với người sử dụng cũng như những đối tượng khác.


Khi người sử dụng hoặc những đối tượng khác cần thay đổi trạng thái của đối tượng đồ họa, nó sẽ tương tác thông qua Controller của đối tượng đồ họa. Controller sẽ thực hiện việc thay đổi trên Model. Khi có bất kỳ sự thay đổi nào ở xảy ra ở Model, nó sẽ phát thông điệp (broadcast message) thông báo cho View và Controller biết. Nhận được thông điệp từ Model, View sẽ cập nhật lại thể hiện của mình, đảm bảo rằng nó luôn là thể hiện trực quan chính xác của Model. Còn Controller, khi nhận được thông điệp từ Model, sẽ có những tương tác cần thiết phản hồi lại người sử dụng hoặc các đối tượng khác

Lấy ví dụ một GUI Component đơn giản là Checkbox. Checkbox có thành phần Model để quản lý trạng thái của nó là check hay uncheck, thành phần View để thể hiện nó với trạng thái tương ứng lên màn hình, và thành phần Controller để xử lý những sự kiện khi có sự tương tác của người sử dụng hoặc các đối tượng khác lên Checkbox. Khi người sử dụng nhấn chuột vào Checkbox, thành phần Controller của Checkbox sẽ xử lý sự kiện này, yêu cầu thành phần Model thay đổi dữ liệu trạng thái. Sau khi thay đổi trạng thái, thành phần Model phát thông điệp đến thành phần View và Controller. Thành phần View của Checkbox nhận được thông điệp sẽ cập nhật lại thể hiện của Checkbox, phản ánh chính xác trạng thái Checkbox do Model lưu giữ. Thành phần Controller nhận được thông điệp do Model gởi tới sẽ có những tương tác phản hồi với người sử dụng nếu cần thiết.

Kiến trúc MVC đã tách biệt (decoupling) sự phụ thuộc giữa các thành phần trong một đối tượng đồ họa, làm tăng tính linh động (flexibility) và tính tái sử dụng (reusebility) của đối tượng đồ họa đó. Một đối tượng đồ họa bấy giờ có thể dễ dàng thay đổi giao diện bằng cách thay đổi thành phần View của nó trong khi cách thức lưu trữ (Model) cũng như xử lý (Controller) không hề thay đổi. Tương tự, ta có thể thay đổi cách thức lưu trữ (Model) hoặc xử lý (Controller) của đối tượng đồ họa mà những thành phần còn lại vẫn giữ nguyên.

Kiến trúc MVC đã được ứng dụng để xây dựng rất nhiều framework và thư viện đồ họa khác nhau. Tiêu biểu là bộ thư viện đồ họa của ngôn ngữ lập trình hướng đối tượng SmallTalk (cũng do Xerox PARC nghiên cứu và phát triển vào thập niên 70 của thế kỷ 20). Các Swing Components của Java cũng được xây dựng dựa trên kiến trúc MVC. Ví dụ đi cùng với JButton là ButtonUI (thành phần View) và ButtonModel (thành phần Model). Ta hoàn toàn có thể viết MyButtonUI hoặc YourButtonUI để thay đổi giao diện của JButton theo ý mình (tương tự cho ButtonModel). Một điểm khá thú vị đối với Swing Components là nó cho phép ta chỉ thay đổi giao diện một phần nào đó của component. Ví dụ ta có thể thay đổi thể hiện của list item trong JList thông qua ListCellRenderer.


Ngay cả Microsoft Visual C++ (VC++) cũng ứng dụng MVC để xây dựng Document View Architecture. Bạn nào đã từng tạo một project MDI trong VC++ đều thấy rằng VC++ sẽ tạo ra các lớp CXXXDoc và CXXXView (XXX là tên project của chúng ta). CXXXDoc chính là thành phần Model và CXXXView là thành phần View của chương trình. Như vậy nếu theo đúng kiến trúc MVC thì tất cả những xử lý liên quan đến lưu trữ dữ liệu của chương trình phải được đặt ở CXXXDoc, còn những xử lý liên quan đến việc thể hiện phải được đặt ở CXXXView. Khi có sự thay đổi dữ liệu ở CXXXDoc, cần cập nhật lại hiển thị ở CXXXView, CXXXDoc sẽ gọi hàm UpdateAllView của nó để phát thông điệp thông báo cho tất cả các View gắn kết với nó. Tại CXXXView ta bắt sự kiện OnUpdate để cập nhật lại hiển thị của View. Hồi đó mỗi lần làm chương trình VC++, tchya đặt tất cả xử lý ở CXXXView, xong rồi ở CXXXDoc hay CMainFrame cần gọi cái gì đó của CXXXView thì cứ việc khai báo một con trỏ pView trỏ đến CXXXView. hì hì, giờ nghĩ lại thấy “bưởi” quá. Vì như vậy vô tình ta đã làm cho CXXXDoc và CMainFrame phụ thuộc (coupling) vào CXXXView, khi muốn thay đổi View thì rất khó khăn.
Khi cài đặt kiến trúc MVC ta cần lưu ý những điểm sau:


- Thành phần Model không cần thiết phải biết đến các View và Controller cụ thể gắn kết với nó. Khi có thay đổi, Model chỉ việc phát thông điệp cho những ai đăng ký với nó. Điều này có thể được thực hiện thông qua Observer Pattern.

- Nên áp dụng Facade Pattern để kết hợp Model, View, và Controller lại với nhau thành “3 trong 1” cho dễ quản lý và thao tác đối với người sử dụng.

- Kiến trúc MVC không phải là kiến trúc 3 tầng (3-Tiers Architecture). Mặc dù giữa 2 kiến trúc này có nhiều điểm tương đồng nhưng chúng nói về 2 khía cạnh khác nhau.
Mô hình MVC đơn giản




Mô hình MVC phức tạp