Không có một con số dòng cố định cho độ dài của hàm. Bạn nên tách một hàm khi nó làm nhiều hơn một việc, khi phải cuộn màn hình mới thấy hết, khi có một đoạn bên trong cần chú thích mới hiểu nó làm gì, hoặc khi một phần có thể đặt một cái tên riêng rõ ràng. Nhưng tách quá vụn cũng làm mã khó đọc không kém.
Chào bạn, đây là Nhà Lập Trình. Câu hỏi hàm bao nhiêu dòng là vừa được tranh cãi mãi trong giới lập trình. Có người nói không quá hai mươi dòng, có người nói không quá một màn hình, có người nói miễn dễ đọc là được. Tập này mình không đưa ra con số, mà đưa ra những dấu hiệu để bạn tự quyết.
Vì sao hàm dài khó chịu?
Một hàm vài trăm dòng giống một căn phòng không có ngăn kéo. Mọi thứ nằm lẫn lộn trên sàn. Muốn tìm một món, bạn phải bới từ đầu tới cuối.
Khi đọc hàm dài, bạn phải giữ trong đầu quá nhiều thứ cùng lúc: biến nào được tạo ở đầu hàm, được sửa ở giữa, được dùng ở cuối. Tới dòng thứ hai trăm, bạn đã quên biến ở dòng thứ mười được gán giá trị gì.
Hàm dài cũng khó thử nghiệm. Muốn kiểm tra phần tính thuế ở giữa, bạn phải chuẩn bị dữ liệu cho cả phần đầu và phần cuối. Muốn sửa một phần, bạn sợ ảnh hưởng tới những phần khác cùng dùng chung biến.
Và hàm dài có xu hướng dài thêm. Mỗi lần có yêu cầu mới, người ta thêm một đoạn điều kiện vào giữa, vì tách ra thì mất công. Sau vài năm, hàm trở thành một khối mà không ai dám đụng vào.
Dấu hiệu thứ nhất: hàm làm nhiều việc
Dấu hiệu rõ nhất là khi bạn mô tả hàm làm gì mà phải dùng chữ và. Hàm này kiểm tra đơn hàng, và tính tiền, và trừ kho, và gửi thư. Mỗi chữ và là một chỗ có thể tách.
Một cách thử khác: nhìn các khối trong hàm. Thường người viết đã vô thức nhóm mã thành từng khối, cách nhau bằng dòng trống, có khi kèm một dòng chú thích ở đầu mỗi khối. Mỗi khối có chú thích như vậy là một hàm đang chờ được tách ra, và dòng chú thích đó chính là gợi ý cho tên hàm.
Sau khi tách, hàm gốc trở thành một bản tóm tắt: kiểm tra đơn hàng, tính tiền, trừ kho, gửi thư. Bốn dòng, đọc như đọc mục lục. Ai muốn biết chi tiết phần nào thì mở phần đó ra.
Đây là lợi ích lớn nhất của việc tách hàm: không phải hàm ngắn đi, mà là mã có thêm một tầng tóm tắt, cho người đọc chọn đọc ở mức chi tiết nào.
Dấu hiệu thứ hai: cần chú thích hoặc lồng quá sâu
Nếu một đoạn trong hàm cần chú thích để giải thích nó làm gì, hãy cân nhắc tách đoạn đó ra thành hàm có tên đúng bằng nội dung chú thích. Tên hàm thay cho chú thích, và nó không bao giờ lỗi thời như chú thích, vì đổi việc thì người ta sẽ đổi tên.
Dấu hiệu khác là lồng quá sâu. Điều kiện trong vòng lặp, trong điều kiện, trong vòng lặp nữa. Mã thụt vào bốn năm tầng, lệch hẳn sang phải màn hình. Mỗi tầng lồng là một thứ nữa người đọc phải giữ trong đầu.
Có những cách giảm lồng mà không cần tách: kiểm tra các trường hợp đặc biệt ở đầu hàm rồi thoát sớm, thay vì bọc cả hàm trong một điều kiện lớn. Nhưng nhiều khi, phần lồng sâu nhất chính là một việc riêng, tách ra thì hàm gốc phẳng lại ngay.
Một mẹo mình hay dùng: nếu phải cuộn màn hình để thấy đầu và cuối của một khối lồng, đó là lúc nên nghĩ tới việc tách.
Tách quá vụn cũng là một bệnh
Nói vậy nhưng đừng đi tới cực đoan bên kia. Có những dự án mà mỗi hàm chỉ ba dòng, gọi hàm khác ba dòng, gọi hàm khác nữa. Để hiểu một việc đơn giản, bạn phải nhảy qua mười tệp, hai mươi hàm. Mỗi hàm đọc rất dễ, nhưng bức tranh tổng thể thì mất hẳn.
Tách hàm có giá khi mỗi hàm mới có một cái tên có ý nghĩa, và người đọc không cần mở nó ra để hiểu hàm gốc. Nếu tên hàm con không nói được gì, như xử lý phần hai, hoặc người đọc luôn phải mở ra xem, thì tách chỉ làm thêm bước nhảy.
Đừng tách chỉ vì hàm vượt một con số dòng nào đó. Một hàm năm mươi dòng làm đúng một việc, đọc một mạch từ trên xuống, đôi khi dễ hiểu hơn năm hàm mười dòng nhảy qua lại.
Mục tiêu không phải hàm ngắn, mà là mã dễ hiểu. Độ dài chỉ là một dấu hiệu, không phải đích đến.
Tách thế nào cho an toàn?
Khi tách hàm trong mã đang chạy, hãy đi từng bước nhỏ. Tách một phần, chạy thử, đảm bảo mọi thứ vẫn đúng, rồi mới tách phần tiếp theo. Đừng tách cả hàm một lúc rồi mới thử.
Nếu có bài thử nghiệm tự động cho hàm gốc, việc tách an toàn hơn nhiều. Nếu chưa có, hãy cân nhắc viết vài bài thử nghiệm cho hành vi hiện tại trước khi tách, để biết chắc mình không làm đổi hành vi.
Trình soạn thảo hiện nay thường có chức năng tách hàm tự động: bạn chọn một đoạn mã, nó tạo hàm mới, tự tìm những biến cần truyền vào và trả ra. Dùng chức năng này ít sai hơn làm bằng tay.
Và tách hàm là một thay đổi riêng. Đừng vừa tách hàm vừa sửa lỗi vừa thêm tính năng trong cùng một lần. Người xem lại mã sẽ không phân biệt được đâu là thay đổi hành vi, đâu chỉ là sắp xếp lại.
Câu hỏi thường gặp
Có quy tắc cụ thể về số dòng tối đa của một hàm không?
Một số đội đặt giới hạn làm gợi ý, nhưng không có con số đúng cho mọi trường hợp. Dấu hiệu quan trọng hơn là hàm có làm nhiều việc, có cần chú thích để hiểu hay có lồng quá sâu không.
Tách hàm có làm chương trình chạy chậm hơn không?
Trong hầu hết trường hợp, ảnh hưởng không đáng kể và thường được trình biên dịch tối ưu. Chỉ cân nhắc khi đo thật thấy một chỗ gọi hàm cực nhiều lần là điểm nghẽn.
Một hàm một việc nghĩa là gì?
Nghĩa là hàm có thể mô tả bằng một câu ngắn không cần chữ và. Các bước bên trong phục vụ cùng một mục đích và ở cùng một mức chi tiết.
Tách hàm quá vụn có sao không?
Có. Khi mỗi hàm quá nhỏ và tên không nói lên nhiều, người đọc phải nhảy qua nhiều nơi mới hiểu một việc đơn giản. Chỉ tách khi phần tách ra có tên rõ nghĩa và đọc tên là đủ hiểu.
Nên tách hàm lúc viết mới hay lúc sửa sau?
Cả hai. Lúc viết mới, nếu thấy rõ các phần riêng thì tách ngay. Lúc sửa sau, khi chạm vào một hàm dài, hãy tách phần mình đang làm để lần sau dễ hơn.