Bài 8 - Nguyên tắc lập trình DRY là gì?

Để công việc lập trình của bạn trở nên dễ dàng hơn thì các lập trình viên thường áp dụng một số nguyên tắc như DRY, SOLID, YAGNI, KISS... Trong đó nguyên tắc căn bản được áp dụng nhiều trong lập trình đó là nguyên tắc DRY - Don't Repeat Yourself (các nguyên tắc khác bạn có thể tự tìm hiểu bằng cách search các từ khóa này trên Google). Vậy nguyên tắc DRY có nghĩa là gì, vì sao cần sử dụng nguyên tắc này trong lập trình. Mời bạn tìm hiểu qua bài viết này nhé.

Don't repeat yourself dịch sang tiếng Việt có nghĩa là "đừng lặp lại chính bạn", trong lập trình nó có nghĩa là "đừng lặp lại code chính bạn". Chúng ta sẽ bắt đầu bằng 1 câu chuyện của 1 anh lập trình viên như sau:

Chuyện kể rằng, có anh lập trình viên nọ lọ mọ viết code bằng PHP, sếp yêu cầu anh ta hãy in ra màn hình chữ "xin chào". Việc này quá đơn giản với anh, anh liền viết câu lệnh như sau: 

 echo "Xin chào";

Rồi một ngày đẹp trời nọ, sếp bảo anh "chú viết cho anh 1000 lần xin chào nhé, đơn giản mà". "Móa, chẳng nhẽ phải viết 1000 câu lệnh đơn lẻ, như thế không ổn, rồi hôm nào sếp dở chứng bảo sửa "xin chào" thành "xin chào thế giới" thì lại phải sửa 1000 dòng, thế thì xin vĩnh biệt cụ thật", anh thầm nghĩ. Và thế là anh tìm hiểu và tóm được vòng lặp for, sau một hồi anh viết lệnh như sau:

for($i=1;$i<=1000;$i++){
    echo "xin chào";
}

Như bạn thấy đấy, anh lập trình viên thay vì viết 1000 câu lệnh echo "xin chào" lặp đi lặp lại thì giờ đây code của anh ngắn gọn hơn rất nhiều mà vấn đáp ứng được công việc, sửa dễ dàng. Nếu bảo in 1 triệu thì thêm 3 số 0 vào, muốn in câu "xin chào bạn" thì chỉ cần thêm chữ "bạn" vào là xong. Nếu bạn chưa biết vòng lặp for là gì thì ở trong seriez "PHP cơ bản" bạn sẽ tìm hiểu rõ hơn, trong ví dụ này bạn hiểu vòng lặp for giúp bạn thực hiện 1 đoạn code lặp đi lặp lại và có giới hạn (ở đây 1000 là giới hạn).

Nhưng câu chuyện chưa dừng lại ở đây, mấy hôm sau sếp lại bảo với anh rằng "chú viết cho anh 200 câu lệnh xin chào ba mẹ", và viết cho anh "300 lệnh xin chào người yêu". Anh hí hoáy viết thêm 2 vòng for nữa nhưng lại thầm nghĩ yêu cầu công việc của sếp có điểm chung, đó là đều in ra số lượng câu lệnh (200, 300...) và đoạn text để in (xin chào ba mẹ, xin chào người yêu...). Vậy có cách nào tối ưu code không? Sau một hồi loay hoay đọc tài liệu thì anh phát hiện ra giải pháp tuyệt vời, đó là anh sẽ viết 1 hàm để xử lý vấn đề này.

Ngắt lời một chút để mình giới thiệu bạn về khái niệm hàm (function). Khái niệm hàm đơn giản lắm, hàm có 2 loại: 1 là có giá trị trả về, 2 là không có giá trị trả về (trong lập trình Passcal gọi là thủ tục, tập hợp các lệnh có ý nghĩa lại với nhau. Ví dụ: thủ tục nấu cơm sẽ bao gồm vo gạo, rửa xong, nấu cơm, ghế cơm...). Với loại 1 loại mà có giá trị trả về thì nó giống như máy làm súc xích vậy: đút con bò vào máy sẽ sản xuất ra được xúc xích. Mà muốn đút con bò vào thì ta cần có cái khay, (khay gọi là tham số của hàm, con bò gọi là đối số của hàm (giá trị thực truyền vào), còn xúc xích là kết quả trả về của hàm).
Ví dụ ta viết hàm có tên là "máy làm xúc xích" như sau:

function may_lam_xuc_xich($khay_con_bo){
        //Quy trình Xử lý con bò: lọc thịt, bỏ xương, nhào nặn ra xúc xích
        return $xuc_xich; //câu lệnh return trả về giá trị nào đấy
    }

Muốn sử dụng cái máy này thì ta có lời gọi hàm (giống như công tắc khởi động máy). Ta gọi:

may_lam_xuc_xich($con_bo_that_nang_100kg); //trả về xúc xích 

Trở lại câu chuyện trên, anh lập trình viên nảy ra 1 ý tưởng là viết 1 hàm có tên in_cau_lenh với 2 tham số là số câu lệnhtext in ra như sau:

function in_cau_lenh ($so_cau_lenh=1,$text_in_ra=''){
		for($i=1;$i<=$so_cau_lenh;$i++){
			echo "$text_in_ra";
		}
	}

Câu lệnh khi gọi hàm

in_cau_lenh(200,"xin chào ba mẹ");
in_cau_lenh(300,"xin chào người yêu");
in_cau_lenh(400,"xin chào anh hàng xóm");
...

Lưu ý: $so_cau_lenh=1; ta có thể gán giá trị mặc định cho đối số hàm, trường hợp không truyền giá trị thì nó sẽ lấy giá trị này ra ví dụ: in_cau_lenh("","xin chào 500 anh em"); sẽ in ra 1 câu "xin chào 500 anh em"

Như vậy bằng cách viết 1 hàm chỉ 4 dòng thì anh lập trình viên đã giải quyết ổn thỏa được công việc, giờ sếp thích in bao nhiêu dòng, in text gì cũng chiến được hết. Khi cần sửa thì anh ấy chỉ cần vào hàm in_cau_lenh để sửa là xong.

Bạn cũng cần biết là cách viết lệnh bằng hàm là cách viết phổ biến của lập trình có cấu trúc, về sau các hàm này chính là phương thức (method) của class trong OOP (lập trình hướng đối tượng). Bạn hiểu đơn giản class là khuôn mẫu, từ khuôn mẫu này có thể tạo ra hàng trăm cái bánh (đối tượng) và điều đặc biệt là class con có thể kế thừa class cha của nó.

Với hướng tiếp cận lập trình hướng đối tượng thì số lượng dòng code cũng giảm đi đáng kể và cũng tránh trùng lặp code (phương thức kế thừa), do đó chương trình trở nên đơn giản, dễ bảo trì, nâng cấp mở rộng hơn rất nhiều.

Kết luận:

Thông qua câu chuyện vui trên thì bạn đã phần nào hiểu được nguyên tắc lập trình DRY rồi phải không? Nguyên tắc lập trình DRY áp dụng nhiều trong thực tế. Bất cứ khi nào bạn thấy dòng code mình lặp đi lặp lại thì hãy nghĩ ngay tới hàm, tới nguyên tắc lập trình DRY này. 

Tác giả: Admin