# 30: Nguyên tắc DRY: Don’t repeat yourself

Trong tất cả các nguyên tắc lập trình , Don’t Repeat Yourself (DRY) (opens new window) có lẽ là một trong những điều cơ bản nhất. Nguyên tắc này được nhắc tới lần đầu trong cuốn sách The Pragmatic Programmer​ viết bởi Andy Hunt và Dave Thomas , và cũng là nền tảng cho việc phát triển các software development và design pattern khác. Những developer nào nhận ra được các sự trùng lặp, và biết cách để loại bỏ nó thông qua thực tiễn và trừu tượng hóa một cách phù hợp thì những người đó có thể có thể viết code sạch sẽ và gọn (clean code ) hơn nhiều so với những người viết code lặp đi lặp lại một cách thừa thãi.

Trùng lặp là một sự thừa thãi

Mỗi một dòng code tạo nên ứng dụng đều cần được bảo trì, và nó cũng là nguy cơ tiềm ẩn cho sự xuất hiện của những con bug sau này. Sự trùng lặp sẽ “thổi phồng” codebase của bạn ,và vô tình làm cho hệ thống thêm phức tạp hơn. Sự tăng kích cỡ codebase cũng sẽ làm cho các developer khó có thể làm việc khi không thể hiểu rõ toàn bộ hệ thống, hoặc không thể chắc chắn rằng nếu sửa đổi code ở một vị trí thì có cần phải thay đổi ở những chỗ có logic tương tự hay không. Nguyên lý DRY yêu cầu “mỗi giải thuật trong một hệ thống chỉ được có một đại diện duy nhất, rõ ràng và có thẩm quyền” (câu gốc :”every piece of knowledge must have a single, unambiguous, authoritative representation within a system”)

Tự động hóa sự lặp lại trong process call

Nhiều quy trình trong phát triển phần mềm được lặp đi lặp lại và dễ dàng tự động hóa. Nguyên tắc DRY phù hợp để áp dụng vào những trường hợp này cũng như trong source code của ứng dụng. Test thủ công rất tốn thời gian, dễ bị lỗi, và khó để lặp lại, vì vậy các bộ kiểm tra tự động nên được sử dụng ở những vị trí khả thi. Tích hợp phần mềm có thể sẽ mất thời gian và dễ gây lỗi nếu được làm một cách thủ cộng, do đó một quy trình xây dựng nên được cho chạy một cách thường xuyên, lý tưởng nhất là với mỗi lần check-in. Bất cứ chỗ nào có những quy trình thủ công bị hư hại mà có thể tự động hóa, thì chúng nên được tự động hóa và tiêu chuẩn hóa. Mục đích của việc này là để đảm bảo chỉ có duy nhất một cách hoàn thành công việc, và là một cách ít gây hại nhất.

Trừu tượng hóa sự lặp lại trong Logic Call

Sự lặp lại ở trong logic có thể có nhiều dạng. copy-Paste, If-then hoặc switch-case, chúng thuộc những loại logic dễ nhận ra và dễ sửa lỗi nhất. Nhiều design pattern có mục tiêu rõ ràng về việc giảm thiểu hoặc loại bỏ sự trùng lặp logic trong một application. Nếu một object điển hình require nhiều thứ xảy ra trước khi nó được sử dụng tới thì nó có thể được làm bằng cách sử dụng pattern Abstract Factory hoặc Factory Method. Nếu một object có nhiều biến khác nhau trong behavior của nó, thì những behavior này nên được truyền vào bằng cách sử dụng Strategy pattern thay vì sử dụng một đống cấu trúc if-then. Trong thực tế, việc tạo ra các design pattern là một sự nỗ lực giảm thiểu sự lặp cấu trúc để giải quyết các vấn đề thường gặp và thảo luận về các giải pháp đó. Hơn nữa, nguyên lý DRY có thể được áp dụng trực tiếp vào cấu trúc như là database schema để đơn giản hoá nó.

Một vấn đề về nguyên lý DRY

Các nguyên tắc phần mềm khác cũng đều có liên quan tới DRY:

Như nguyên tắc một và chỉ một (Once and Only Once principle), là nguyên tắc chỉ áp dụng cho các behavior function, nó cũng được coi như là một nguyên tắc bắt nguồn từ nguyên tắc DRY.

Nguyên tắc đóng mở (Open/Closed Principle), là nguyên tắc chỉ ra rằng : ”Các software entity nên được mở ra cho sự mở rộng, nhưng đóng lại cho sự thay đổi”, trong thực tế, nguyên tắc này chỉ hoạt động khi tuân theo nguyên tắc DRY. Cũng tương tự như vậy

Nguyên tắc được biết đến khá nhiều đó là nguyên tắc Single Responsibility, nguyên tắc này yêu cầu một class “chỉ có một lý do để thay đổi“, đó là dựa trên DRY.

Khi tuân theo cấu trúc, logic, quy trình và chức năng, nguyên tắc DRY cung cấp sự hướng dẫn cơ bản cho các software developer và hỗ trợ tạo ra các phần mềm đơn giản, dễ bảo trì và có chất lượng cao hơn. Mặc dù có những trường hợp việc lặp lại có thể cần thiết để đáp ứng hiệu suất hoặc các yêu cầu khác (ví dụ : không chuẩn hóa dữ liệu trong database), nhưng nó chỉ nên được sử dụng khi trực tiếp giải quyết một vấn đề thực tế chứ không phải là một vấn đề tưởng tượng.