Darek - tay lập trình viên đã và đang kiểm duyệt tất cả bài viết trên TidyJava đề nghị Grzegorz Ziemonski làm một series các bài phân tích về những kiểu kiến trúc trong xây dựng ứng dụng. Và Grzegorz khởi đầu series đó với bài viết về "kiến trúc đa tầng" mà các bạn đang theo dõi.

#1 Kiến trúc đa tầng là gì?

Theo ngụ ý của tác giả, kiến trúc đa tầng là một cách cấu trúc project theo 4 tầng chính:

  1. presentation: chứa các thành phần đảm nhiệm việc gửi phản hồi và hiển thị giao diện phía người dùng
  2. application: chứa logic code tương ứng với tính năng của ứng dụng
  3. domain: tầng này biểu diễn các thực thể hoặc service
  4. infrastructure (hay còn gọi là persistence layer): các đối tượng nằm ở tầng này liên quan tới thao tác với cơ sở dữ liệu, Data Access Object,...

2 quy tắc bất biến của kiến trúc phân tầng mà mọi lập trình viên phải tuân theo gồm có:

  1. Tất cả các mối ràng buộc (dependecy) chỉ được đi theo 1 chiều, từ tầng cao xuống tầng thấp hơn.
  2. Logic của mỗi tầng độc lập với nhau (Ví dụ: tầng presentation không chứa các câu truy vấn CSDL...)

#2 Bản chất của kiến trúc đa tầng

Ý tưởng chính của kiến trúc đa tầng là việc chia tách các khía cạnh(concern) khác nhau của ứng dụng thông qua quá trình tổ chức và sắp xếp các file source code một cách hợp lý. Và ý tưởng này chỉ dừng lại ở đó. Điều này đồng nghĩa với việc trong quá trình xây dựng một ứng dụng, kiến trúc đa tầng thuộc về khâu tổ chức. Do đó, tác giả đã đưa ra một vài gợi ý cho kiến trúc xử lý dể kết hợp với kiến trúc tổ chức đa tầng: upfront desgin, daily design session hoặc Domain-Driven Design...

Dù ta kết hợp kiến trúc đa tầng với bất kỳ kiến trúc nào chăng nữa, có một nguyên tắc mà lập trình viên nào cũng phải ghi nhớ, đó là kiến trúc đa tầng chỉ đỏng vai trò trong khâu tổ chức.

Thực tập NodeJS Fullstack 2017

#3 Triển khai kiến trúc đa tầng

Sau khi nắm được bản chất và vai trò của kiến trúc đa tầng, chúng ta đã sẵn sàng để triển khai mô hình này.

Có lẽ các bạn cũng đã đoán được, cách triển khai cơ bản nhất của kiến trúc đa tầng là tổ chức mỗi tầng theo từng package tương ứng. Theo kinh nghiệm của tác giả, triển khai 2 tầng Domain và Persistence có phần phức tạp hơn vì tầng Persistece thường lưu trực tiếp Object từ tầng Domain, tức là tầng Persistence sẽ "biết" các class ở tầng Domain, và việc này đi ngược lại quy tắc số 1 của kiến trúc đa tầng.

Ví dụ: ứng dụng Spring Pet Clinic

Với một project này, tác giả đưa ra tương quan giữa 2 trường hợp: có áp dụng kiến trúc đa tầng và không áp dụng kiến trúc đa tầng:

so sánh kiến trúc đa tầng
Bên trái : không áp dụng
Bên phải: có áp dụng

Bạn dễ dàng nhận thấy sự khác biệt giữa 2 cách tổ chức project. Trong quá trình chuyển đổi giữa 2 cách tổ chức, tác giả nhận ra ở project mới không có service. Tuy nhiên ngay sau khi hoàn tất việc di chuyển các class vào package phù hợp, anh ta nhận ra rằng Controller đã đảm nhiệm phần việc đó.

Các bạn có thể truy cập project trên GitHub tại đây

#4 Được lợi gì?

  1. Đơn giản - kiến trúc tổ chức này không tốn quá nhiều thời gian để học và làm quen, do đó nó phù hợp với cả người mới học lập trình
  2. Tính vững chắc được duy trì qua nhiều project - ưu điểm này xuất phát từ bản chất của kiến trúc đa tầng : nó là một kiến trúc áp dụng cho khâu tổ chức project
  3. Đảm bảo việc chia tách các khía cạnh trong project: mỗi khía cạnh đã được chia thành 1 tầng riêng, không lo xáo trộn, nhầm lẫn
  4. Dễ đọc, dễ hiểu, dễ bảo trì: nhờ chia tách ứng dụng thảnh các tầng logic, việc tìm, xem và sửa code trở nên đơn giản hơn.

#5 Mất gì?

  1. Không đảm bảo khả năng chịu tải: khi project phát triển qúa lớn, lập trình viên cần tìm một kiến trúc tổ chức khác bởi tính hiệu quả của kiến trúc đa tầng sẽ bị hạn chế trong trường hợp đó (tuy nhiên lớn đến mức bao nhiêu thì tác giả không hề nhắc đến??? )
  2. Kết dính kém: nhược điểm này đến từ bản chất của kiến trúc đa tầng, đó là chia tách ứng dụng theo 4 tầng, 4 tầng này lại liên kết với nhau dưới góc độ kỹ thuật chứ không phải góc độ "business
  3. Không đáp ứng Dependency Inversion.

Dependency Inversion là gì? Bạn có thể tham khảo một bài viết rất chi tiết tại toidicodedao

#6 Áp dụng khi nào?

  1. Bạn cần sự đơn giản: newbie sẽ thích điều này :D
  2. Ưu tiên sự nhất quán: tác giả ngụ ý phần này có liên quan tới một bộ phận của kiến trúc microservice
  3. Ưu tiên sự phân tách các lớp trong quá trình phát triển:
  4. Bạn muốn làm các project vừa và nhỏ

Đón xem kỳ tới: kiến trúc lục giác

Techmaster via TidyJava