Huy có đặt ra vấn đề Suy nghĩ một chút về các MVC framework
http://groups.google.com/group/phpvietnam/t/f541784b9910a00b
Đây là vấn đề hay và khó nhưng tôi khá bận thời gian này cho nên sẽ
chỉ tổng kết ở đây các phân tích của tôi dựa trên kinh nghiệm thiết kế
framework trong thời gian qua. Tôi sẽ nói rõ hơn nếu được yêu cầu
trong một dịp khác.
Tổng kết: Sự khác biệt chính là nhu cầu tổ chức mô hình khái niệm của
người sản xuất
1. Kiến trúc dựa trên page (page-based và Page Controller) dựa trên
quan điểm output - sản phẩm cuối cùng: đó là trang
1.1 Chu kì sống của page-based architecture quá ngắn do nó tập trung
vào quá trình sinh trang chứ không phải là quá trình điều khiển luồng.
Điều này làm hạn chế khả năng của việc plug các luồng thực thi đặc
biệt vào giữa chu kì request-page view
1.2 Page-based là view-centric, hợp theo quan điểm của người dùng cuối
nhưng sẽ gây khó dễ cho người sản xuất khi muốn phức tạp hóa một quy
trình sản sinh trang đặc biệt là workflow.
1.3 Page-based đi theo mô hình xử lý phân tán. Nghĩa là mỗi trang sẽ
có xu hướng cách hành xử một kiểu (by design). Ngoài việc phải quản lý
chặt chẽ cách hành xử phân tán đó (nghĩa là có nhiều vấn đề với việc
bảo trì, kiểm soát và duy trì sự nhất quán) thì những cách hành xử
chung (áp dụng cho nhiều trang) sẽ cần được duplicate ở mức code cho
nhiều trang
1.4 Page-view không có xu hướng phức tạp hóa quy trình sinh trang mà
tập trung vào việc trang sẽ được render trông như thế nào do vậy ít có
tác động về performance.
1.5 Page based có xu hướng tạo ra sự liên kết chặt chẽ hơn giữa
controller và view (phần code để chuyển template thành page). Người
gọi cái này là MVC1.
1.6 Page-based có xu hướng container hóa cho nên liên kết giữa các
page về mặt khái niệm sẽ rất lỏng lẻo. Điều này sẽ gây chút vấn đề với
multi-step workflow.
2. Kiến trúc dựa trên Front Controller và Command pattern (kiến trúc
áp dụng ở các framework: Zend, Symfony, Cake, SolarPHP ... hay Sky/
Pone do tôi viết) dựa trên quan điểm xử lý tập trung, hướng
navigation, tránh nhìn một hệ thống web (website) như một tập hợp các
trang. Thay vào đó, những framework designer như chúng tôi nhìn hệ
thống như là một ứng dụng hay một tập các ứng dụng web có nhiều giao
diện (view thay vì page) và một quy trình navigate giữa các giao diện
đó. Quan điểm này sẽ giúp người sản xuất nhận thấy trước quy trình
sinh trang là một quy trình của ứng dụng. Front Controller hướng đến
input ban đầu và sự ánh xạ giữa input đó vào cấu trúc hệ thống.
2.1 Front Controller và Command pattern quan niệm điều khiển luồng ứng
dụng phải tập trung. Điều này làm nảy sinh sự giàu có của quy trình
thực thi trước khi sinh trang và/hoặc workflow và các developer dễ
dàng plug các luồng thực thi đặc biệt vào quá trình này. Decorator hay
Inteceptor pattern do vậy hay được ứng dụng.
2.2 Front Controller sử dụng một quy trình điều khiển thống nhất trước
khi quy trình sinh trang được tiếp cận cho nên nó sẽ giúp tập trung
hóa quá trình điều khiển. Tuy nhiên lại tạo thêm overhead cho quá
trình sinh trang này mặc dù nó sẽ giúp duy trì sự nhất quán và lượng
code dư thừa. Performance tác động cũng không nhỏ.
2.3 Do Front Controller không hướng page mà hướng view cho nên về mặt
tư duy sẽ có sự chuyển đổi từ page sang masterview/layout/fragment/
slot/partial/placeholder (theo quan điểm của Symfony, CakePHP) hay
layout/element/elementgroup/placeholder/face (theo quan điểm của tôi).
View là một khái niệm trừu tượng hơn Page. Thay vì hình dung toàn bộ
page sẽ được render như thế nào thì View được hiểu là một nhóm các đối
tượng có khả năng điều khiển việc sinh HTML để lắp ghép quá trình tạo
page. Đó có thể là Two-Step View hay Composite View. Như vậy View sẽ
cho phép fine-tune quá trình sinh trang.
2.4 Front Controller làm nảy sinh nhu cầu thực thi các thành phần ứng
dụng có xu hướng không thiên về sinh trang mà thiên về xử lý
navigation như request intercepting filter, before-after-action hooks.
2.5 Do nhìn web như là một ứng dụng có nhiều view, Front Controller và
Command pattern sẽ chủ động trừu tượng hóa request từ người dùng thành
các thành phần ứng dụng nhất quán và xử lý tập trung ở 2 điểm: đầu vào
(Request/Dispatcher) và đầu ra (Response).
2.6 Do có sự chia rẽ chắc chắn giữa Controller và View, cái mà người
ta gọi là MVC2, Front Controller và Command pattern sẽ có kiến trúc
phức tạp hơn, đòi hỏi nhiều bộ nhớ và CPU hơn để duy trì một tổ chức
hết sức mạch lạc và có độ mở rộng cao, phù hợp với các ứng dụng cần xử
lý navigation phức tạp khi mà performance có thể được bù đắp theo cách
khác.
2.7 Front Controller và Command pattern có xu hướng service hóa.
2.8 Mô hình Front Controller và Command pattern sẽ cho phép tính đa
hình được thể hiện nhiều hơn và dễ dạng thực thi cái mà tôi gọi là
multi-layered MVC và configurable navigation do sự kết hợp giữa
Composite View/FrontController/Command tạo nên tính solid của sự liên
kết về mặt khái niệm giữa các view.
3. Quan điểm về router trong Cake, Zend, Symfony
Route chỉ là việc ánh xạ quan điểm nhận thức từ điểm nhìn end-user về
cấu trúc ứng dụng từ quan điểm của người làm phần mềm.
Trên thực tế, nó dùng để thiết kế url và che giấu kiến trúc thì nhiều
ý nghĩa hơn. Route không giúp chúng ta tái cấu trúc cách bố trí các
module trong hệ thống (vốn đã được định nghĩa cố định bởi framework),
thay đổi classloader hay tính navigation của nội bộ của các luồng
chương trình. Nó chỉ làm cho cái nhìn từ bên ngoài trở nên lệch lạc
hơn so với những gì diễn ra thực sự từ bên trong. Tất nhiên, những
người làm framework luôn biết nhu cầu áp đặt filter lên một route cụ
thể để thay đổi cách vận hành của hệ thống nhưng trên thực tế thì
dynamic route hay static route nhìn từ quan điểm Front Controller/
Command đều chỉ là 1. Nên dùng static route nếu như làm các site high
traffic. Tô son trát phấn nhiều quá có ngày mẩn ngứa đấy.
4. REST
Tôi không ưa strict-REST vì không muốn áp đặt kiến trúc ứng dụng theo
semantic rất hạn chế của HTTP. Restful thì đáng theo đuổi hơn.
Trên đây là quan điểm của tôi. Việc lựa chọn mô hình nào là tùy thuộc
vào nhu cầu và các tiêu chí ảnh hưởng như navigation, team skill,
performance. Nên nhớ là ước mơ của nhà kiến trúc phần mềm chính là cơn
ác mộng của nhà phát triển và người vận hành hệ thống. Làm thế nào để
justify điều này là cần thiết để có được sự song hành giữa đẹp-hiệu
quả-có định hướng.