Một developer Rails đã khơi mào cuộc thảo luận trong cộng đồng bằng cách phân tích một cách phê phán mô hình Hexagonal Architecture đã trở nên phổ biến trong các ứng dụng Rails khoảng một thập kỷ trước. Tác giả đã đặt ra thuật ngữ hexatetrahedral Rails để mô tả những ứng dụng đã trở nên quá phức tạp thông qua cách tiếp cận kiến trúc này, đặt câu hỏi liệu những lợi ích có xứng đáng với sự phức tạp gia tăng hay không.
Khoảng cách giữa Lời hứa và Thực tế
Hexagonal Architecture ban đầu, được đề xuất bởi Tiến sĩ Alistair Cockburn , nhằm tạo ra sự tách biệt rõ ràng giữa logic nghiệp vụ và các mối quan tâm bên ngoài thông qua các giao diện được định nghĩa rõ ràng. Tuy nhiên, nhiều triển khai Rails đã đi xa khỏi tầm nhìn này. Thay vì đạt được tính mô-đun như dự định, những ứng dụng này thường trở thành cơn ác mộng bảo trì đầy những trừu tượng hóa không cần thiết và các công cụ không chuẩn.
Cộng đồng đã lưu ý rằng trong khi repositories có thể ngăn chặn các developer junior mắc những lỗi cơ sở dữ liệu tốn kém, việc xây dựng chúng trên ActiveRecord thay vì thay thế hoàn toàn sẽ có ý nghĩa thực tế hơn. Cách tiếp cận này duy trì các quy ước Rails trong khi thêm các rào cản cần thiết.
Đặc điểm phổ biến của ứng dụng Rails "Hexatetrahedral":
- DataMapper hoặc ROM thay vì ActiveRecord
- Sử dụng nhiều thư viện dry-rb
- RSpec với mocking mở rộng thay vì Minitest
- FactoryBot thay vì fixtures
- Các mẫu Repository bao bọc truy cập ActiveRecord
- Trailblazer và ROM cho views
- Các Service objects cho business logic
Gánh nặng Bảo trì và Động lực Nhóm
Một mối quan tâm đáng kể được nêu ra là chi phí bảo trì của các ứng dụng hexatetrahedral. Những codebase này thường dựa vào nhiều thư viện bên thứ ba và các trừu tượng hóa tùy chỉnh đòi hỏi cập nhật liên tục và hiểu biết sâu sắc. Khi các thành viên trong nhóm rời đi hoặc các thư viện trở nên lỗi thời, gánh nặng kiến thức sẽ đè nặng lên các developer còn lại.
Cuộc thảo luận tiết lộ một tình huống khó xử phổ biến mà các nhóm phát triển phải đối mặt: lựa chọn giữa các mô hình Rails được tài liệu hóa tốt, được sử dụng rộng rãi và việc duy trì các quyết định kiến trúc tùy chỉnh được đưa ra từ nhiều năm trước. Hầu hết các developer, khi bị thúc ép về thời gian, sẽ từ bỏ cách tiếp cận tùy chỉnh để ủng hộ các phương pháp Rails tiêu chuẩn.
Vấn đề Thu hẹp API
Tác giả xác định những gì họ tin là động cơ thực sự đằng sau các kiến trúc hexagonal Rails : giảm bề mặt API khổng lồ của ActiveRecord . Với hơn 666 class methods và 230 instance methods có sẵn trên một ApplicationRecord cơ bản, việc kiểm soát cách các nhóm tương tác với dữ liệu trở nên thách thức trong các tổ chức lớn.
Nếu giao diện của tôi là ActiveRecord thô, thì bạn không thể tức giận với junior của bạn vì đã tạo ra một full table scan với 'where' trên mọi request.
Cái nhìn sâu sắc này gây tiếng vang với các developer đã trải qua nỗi đau của việc truy cập cơ sở dữ liệu không hạn chế trong các ứng dụng đang phát triển.
Độ phức tạp API của ActiveRecord:
- 666 class method có sẵn trên ApplicationRecord
- 230 instance method cho mỗi model
- Mỗi association đều hiển thị cùng số lượng method cộng thêm các association helper
- Các hành vi method phức tạp với các ràng buộc về trình tự và phụ thuộc
Một Giải pháp Thay thế Đơn giản hơn
Thay vì triển khai kiến trúc hexagonal đầy đủ, tác giả đề xuất một cách tiếp cận thực dụng hơn bằng cách sử dụng các Ruby modules để tổ chức logic domain. Phương pháp này cung cấp sự tách biệt namespace và các ranh giới rõ ràng hơn mà không có chi phí phức tạp của repositories, service objects và các ORM tùy chỉnh đặc trưng cho các ứng dụng hexatetrahedral.
Cộng đồng Rails dường như đã phần lớn vượt qua xu hướng kiến trúc này, với các giải pháp mới hơn như Packwerk giải quyết những mối quan tâm tương tự về tổ chức code và ranh giới nhóm. Sự đồng thuận dường như ủng hộ kỷ luật và các quy ước rõ ràng hơn là sự phức tạp kiến trúc, đặc biệt là do hầu hết các ứng dụng không yêu cầu những lợi ích lý thuyết mà hexagonal architecture hứa hẹn mang lại.
Lưu ý: Hexatetrahedral đề cập đến một hình dạng hình học phức tạp, được sử dụng ở đây một cách ẩn dụ để mô tả các mô hình kiến trúc quá phức tạp.
Tham khảo: Hexatetrahedral Rails