[ Better ] 10 Mẹo Áp Dụng DRY Nguyên Tắc Cho Lập Trình Viên dễ bảo trì
Nguyên tắc cơ bản Một nguyên tắc lập trình quan trọng là DRY (Don’t Repeat Yourself), 10 mẫu dry giúp tăng hiệu quả và tính bảo trì của phần mềm bằng cách giảm thiểu việc lặp lại mã nguồn. Đây là mười cách tốt nhất để sử dụng nguyên tắc DRY trong lập trình hàng ngày.
Table of Contents
Sử Dụng Hàm Để Tránh Lặp Lại Mã
Không Tuân Thủ DRY
function calculateAreaOfSquare(side) { return side * side; } function calculateAreaOfRectangle(length, width) { return length * width; } function calculateAreaOfCircle(radius) { return Math.PI * radius * radius; } console.log(calculateAreaOfSquare(4)); // 16 console.log(calculateAreaOfRectangle(4, 5)); // 20 console.log(calculateAreaOfCircle(3)); // 28.274333882308138
Trong ví dụ trên, chúng tôi sử dụng ba hàm khác nhau để tính diện tích của ba hình riêng biệt. Mỗi hàm sử dụng logic tính diện tích của riêng mình, dẫn đến việc lặp lại mã nguồn.
Ví dụ tuân thủ nguyên tắc DRY
function calculateArea(shape, ...dimensions) { switch (shape) { case 'square': return dimensions[0] * dimensions[0]; case 'rectangle': return dimensions[0] * dimensions[1]; case 'circle': return Math.PI * dimensions[0] * dimensions[0]; default: throw new Error('Unknown shape'); } } console.log(calculateArea('square', 4)); // 16 console.log(calculateArea('rectangle', 4, 5)); // 20 console.log(calculateArea('circle', 3)); // 28.274333882308138
Chúng tôi tạo ra một hàm calculateArea duy nhất trong ví dụ này để tính diện tích cho các loại hình khác nhau. Chúng ta giảm thiểu việc lặp lại mã nguồn và tuân thủ nguyên tắc DRY bằng cách sử dụng một hàm với tất cả các tham số hình dạng và kích thước.
Một số nguyên tắc lập trình khác ngoài nguyên tắc DRY:
Một số nguyên tắc lập trình khác ngoài nguyên tắc DRY:
– KISS (Keep It Simple, Stupid): Nguyên tắc này giúp mã nguồn trở nên dễ hiểu và đơn giản. Bảo trì và mở rộng mã có thể trở nên khó khăn do mã phức tạp.
– YAGNI (You Ain’t Gonna Need It): Nguyên tắc này khuyến khích bạn tránh thêm các tính năng không cần thiết vào mã. Mã có thể trở nên phức tạp hơn và kém linh hoạt hơn do thêm các tính năng không cần thiết.
TỐT:
S (Quy tắc một trách nhiệm): Mỗi lớp hoặc module nên chỉ có một trách nhiệm.
O (Nguyên tắc mở/đóng): Mã nguồn có thể mở rộng nhưng không thay đổi.
L (Liskov Substitution Principle): Đối tượng của một lớp có thể được thể hiện cho đối tượng của lớp cha mà không ảnh hưởng đến chất lượng chương trình.
Theo nguyên tắc phân chia interface, các interface nhỏ và dễ hiểu được ưu tiên hơn các interface lớn.
Law of Demeter (LoD): Nguyên tắc này nói rằng mỗi thứ chỉ nên tương tác với những thứ mà nó biết và không nên tiếp cận các thành phần bên trong của những thứ khác.
Composition over Inheritance: Thúc đẩy việc sử dụng hình thức thay vì di truyền để tạo ra các hệ thống linh hoạt hơn và dễ duy trì hơn.
Thất bại nhanh: Khi có lỗi, hãy thất bại ngay lập tức. Theo nguyên tắc này, lỗi nên được kiểm tra và xử lý ngay khi chúng xảy ra để ngăn ngừa các vấn đề phức tạp trong tương lai.
Ví dụ
try{ console.log("Lỗi nè"); } catch(err){ }
Xử lý các quan tâm (SoC): Tách biệt các quan tâm khác nhau trong mã nguồn. Xử lý dữ liệu, hiển thị giao diện và logic kinh doanh là một ví dụ về các quan tâm này. Điều này giúp bảo trì và mở rộng mã.
Quy định về cấu hình (CoC): Ưu tiên việc sử dụng các cấu hình mặc định hoặc quy ước hơn là yêu cầu người phát triển cấu hình chi tiết. Điều này làm giảm nhu cầu cấu hình và tăng hiệu suất.
Một khuôn khổ chung về cách viết mã nguồn một cách có tổ chức, dễ hiểu và dễ bảo trì được cung cấp bởi các nguyên tắc này.
Ví dụ về DRY dùng args
Không tuân thủ Dry
function calculateAreaOfSquare(side) { return side * side; } function calculateAreaOfRectangle(length, width) { return length * width; } function calculateAreaOfCircle(radius) { return Math.PI * radius * radius; }
Tuân thủ Dry
function calculateArea(shape, ...dimensions) { switch (shape) { case 'square': return dimensions[0] * dimensions[0]; case 'rectangle': return dimensions[0] * dimensions[1]; case 'circle': return Math.PI * dimensions[0] * dimensions[0]; default: throw new Error('Unknown shape'); } }
- Sử dụng Args để truyền bất kì tham số nào vào có thể là side, lenght, width, radius bằng cách quy định chung là dimensions với 0 là width, 1 là height
Ví dụ 2 về Dry dùng biến để dễ nhìn hơn
Không Tuân Thủ DRY
const taxRate = 0.08; const price1 = 100 * (1 + 0.08); const price2 = 200 * (1 + 0.08);
Tuân thủ nguyên tắt
const taxRate = 0.08; const price1 = 100 * (1 + taxRate); const price2 = 200 * (1 + taxRate);
Khi đó với mỗi biến sẽ là 1 mục trong tính toán như tax, amount, price, total_price vv
Và chính vì vậy sẽ dễ thao tác tính toán hơn, mỗi khi ta có sự thay đổi về giá trị thì cũng dễ bảo trì hơn
Ví dụ 3 về Dry Sử Dụng Constants Cho Các Giá Trị Tĩnh
Không tuân thủ
const pi1 = 3.14159; const pi2 = 3.14159;
Tuân thủ nguyên tắt
const PI = 3.14159; const circleArea1 = PI * radius1 * radius1; const circleArea2 = PI * radius2 * radius2;
Với các hằng số như PI, các biến môi trường, các URL dùng chung thì nên tạo ra 1 file là đặt là static
Có thể dùng qua config như tôi cấu hình trên flask
Tái Sử Dụng Code Với Các Thư Viện Chung
Không Tuân Thủ DRY
class User { constructor(name) { this.name = name; } }
Tuân thủ nguyên tắt
class Person { constructor(name) { this.name = name; } } class User extends Person { // User-specific methods }
Bạn hãy luôn sử dụng Base, hoặc lớp parent để khởi tạo các giá trị dùng chung cho các class để khi mở rộng code có thể tái sử dụng thuộc tính đã tạo và chỉ cần overrive
Sử Dụng Template Literals Để Tránh Lặp Lại Chuỗi
Không tuân thủ
const greeting1 = "Hello, " + name1 + "!"; const greeting2 = "Hello, " + name2 + "!";
Tuân thủ
function getGreeting(name) { return `Hello, ${name}!`; } const greeting1 = getGreeting(name1); const greeting2 = getGreeting(name2);
Đây là cách tôi áp dụng template Literals vào dự án
Sử Dụng Destructuring Để Tránh Lặp Lại Mã
Không tuân thủ
const person = { name: 'John', age: 30 }; const name = person.name; const age = person.age;
Tuân thủ
const person = { name: 'John', age: 30 }; const { name, age } = person;
Khi có một object hoặc 1 array thì bạn có thể dùng Destructuring để có thể lấy nha thuộc tính cần lấy mà không cần quan phải gán vào biến hay phải lấy từng thuộc tính
Code nó sẽ gọn hơn và dễ bảo trì hơn, nếu thuộc tính đó không có thì nó lẽ báo lỗi cho mình biết để dễ sử lỗi hơn
Sử Dụng Các Thư Viện và Frameworks
Không tuân thủ
function ajaxGet(url, callback) { const xhr = new XMLHttpRequest(); xhr.open('GET', url); xhr.onload = () => callback(xhr.responseText); xhr.send(); }
Tuân thủ
fetch(url) .then(response => response.json()) .then(data => console.log(data));
Bạn hãy dùng fetch hoặc axios hoặc dio thay vì dùng XML hay các phương thức request khác
Sử Dụng Higher-Order Functions
Không tuân thủ
function doubleNumbers(numbers) { let result = []; for (let i = 0; i < numbers.length; i++) { result.push(numbers[i] * 2); } return result; }
Tuân thủ
function doubleNumbers(numbers) { return numbers.map(number => number * 2); }
Với map là 1 HOF có chức năng tương tự nhưng khi bạn nhìn vào sẽ gọn hơn và dễ bảo trị hơn
Tạo Các Component Tái Sử Dụng Trong React
Không tuân thủ
function Header() { return <h1>My App</h1>; } function Footer() { return <h1>My App</h1>; }
Tuân thủ
function Title({ text }) { return <h1>{text}</h1>; } function Header() { return <Title text="My App" />; } function Footer() { return <Title text="My App" />; }
Tái Sử Dụng Cấu Trúc Dữ Liệu
Không tuân thủ
const user1 = { name: 'John', age: 30 }; const user2 = { name: 'Jane', age: 25 };
Tuân thủ
function createUser(name, age) { return { name, age }; } const user1 = createUser('John', 30); const user2 = createUser('Jane', 25);
Khi bạn chỉ tạo một object và gán thuộc tính thì người dùng sẽ không biết nó có tác dụng gì
Nhưng nếu bạn đưa vào hàm và đặt tên nhìn vào sẽ dễ hiểu hơn khi bảo trì.
Kết luận
Viết mã nguồn rõ ràng, dễ hiểu và dễ bảo trì hơn sẽ dễ dàng hơn nếu bạn áp dụng các hướng dẫn này. Để nâng cao chất lượng và hiệu quả trong công việc lập trình của bạn, hãy bắt đầu sử dụng nguyên tắc DRY ngay hôm nay!
#Mtips5s #Contact
Fanpage: https://www.facebook.com/mtipscoder
Group trao đổi, chia sẻ: https://www.facebook.com/groups/mtipscoder
Website: https://mtips5s.com
Youtube: https://mtips5s.com
Twitter(X): @takagiks99
Instagram: @khuongkara
Threads: @khuongkara
Google Maps: @khuongkara
#Base Code #Souce Code
Npm: @tools.mtips5s.com
Bộ công cụ My Self: @github
Npm: @npm
Docker: @docker
Chúc các bạn thành công!
Written by admin
Comments
This post currently has no responses.