- Đây là cuộc đối thoại về thiết kế phần mềm giữa Robert “Uncle Bob” Martin và John Ousterhout, diễn ra từ tháng 9/2024 đến tháng 2/2025
- Cả hai đều đã viết sách về thiết kế phần mềm
- Họ thể hiện khác biệt quan điểm ở ba chủ đề chính: độ dài phương thức, chú thích và Test-Driven Development
- Trọng tâm của cuộc đối thoại là cách giảm độ phức tạp của mã, tăng khả năng đọc hiểu, và cách viết kiểm thử phù hợp
Độ dài phương thức
- Uncle Bob (sau đây viết tắt là UB) nhấn mạnh lập trường “hàm ngắn là tốt, nếu có thể thì nên tách ngắn hơn nữa”
- Một phương thức chỉ nên làm một “việc (One Thing)”
- Tuy nhiên, nếu áp dụng quá cực đoan, điều này có thể dẫn đến phân rã quá mức (over-decomposition)
- John chỉ ra rằng các phương thức quá nhỏ lại khiến việc hiểu toàn bộ luồng trở nên khó hơn
- Khi có quá nhiều phương thức “nông (shallow)”, để hiểu một chức năng, bạn phải xem hết các phương thức liên quan
- Mức độ phụ thuộc lẫn nhau giữa các phương thức (“entanglement”) tăng cao, làm gánh nặng đọc mã lớn hơn
- Ví dụ
PrimeGenerator
- Mã gốc của UB được chia thành khoảng 8 phương thức nhỏ, và các phương thức đan xen với nhau nên khó hiểu
- Phiên bản của John được viết theo dạng một phương thức với chú thích đầy đủ để có thể nắm toàn bộ luồng chỉ trong một lần nhìn
- UB cũng phần nào thừa nhận rằng “đã có sự phân rã quá mức”
- Kết luận là cả hai đều công nhận việc phân tách mã là quan trọng, nhưng điều cốt lõi là giữ được sự cân bằng giữa “chia quá nhỏ” và “để quá lớn”
Chú thích
- UB có quan điểm rằng chú thích là một “cái ác cần thiết (necessary evil)”
- Ông cho rằng chú thích dễ không được cập nhật, hoặc có nguy cơ chứa thông tin sai
- Ông thích cách làm sao cho ý định được thể hiện tối đa qua mã, và nếu cần thì dùng những cái tên rất dài
- John khẳng định chú thích là thực sự cần thiết
- Nếu ghi rõ bằng tiếng Anh mục đích của interface (phương thức) hoặc ý đồ triển khai, điều đó giúp các lập trình viên khác giảm thời gian phải lục tung mã không cần thiết
- Ông cho rằng “điều nguy hiểm nhất là tình huống không có chú thích, buộc phải tự diễn giải mã”
- Lấy
PrimeGenerator làm ví dụ, John chỉ ra rằng nếu không có chú thích giải thích “vì sao thuật toán lại hoạt động theo cách đó” thì sẽ rất khó hiểu
- UB giữ lập trường rằng “chú thích không chính xác thì còn gây hại hơn”, còn John nghiêng về quan điểm “chú thích sai còn đỡ hại hơn là không có chú thích”
- Cả hai đều phần nào đồng ý rằng “cần viết mức độ chú thích phù hợp tùy theo nhóm và tình huống”, nhưng nhìn chung John đánh giá giá trị của chú thích cao hơn rất nhiều
Refactor PrimeGenerator của John
- John tái cấu trúc đoạn mã vốn được tách thành 8 phương thức thành một phương thức duy nhất, hoặc cấu trúc 2~3 phương thức
- Ông thêm chú thích phong phú ở những phần cần thiết để giải thích “vì sao lại triển khai theo cách này”
- Thông qua chú thích, ông mô tả cùng lúc ý đồ của các biến chính (
multiples, primes) và cách thuật toán vận hành, nhằm giúp người đọc hiểu mã nhanh hơn
- UB cho biết ngay cả đoạn mã này cũng không hoàn toàn trực quan
- Để giải thích một thuật toán phức tạp vẫn cần thời gian, và chính tác giả cũng cảm thấy khó khăn trong quá trình xem xét lại
Refactor PrimeGenerator2 của Bob
- Đây là phiên bản UB chỉnh sửa nhẹ từ mã của John
- Ông tách thêm một vài phương thức để áp dụng “refactor tiếp theo”
- Ở phần vòng lặp, ông cải thiện khả năng đọc hiểu, nhưng hiệu năng đã tạm thời bị giảm
- John chỉ ra rằng “nếu chia thành các phương thức quá nhỏ thì có thể phát sinh vấn đề hiệu năng”, và UB đã chỉnh sửa lại để cải thiện hiệu năng
- Tuy vậy, do UB vẫn thích “giảm thiểu chú thích”, John vẫn giữ quan điểm rằng “nếu bổ sung thêm giải thích thì sẽ dễ hiểu hơn”
Test-Driven Development
- UB tích cực khuyến nghị cách làm TDD: viết kiểm thử trước theo chu kỳ ngắn, rồi từng chút một thêm mã để làm cho bài kiểm thử đang thất bại vượt qua
- Ông cho rằng cách này giúp mã luôn duy trì độ bao phủ kiểm thử và tránh gỡ lỗi phức tạp
- Lập trường của ông là mã sẽ được refactor thường xuyên và dần trở nên sạch hơn
- John lo ngại rằng TDD dễ trượt thành một “cách tiếp cận mang tính chiến thuật” quá mức
- Ông chỉ ra rằng “thiết kế cần phải đi trước, nhưng TDD lại dẫn dắt việc viết mã trước (triển khai tối thiểu để phục vụ kiểm thử)”
- Ông cho rằng một thiết kế tốt nên suy nghĩ phạm vi rộng hơn trong một lần, và tốt hơn là viết kiểm thử theo kiểu gom nhóm (bundling) cho phần mã đó
- UB thừa nhận có thể có “những vấn đề phát sinh do áp dụng TDD sai cách”, nhưng cho rằng nếu thực hành đúng thì nó sẽ giúp ích cho độ bao phủ kiểm thử và tái thiết kế (refactoring)
- John bày tỏ lo ngại rằng “đối với người mới, TDD thậm chí còn có nguy cơ khiến mã nhanh chóng trở nên lộn xộn”
- Cuối cùng, cả hai đồng ý rằng “nếu làm tốt thì cả TDD lẫn cách tiếp cận Bundling đều có thể tạo ra mã xuất sắc”, nhưng quan điểm về bên nào tốt hơn thì vẫn khác nhau
Lời kết
- John:
- Ông lo ngại rằng “Clean Code” nhấn mạnh quá mức vào việc tách hàm quá nhỏ và hạn chế chú thích, khiến độc giả có nguy cơ làm theo một cách cực đoan
- Nếu không viết đủ chú thích thì mã sẽ khó hiểu, và kết quả là lập trình viên phải tiêu tốn nhiều thời gian hơn
- Ông cũng chỉ ra rằng TDD có thể làm người ta bỏ lỡ thiết kế ở tầm bức tranh lớn
- UB:
- Ông cho biết ở bản 2 của “Clean Code” đã có phần nào bổ sung và tích hợp một phần ý kiến của John
- Tôn trọng những trải nghiệm và góc nhìn khác nhau, ông nhấn mạnh điểm chung rằng “mọi người đều nên hướng tới thứ mã sạch và dễ bảo trì”
- Tóm lại, cả hai đều đặt tầm quan trọng của thiết kế phần mềm và “làm cho mã dễ đọc” làm giá trị ưu tiên hàng đầu
- Tuy vậy, vẫn tồn tại khác biệt quan điểm về tiêu chí tách phương thức, cách sử dụng chú thích, và thứ tự viết kiểm thử
- Điểm cốt lõi là cần giữ được sự cân bằng phù hợp với môi trường nhóm và cấu trúc mã, đồng thời nỗ lực cải thiện thiết kế một cách liên tục
14 bình luận
Tôi có vài cuốn trong series Clean, nhưng có lẽ chúng chỉ phù hợp để tham khảo ở mức độ siêu nhận thức. Nếu coi chúng như nguyên tắc hay quy luật thì sẽ cực kỳ mệt mỏi, mà cũng không thực tế. Uncle Bob lúc nào cũng nói về các nguyên tắc SOLID, nhưng cá nhân tôi thấy nội dung thực dụng thì không nhiều lắm.
Tôi cho rằng
Code Complete,Clean Codeđồng hạng nhất trong danh sách những cuốn sách bị đánh giá quá cao.Bản dịch của Software Philosophy đã ra chưa? Tôi tìm thử nhưng không thấy.
Nghe có vẻ nghịch lý, nhưng với code tốt thì có lẽ những cuốn sách kiểu mỉa mai như "cách code sao cho khó bảo trì" lại dễ thấm hơn là các cuốn sách chỉ nói kiểu cái này là tốt.
Dạo này có vẻ tôi cãi nhau nhiều hơn vì những người hâm mộ một tech stack hoặc kiến trúc cụ thể, hơn là vì clean code, cứ nói như thể nếu không áp dụng tech stack hay kiến trúc đó thì sẽ xảy ra chuyện lớn vậy. Phải xem tình huống mà áp dụng mới đúng, có lẽ chẳng có gì là tốt một cách tuyệt đối.
Một cuộc thảo luận thật tuyệt.
Nghĩ lại thì tôi cũng có giới thiệu cho các bạn junior cuốn philosophy of sw design của John, nhưng lại không đặc biệt khuyến nghị clean code.
Có vẻ điều quan trọng là không mù quáng làm theo mỗi tiêu đề, mà phải hiểu rõ ngữ cảnh và áp dụng cho phù hợp.
Sách tự phát triển bản thân về lập trình có thể ổn với người mới bắt đầu khi họ chưa có quan điểm rõ ràng về công nghệ hay cách triển khai, nhưng tôi nghĩ hiệu quả của chúng sẽ giảm dần khi kinh nghiệm tích lũy nhiều hơn. Cũng vì không có chân lý tuyệt đối nào phù hợp với mọi dự án và môi trường, và cũng có những tình huống mà các nguyên tắc chung không thể áp dụng. Giống như lời khuyên trong các sách tự phát triển bản thân phổ thông khác, có lẽ nên giữ một khoảng cách vừa phải, chỉ áp dụng những lời khuyên phù hợp với hoàn cảnh, và không mù quáng theo đuổi chúng.
Tôi có phần đồng cảm với ý kiến của John hơn.
Có lẽ điều cốt lõi là không nên vô điều kiện làm theo lời của hai người như một giáo điều, mà phải hiểu vì sao lại như vậy rồi tiếp tục tiến lên.
Đừng quên rằng clean code không phải là mục tiêu, mà là phương tiện để đạt tới mục tiêu.
Đúng là điều quan trọng vẫn là sự vừa phải.
Rất hữu ích 👍🏻
Ý kiến trên Hacker News
Một số người có thể rất giáo điều về những thứ cụ thể. Tôi không thể hiểu vì sao họ lại tiếp nhận những điều này như chân lý
Chỉ cần từng trải nghiệm một dự án mù quáng làm theo khuyến nghị của Uncle Bob là sẽ thấy giá trị của chúng thấp đến mức nào
Clean Code là một trong các công cụ trong hộp đồ nghề của một kỹ sư phần mềm giỏi
Một số người chỉ đơn giản gom các dòng ở gần nhau rồi gọi đó là "refactor", thay vì tách hàm khi nó có thể tái sử dụng hoặc có ý nghĩa logic
Có một trường hợp quan trọng về tầm quan trọng của comment mà chưa được nhắc đến
Rất khuyến nghị "A Philosophy of Software Design"
Đây là phản ứng trước những vấn đề thực tế của ngành phần mềm trước phong trào Clean Code
Ý kiến của Bob về comment khá kỳ lạ
Sách của Uncle Bob là thứ bạn sẽ dần rời bỏ theo thời gian
Có sự khó chịu với chính cái tên Clean Code