Xem thêm

Kiến trúc phân lớp (Layered Architecture): Tổ chức mã nguồn hiệu quả và dễ đọc

Huy Erick
Ảnh chỉ mang tính chất minh họa Kiến trúc phân lớp là một kiểu kiến trúc phổ biến trong ngành công nghệ hiện nay, đồng thời cũng được ứng dụng rộng rãi trong các hệ...

Kiến trúc phân lớp (Layered Architecture) Ảnh chỉ mang tính chất minh họa

Kiến trúc phân lớp là một kiểu kiến trúc phổ biến trong ngành công nghệ hiện nay, đồng thời cũng được ứng dụng rộng rãi trong các hệ thống phần mềm. Kiến trúc này giúp tổ chức mã nguồn theo từng lớp, từ đó tạo ra sự phân rã và tối ưu hóa quá trình phát triển, bảo trì và mở rộng của hệ thống.

Sự phân lớp là gì?

Trong một hệ thống phân lớp, mỗi lớp:

  • Phụ thuộc vào các lớp bên dưới nó;
  • Không biết và không phụ thuộc vào các lớp bên trên sử dụng nó.

Trong kiến trúc phân lớp, các layer có thể được thiết kế theo hướng nghiêm ngặt hoặc linh hoạt hơn. Hướng nghiêm ngặt có nghĩa là một layer chỉ có thể sử dụng và hiểu biết về layer ngay bên dưới nó. Hướng linh hoạt hơn có nghĩa là một layer có thể sử dụng tất cả các layer ở dưới nó. Cả Martin Fowler và tôi đều đồng ý rằng cách thứ hai tạo ra sự linh hoạt và tránh việc tạo ra các proxy method hoặc proxy class trong các layer trung gian chỉ để truyền tải thông điệp từ lớp bên trên xuống lớp phía dưới. Sử dụng các layer trung gian như vậy được coi là một "anti-pattern" với tên gọi "Lasagna Architecture".

Đôi khi các layer được thiết kế sao cho domain layer hoàn toàn không muốn presentation layer biết đến data source layer. Tuy nhiên, thường xuyên, presentation layer nên truy cập trực tiếp đến data source layer. Mặc dù không phải là cách tốt nhất, nhưng phương pháp này thường hoạt động tốt hơn trong thực tế.

Ưu điểm của kiến trúc phân lớp

  • Chỉ cần hiểu những lớp bên dưới lớp đang làm việc;
  • Mỗi lớp có thể được thay thế bởi một thể hiện tương đương mà không ảnh hưởng đến các lớp khác;
  • Một lớp có thể được sử dụng bởi một số lớp cấp cao khác nhau.

Nhược điểm của kiến trúc phân lớp

  • Lớp không thể đóng gói tất cả mọi thứ;
  • Các lớp bổ sung có thể ảnh hưởng đến hiệu suất, đặc biệt nếu ở các tier khác nhau.

Sự tiến hóa của kiến trúc phân lớp

Những năm 60 và 70

Trước đây, các ứng dụng hoàn toàn khác với hiện nay. Không có giao diện người dùng đồ họa, tất cả các ứng dụng được sử dụng thông qua giao diện dòng lệnh hoặc cửa sổ console để nhập dữ liệu từ người dùng và hiển thị kết quả trên màn hình. Không có khái niệm Client-Server, tất cả được cài đặt trên từng máy trạm.

Kiến trúc phân lớp (Layered Architecture)

Vì ứng dụng lúc đó đơn giản, không ai quan tâm đến việc phân tách layer hay tổ chức mã nguồn. Có thể gọi các ứng dụng lúc đó với kiến trúc một layer, một tier, không thể mở rộng và nâng cấp. Ví dụ, nếu muốn cập nhật phiên bản mới, chỉ có cách cài đặt trên từng máy trạm.

Giai đoạn những năm 80 và 90

Giai đoạn này chứng kiến sự xuất hiện của các ứng dụng doanh nghiệp dành cho người dùng sử dụng máy tính cá nhân để truy cập vào ứng dụng qua mạng.

Có 3 layers được chia ra:

User Interface (Presentation): Là các chương trình chạy trên desktop hoặc trên web page. Các chương trình client thường là các rich client, nơi luồng công việc và kiểm tra input đầu vào được đặt ở client.

Business Logic (Domain): Là nơi đặt các logic về nghiệp vụ chính của hệ thống. Layer này tiếp nhận các request từ phía client, xử lý và lưu trữ dữ liệu thông qua Data source layer.

Data source: Nhiệm vụ chính của layer này là thực thi tác vụ lưu trữ dữ liệu và liên lạc với các ứng dụng khác được yêu cầu từ business logic layer.

Kiến trúc phân lớp (Layered Architecture)

