Khi nhìn vào một bản thiết kế công trình, chúng ta thường có thể ngay lập tức nhận ra bản thiết kế đó đang thiết kế cho loại công trình gì – nhà ở, hay nhà văn phòng, hay công viên hay trường học. Chúng ta nhận ra nhờ sự tồn tại của những thành phần đặc thù cho các nhu cầu sử dụng khác nhau. Bản thiết kế công trình đó được thiết kế dựa theo nhu cầu sử dụng, mà ta gọi là các use case.
Khi nhìn vào một thiết kế phần mềm, chúng ta sẽ nhìn thấy gì? Là hệ thống chăm sóc sức khỏe, hệ thống kế toán, quản lý kho bãi, nhân sự, đơn hàng… Hay chúng ta sẽ thấy Spring, Rail, Laravel hoặc ASP?
Toát ý của một bản thiết kế
Cuốn sách tinh túy của Ivar Jacobson – Object Orientted Software Engineerring có một tiêu đề phụ rất đáng lưu tâm: A Use Case Driven Approach. Trong đó tác giả nêu lên một quan điểm rằng kiến trúc phần mềm là những cấu trúc hỗ trợ cho các use case của hệ thống. Kiến trúc phải hô lớn lên về những use case của hệ thống.
Kiến trúc nhất thiết không được đồng nghĩa với framework. Kiến trúc không được định hình bởi framework. Framework là các công cụ có thể được sử dụng, không phải là khuôn mẫu mà framework phải tuân theo. Nếu một kiến trúc lại đi dựa trên framework, nó sẽ không dựa trên use case nữa.
Mục đích của một bản thiết kế
Một kiến trúc tốt sẽ xoay quanh các use case và bởi vậy các nhà kiến trúc có thể tạo ra các cấu trúc hỗ trợ cho những case study đó mà không bị liên lụy bởi các framework, cộng cụ, môi trường… Một bản thiết kế công trình sẽ quan tâm đến việc công trình đó sẽ được sử dụng vào những việc gì, thay vì đặt ra một ràng buộc rằng công trình đó sẽ được xây nên bởi gạch hay bê tông hay bất cứ vật liệu nào khác. Những thứ đó có thể ra quyết định sau.
Kiến trúc phần mềm tốt cũng sẽ cho phép các quyết định về framework, cơ sở dữ liệu, web servers và đủ thứ các quyết định về môi trường hay công cụ… có thể dời lại sau. Framework là lựa chọn có thể được để ngỏ. Một kiến trúc tốt cho phép chúng ta không cần quyết định sớm về Rail hay Spring hay Hibernate Tomcat MySQL… cho đến những giai đoạn sau của dự án. Một kiến trúc tốt cho phép chúng ta thay đổi tư duy của mình về những lựa chọn đó một cách dễ dàng. Một kiến trúc tốt làm nổi bật nên các use case và đồng thời dứt chúng ra khỏi những khía cạnh ngoại vi.
Về Web
Liệu có có thứ gọi là Kiến trúc Web hay không? Việc hệ thống được triển khai trên nền Web có ảnh hưởng tới kiến trúc của hệ thống hay không?
Hoàn toàn không! Web là phương thức chuyển giao — là một thiết bị vào ra — và kiến trúc hệ thống coi web thuần túy là một ngõ vào ra. Hệ thống được chuyển giao trên nền web là một chi tiết nhỏ không có khả năng chi phối kiến trúc.
Thực tế thì việc hệ thống có được chuyển giao lên web hay không là một quyết định có thể dời lại. Hệ thống phải bỏ qua càng lâu càng tốt về việc nó được chuyển giao như thế nào. Chúng ta cần có khả năng chuyển giao nó như một ứng dụng dòng lệnh, hay một ứng dụng web, hay thậm chí một ứng dụng web service… một cách không quá phức tạp và không gây ảnh hưởng tới kiến trúc căn bản.
Framework là công cụ, không phải lẽ sống
Framework có thể rất mạnh, rất hữu dụng. Các tác giả của các framework có một niềm tin sâu sắc vào framework của họ. Họ chỉ cho chúng ta cách để sử dụng framework, theo cách của một con chiên. Họ thường có lập trường rằng framework của mình là bao quát hết, giải quyết hết, hãy để nó làm mọi thứ…
Đó không phải là lập trường mà nhà thiết kế nên đi theo.
Hãy nhìn vào các framework bằng đôi mắt trong sáng. Xem xét chúng một cách đầy nghi ngờ. Nó hữu dụng, nhưng có “đắt” không? Dùng nó sẽ như thế nào? Phải bảo vệ kiến trúc ra làm sao – làm sao để bảo vệ các use case khỏi framework? Hãy phát triển một chiến thuật để ngăn chặn framework lấn át vào kiến trúc.
Về kiểm thử
Một khi kiến trúc nói lên tất cả về các use case, và framework được đặt hẳn sang một bên, chúng ta sẽ có khả năng kiểm thử toàn bộ các use case mà không bị can thiệp bởi bất kỳ thành phần nào của framework. Chúng ta không cần một web server thật chạy để có thể kiểm thử, cũng không cần kết nối database. Các đối tượng Entity của chúng ta là các pojo đơn thuần và không có bất kỳ phụ thuộc vào với database hay các quan hệ phức tạp khác. Thứ duy nhất điều phối các entity là use case. Và tát cả các use case đều có thể được kiểm thử trong giả lập, mà không cần đến bất kỳ framework phức tạp nào.
Tổng kết
Kiến trúc của chúng ta phải có khả năng nói cho người đọc về hệ thống, không phải về framework được sử dụng trong hệ thống. Nhà phát triển phải có khả năng học được về tất cả các use case trong hệ thống mà thậm chí còn chưa cần biết về cách hệ thống được chuyển giao. Đó là một chi tiết có thể được ra quyết định sau.