Thoát khỏi Tutorial Hell, bí quyết làm chủ mọi UI Framework

Ngày mới bước chân vào thế giới lập trình, tôi cũng chẳng khác gì bao người khác, lao vào xem từ tutorial này đến tutorial khác, cặm cụi gõ từng dòng code theo video, cố gắng nhồi nhét đống cú pháp vào đầu, nhưng chỉ vài tháng sau, mọi thứ tan thành cát bụi.
Đó là cái bẫy mà người ta thường gọi là Tutorial Hell.

Sau những năm tháng lăn lộn với đủ loại framework, từ web như .NET MVC, React, Angular, Vue, đến desktop như WPF rồi cả mobile và cross-platform như Flutter và MAUI, tôi mới nhận ra rằng thực chất tất cả chỉ xoay quanh vài vấn đề cốt lõi như tách bạch trách nhiệm giữa các thành phần, quản lý trạng thái của các component và xử lý luồng dữ liệu cùng sự kiện. Một khi đã nắm vững thì với bất cứ framework mới nào bạn cũng có thể dễ dàng chinh phục.

Hãy cùng tôi ngược dòng lịch sử, khám phá những cột mốc then chốt của kiến trúc UI.

MVC - Người đàn anh tiên phong

MVC được Trygve Reenskaug đề xuất năm 1979 tại Xerox PARC, nhằm giải quyết vấn đề code bị lẫn lộn. MVC tách ứng dụng thành ba phần: Model quản lý dữ liệu và logic nghiệp vụ, View lo việc hiển thị, còn Controller đóng vai trò xử lý input từ người dùng và đồng bộ Model với View.


Nhờ cách tách biệt này giúp code gọn gàng và dễ mở rộng hơn so với việc trộn tất cả vào một chỗ. MVC nhanh chóng trở thành nền tảng cho nhiều framework sau này như .NET MVC hay Ruby on Rails. Nhưng khi web ngày càng phức tạp thì Controller bị phình to vì chứa quá nhiều logic. Hơn nữa, luồng dữ liệu hai chiều (View có thể tác động ngược lên Model) khiến cho State Management và debug trở nên khó khăn.

MVVM - Lời giải cho ứng dụng desktop

Khoảng năm 2005, cùng với sự ra mắt của WPF, Microsoft giới thiệu MVVM (Model–View–ViewModel) nhằm chinh phục những ứng dụng desktop phức tạp.


MVVM giữ lại Model nhưng thay Controller bằng ViewModel. ViewModel chuẩn bị dữ liệu sẵn sàng cho View, đồng thời cung cấp các command để xử lý thao tác người dùng. View chỉ tập trung hiển thị và kết nối với ViewModel thông qua binding.

Điểm mạnh của MVVM nằm ở binding hai chiều. Khi dữ liệu thay đổi, UI tự động cập nhật, ngược lại, khi người dùng thao tác trên UI, dữ liệu cũng được đồng bộ. Điều này đặc biệt phù hợp với ứng dụng desktop và mobile, nơi cần xử lý nhiều state động, nhiều thành phần UI phức tạp và thay đổi liên tục.

Trên web, MVVM từng được thử nghiệm với Knockout.js và một phần trong Angular.
Những thư viện này mang cơ chế binding hai chiều vào DOM, giúp lập trình viên viết ít code thao tác trực tiếp hơn. Tuy nhiên, binding hai chiều dần lộ nhược điểm về hiệu năng và khó debug ở app lớn, dẫn đến sự chuyển dịch sang các kiến trúc unidirectional,
nổi bật nhất là Flux.

Flux và luồng dữ liệu một chiều

Khi single-page app (SPA) bùng nổ, đặc biệt với React năm 2013, web cần một cách tiếp cận mới để kiểm soát sự phức tạp. Năm 2014, Facebook giới thiệu Flux như một pattern đi kèm React, đặt nền tảng cho khái niệm luồng dữ liệu một chiều (unidirectional data flow).


Trong Flux, mọi thứ đi theo một hướng duy nhất: Người dùng thao tác trên View tạo ra Action (như click button). Action được gửi qua Dispatcher để cập nhật Store (nơi lưu state toàn cục), sau đó View sẽ được render lại dựa trên state mới từ Store. Luồng chảy rõ ràng này loại bỏ tình trạng hỗn loạn thường gặp ở MVC truyền thống, làm state dễ dự đoán và debug hơn.

Flux mang lại lợi ích lớn cho các ứng dụng web phức tạp với nhiều thành phần tương tác, và nó sinh ra các thư viện như Redux cho React, NgRx cho Angular, hay Vuex cho Vue. Có thể nói rằng Flux đã thay đổi cách chúng ta quản lý state trong UI hiện đại.

MVU - Elm và triết lý bất biến

Trong giai đoạn 2012 đến 2015, Elm (ngôn ngữ do Evan Czaplicki sáng tạo) giới thiệu MVU (Model–View–Update). MVU có thể coi như phiên bản tinh gọn và functional hóa của Flux.

Ở MVU, Model là state bất biến.
View là một pure function, nhận đầu vào là Model và trả về View.
Mọi thay đổi đến từ Update, một function nhận vào message (tương tự Action) và Model cũ, rồi trả về Model mới.

Điểm khác biệt quan trọng là không ai được chỉnh sửa trực tiếp state.
Mỗi thay đổi tạo ra một Model hoàn toàn mới.

Triết lý bất biến của MVU sau này ảnh hưởng mạnh đến nhiều framework khác, từ Flutter cho đến Elmish.



Nhìn lại, mỗi pattern xuất hiện đều nhằm khắc phục hạn chế của thế hệ trước.
MVC đưa ra tách biệt trách nhiệm, MVVM giải quyết đồng bộ dữ liệu cho desktop và mobile, Flux kiểm soát luồng dữ liệu trên web hiện đại, còn MVU bổ sung triết lý bất biến để state dễ dự đoán.
Khi hiểu rõ điểm chung này, bạn sẽ thấy mọi framework UI thực chất chỉ là biến thể triển khai.

Bình luận

Gợi ý

0%