Đây chính là mô hình 3 lớp (3-layers) mà chúng ta đã từng biết. Tuy nhiên, xét về mặt các lớp vật lý (tier), ứng dụng thường được tổ chức ở mức 2 tier (Client-Server). Client side chứa Presentation layer, Server side chứa Business logic layer và Data source layer.

Kiến trúc này có thể giải quyết các vấn đề về mở rộng, nhưng vẫn còn một số hạn chế. Các ứng dụng dạng rich-client khi được cài đặt trên một số lượng lớn máy trạm sẽ gặp khó khăn trong việc cập nhật và mở rộng.

Vào giữa những năm 90

Đây là giai đoạn công nghệ có sự chuyển biến mạnh mẽ. Từ những năm 95 đến 2005, thế giới bắt đầu dựa vào "đám mây". Số lượng người dùng tăng lên, độ phức tạp của ứng dụng tăng lên, và cơ sở hạ tầng cũng ngày càng phức tạp. Điều này dẫn đến cải tiến kiến trúc phân lớp để phù hợp với nhu cầu phát triển phần mềm.

Web browser: Thực hiện việc hiển thị và gửi/nhận các yêu cầu tới server.

Application server: Chứa Presentation layer, Application layer, Domain layer và Persistence layer.

Database server: Dùng để lưu trữ dữ liệu.

Kiến trúc phân lớp (Layered Architecture)

Đây là mô hình 3 lớp vật lý (3-tier) hay n-tier. Tất cả logic được chuyển lên phía server, giúp giải quyết vấn đề mở rộng. Client thực hiện nhiệm vụ hiển thị mà không cần biết về các thay đổi từ phía server.

Những năm 2000 đến nay

Domain Driven Design là một khái niệm nổi bật trong ngành lập trình phần mềm. Cuốn sách "Domain-Driven Design: Tackling Complexity in the Heart of Software" của Eric Evan đã định nghĩa các khái niệm quan trọng và có ảnh hưởng sâu rộng đến các thiết kế hiện nay.

Kiến trúc phân lớp (Layered Architecture)

User Interface: Chịu trách nhiệm trong việc hiển thị và truyền tải thông điệp từ client tới server. Client ở đây có thể là người dùng hoặc các ứng dụng khác, tương tự khái niệm "Boundary object" trong kiến trúc EBI.

Application Layer: Điều khiển luồng công việc bằng cách thực thi và kết hợp các Domain object. Layer này không chứa business logic. Liên quan đến khái niệm "Interactors" trong kiến trúc EBI, trừ 1 điều là các interactors là bất kỳ object nào không phải là UI hoặc Entity.

Domain Layer: Chứa các logic liên quan đến nghiệp vụ của ứng dụng, các Entities, Events, và bất cứ object nào xử lý logic nghiệp vụ. Tương tự như "Entity" trong kiến trúc EBI, đây là trái tim của cả hệ thống.

Infrastructure: Cung cấp các thành phần kỹ thuật phổ biến dùng chung cho hệ thống, ví dụ như logging, persistence, messaging...

Lasagna Architecture - Một Anti-pattern

Lasagna Architecture là một anti-pattern, thể hiện sự chặt chẽ trong việc liên lạc giữa các layer. Cách tiếp cận này có thể dẫn đến việc tạo ra nhiều proxy method và proxy class trong các layer trung gian, gây khó khăn và tốn công viết mã. Hơn nữa, một thay đổi nhỏ cũng có thể ảnh hưởng đến cả hệ thống. Việc tạo quá nhiều layer có thể gây phức tạp và giảm hiệu suất trong hệ thống. Đôi khi, chúng ta tổ chức và đóng gói layer theo chức năng kỹ thuật, mà không chia theo chức năng nghiệp vụ, làm mất đi khả năng modular và đóng gói theo khái niệm nghiệp vụ.

Kết luận

Kiến trúc phân lớp là một phương pháp tổ chức mã nguồn hiệu quả và dễ đọc bằng cách nhóm mã vào các layer có chức năng tương ứng trong ứng dụng. Tuy nhiên, như mọi thứ khác trong cuộc sống, quá nhiều là phản tác dụng! Vì vậy, quy tắc của ngón tay cái là chỉ sử dụng các lớp cần thiết và không gì nhiều hơn! Đừng đi theo một chén thánh kiến trúc không tồn tại. Quan trọng là hiểu và đáp ứng nhu cầu thực tế. Đây là một phần của phương pháp triết lý Lean.

Hơn nữa, phương pháp tiếp cận top-down đã lỗi thời. Hiện nay đã có những cách tiếp cận mới và tốt hơn trong việc xây dựng kiến trúc ứng dụng. Chúng ta sẽ nói về những cách tiếp cận đó trong bài viết sau này.

Thông tin được tham khảo từ bài viết "Layered Architecture" của Edward Thien Hoang.

Bài viết được viết lại bởi NN.

1