Câu hỏi trình bày một vấn đề nan giải giả. Áp dụng đúng nguyên tắc YAGNI không phải là một điều không liên quan. Đó là một khía cạnh của thiết kế tốt. Mỗi nguyên tắc RẮN là các khía cạnh của thiết kế tốt. Bạn không thể luôn áp dụng đầy đủ mọi nguyên tắc trong bất kỳ ngành học nào. Các vấn đề trong thế giới thực đặt rất nhiều lực vào mã của bạn và một số trong số đó đẩy theo các hướng đối nghịch. Nguyên tắc thiết kế phải tính đến tất cả những thứ đó, nhưng không có nguyên tắc nào có thể phù hợp với mọi tình huống.
Bây giờ, chúng ta hãy xem xét từng nguyên tắc với sự hiểu rằng trong khi đôi khi chúng có thể kéo theo các hướng khác nhau, thì chúng hoàn toàn không phải là xung đột.
YAGNI được hình thành để giúp các nhà phát triển tránh một loại công việc đặc biệt: đó là từ việc xây dựng điều sai. Nó thực hiện điều này bằng cách hướng dẫn chúng tôi tránh đưa ra quyết định sai lầm quá sớm dựa trên các giả định hoặc dự đoán về những gì chúng tôi nghĩ sẽ thay đổi hoặc cần thiết trong tương lai. Kinh nghiệm tập thể cho chúng ta biết rằng khi chúng ta làm điều này, chúng ta thường sai. Ví dụ: YAGNI sẽ bảo bạn không tạo giao diện cho mục đích tái sử dụng , trừ khi bạn biết ngay bây giờ rằng bạn cần nhiều người triển khai. Tương tự, YAGNI sẽ nói không tạo "Trình quản lý màn hình" để quản lý biểu mẫu đơn trong một ứng dụng trừ khi bạn biết ngay rằng bạn sẽ có nhiều hơn một màn hình.
Trái với những gì nhiều người nghĩ, RẮN không phải là về khả năng sử dụng lại, tính tổng quát hay thậm chí là trừu tượng. RẮN nhằm giúp bạn viết mã được chuẩn bị để thay đổi , mà không nói bất cứ điều gì về sự thay đổi cụ thể đó có thể là gì. Năm nguyên tắc của RẮN tạo ra một chiến lược xây dựng mã linh hoạt mà không quá chung chung và đơn giản mà không ngây thơ. Áp dụng đúng mã RẮN tạo ra các lớp nhỏ, tập trung với các vai trò và ranh giới được xác định rõ. Kết quả thực tế là đối với bất kỳ yêu cầu cần thiết nào thay đổi, một số lượng tối thiểu các lớp cần phải được chạm vào. Và tương tự, đối với bất kỳ thay đổi mã nào, có một lượng "gợn" tối thiểu thông qua các lớp khác.
Nhìn vào tình huống ví dụ bạn có, hãy xem YAGNI và RẮN có thể nói gì. Bạn đang xem xét một giao diện kho lưu trữ phổ biến do thực tế là tất cả các kho lưu trữ trông giống nhau từ bên ngoài. Nhưng giá trị của một giao diện chung, chung là khả năng sử dụng bất kỳ trình triển khai nào mà không cần biết cụ thể là giao diện nào. Trừ khi có một nơi nào đó trong ứng dụng của bạn, nơi điều này sẽ cần thiết hoặc hữu ích, YAGNI nói đừng làm điều đó.
Có 5 nguyên tắc RẮN để xem xét. S là Trách nhiệm duy nhất. Điều này không nói gì về giao diện, nhưng nó có thể nói điều gì đó về các lớp cụ thể của bạn. Có thể lập luận rằng việc tự xử lý truy cập dữ liệu có thể là trách nhiệm của một hoặc nhiều lớp khác, trong khi trách nhiệm của kho lưu trữ là dịch từ ngữ cảnh ngầm (CustomerRep repository là một kho lưu trữ ngầm cho các thực thể Khách hàng) thành các cuộc gọi rõ ràng đến API truy cập dữ liệu tổng quát chỉ định loại thực thể Khách hàng.
O là Đóng-Đóng. Điều này chủ yếu là về thừa kế. Nó sẽ được áp dụng nếu bạn đang cố gắng lấy các kho lưu trữ của mình từ một cơ sở chung triển khai chức năng chung hoặc nếu bạn dự kiến sẽ lấy thêm từ các kho khác nhau. Nhưng bạn thì không, vì vậy nó không.
L là Liskov Thay thế. Điều này áp dụng nếu bạn có ý định sử dụng các kho lưu trữ thông qua giao diện kho lưu trữ chung. Nó đặt các hạn chế trên giao diện và triển khai để đảm bảo tính nhất quán và tránh xử lý đặc biệt cho các yếu tố khác nhau. Lý do cho điều này là việc xử lý đặc biệt như vậy làm suy yếu mục đích của một giao diện. Có thể hữu ích khi xem xét nguyên tắc này, bởi vì nó có thể cảnh báo bạn khỏi việc sử dụng giao diện kho lưu trữ chung. Điều này trùng với hướng dẫn của YAGNI.
Tôi là phân chia giao diện. Điều này có thể áp dụng nếu bạn bắt đầu thêm các hoạt động truy vấn khác nhau vào kho lưu trữ của mình. Phân tách giao diện áp dụng trong đó bạn có thể chia các thành viên của một lớp thành hai tập con, trong đó một tập hợp sẽ được sử dụng bởi một số người tiêu dùng và người khác, nhưng không người tiêu dùng nào có thể sử dụng cả hai tập hợp con. Hướng dẫn là tạo hai giao diện riêng biệt, thay vì một giao diện chung. Trong trường hợp của bạn, không có khả năng tìm nạp và lưu các cá thể riêng lẻ sẽ được sử dụng bởi cùng một mã sẽ thực hiện truy vấn chung, do đó, có thể hữu ích khi tách chúng thành hai giao diện.
D là tiêm phụ thuộc. Ở đây chúng ta quay trở lại cùng một điểm với S. Nếu bạn tách mức tiêu thụ API truy cập dữ liệu của mình thành một đối tượng riêng biệt, nguyên tắc này nói rằng thay vì chỉ tạo một thể hiện của đối tượng đó, bạn nên chuyển nó vào khi bạn tạo một kho lưu trữ. Điều này giúp kiểm soát tuổi thọ của thành phần truy cập dữ liệu dễ dàng hơn, mở ra khả năng chia sẻ các tham chiếu đến nó giữa các kho lưu trữ của bạn mà không cần phải đi theo con đường biến nó thành một singleton.
Điều quan trọng cần lưu ý là hầu hết các nguyên tắc RẮN không nhất thiết phải áp dụng ở giai đoạn phát triển ứng dụng cụ thể này. Ví dụ, việc bạn có nên thoát ra khỏi truy cập dữ liệu hay không tùy thuộc vào mức độ phức tạp của nó và liệu bạn có muốn kiểm tra logic kho lưu trữ của mình mà không cần nhấn cơ sở dữ liệu hay không. Nghe có vẻ như điều này là không thể (thật không may, theo ý kiến của tôi), vì vậy có lẽ không cần thiết.
Vì vậy, sau tất cả những cân nhắc đó, chúng tôi thấy rằng YAGNI và RẮN thực sự cung cấp một lời khuyên chung, có liên quan ngay lập tức: Có lẽ không cần thiết phải tạo giao diện kho lưu trữ chung chung.
Tất cả những suy nghĩ cẩn thận này là vô cùng hữu ích như một bài tập học tập. Nó tốn thời gian khi bạn học, nhưng theo thời gian, bạn phát triển trực giác và trở nên rất nhanh. Bạn sẽ biết điều đúng cần làm, nhưng không cần phải nghĩ tất cả những từ này trừ khi có ai đó yêu cầu bạn giải thích lý do.