47 điểm bởi GN⁺ 2025-02-26 | 14 bình luận | Chia sẻ qua WhatsApp
  • Đâ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

 
mhj5730 2025-03-02

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.

 
ahwjdekf 2025-03-01

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.

 
carnoxen 2025-02-28

Bản dịch của Software Philosophy đã ra chưa? Tôi tìm thử nhưng không thấy.

 
mageia 2025-02-28

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.

 
aer0700 2025-02-27

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.

 
yadameda 2025-02-26

Một cuộc thảo luận thật tuyệt.

 
spilist2 2025-02-26

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.

 
bbulbum 2025-02-26

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.

 
savvykang 2025-02-26

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.

 
nicewook 2025-02-26

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.

 
leojineoo 2025-02-26

Đừ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.

 
ilikeall 2025-02-26

Đúng là điều quan trọng vẫn là sự vừa phải.

 
elddytbt 2025-02-26

Rất hữu ích 👍🏻

 
GN⁺ 2025-02-26
Ý 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ý

    • Tôi từng phải làm việc với những người nổi giận mỗi khi vượt quá giới hạn 80 ký tự trên một dòng
    • Xu hướng này còn nghiêm trọng hơn không chỉ ở phong cách lập trình, pattern, idiom mà cả ở tech stack và kiến trúc giải pháp
    • Trò chuyện với những người chỉ trích dẫn nguyên xi những gì họ đọc trong sách hay blog thật sự rất bức bối
    • Điều này đặc biệt tệ trong thời kỳ NoSQL và microservices bùng nổ, và tôi vẫn cảm nhận thấy nó ở PaaS/SaaS và container hóa
    • Những ứng dụng, lambda hay tác vụ biến đổi chỉ thực hiện chức năng cơ bản lại chỉ làm tăng gánh nặng bảo trì và không mang lại giá trị
    • Khác biệt giữa tác giả sách hay blog và tôi chỉ là họ đã viết ra. Cần luôn nhớ rằng ý kiến của họ không phải là sự thật
  • 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

    • Ông ấy đã tạo ra vài văn bản nhằm cải thiện software engineering, nhưng chúng đầy rẫy lời khuyên tệ hại
    • Thành công của ông ấy đến từ nhu cầu vô tận của các lập trình viên junior đang tìm kiếm chỉ dẫn
    • Code với quá nhiều lớp gián tiếp trở thành thứ rất khó làm việc cùng
  • 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

    • Khi đọc Clean Code thời đại học, tôi đã cảm nhận được bầu không khí chung từ Uncle Bob
    • Có vẻ điều đó bắt nguồn từ lối suy nghĩ rằng hàm phải dài đúng X dòng
    • Tôi biết ơn tính năng inline của IDE hiện đại và dùng nó để tái cấu trúc nhằm hiểu code
  • 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

    • Khi viết phần mềm driver cho thiết bị USB, rất dễ đưa thiết bị vào trạng thái sai
    • Mỗi khi triển khai một cách khắc phục, tôi đều thêm comment để ghi lại tài liệu
    • Nếu không có comment, người khác sẽ rất khó hiểu được ý đồ của đoạn code
  • Rất khuyến nghị "A Philosophy of Software Design"

    • Cốt lõi là đo chất lượng của abstraction bằng tỷ lệ độ phức tạp
    • Sau khi đọc các sách lời khuyên lập trình khác, code của tôi không hề tốt hơn
  • Đâ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

    • Clean Code đã đưa mọi thứ đi theo hướng tốt hơn, nhưng bị chỉnh quá tay
    • Không rõ liệu mọi người có quay lại với các method khổng lồ và các câu lệnh điều kiện lồng sâu hay không
  • Ý kiến của Bob về comment khá kỳ lạ

    • Sự hoang tưởng về comment sai là vô lý
    • Tôi đã lãng phí quá nhiều thời gian vì code không rõ ràng
    • Thay vì vẽ những sơ đồ kỳ quặc, thà giải thích ngắn gọn thuật toán hoặc đưa link còn dễ hơn
  • Sách của Uncle Bob là thứ bạn sẽ dần rời bỏ theo thời gian

    • Khi làm theo hướng dẫn của Clean Code, tôi đã học được về "phân rã quá mức"
    • Những hàm nhỏ cuối cùng lại chẳng làm gì cả
    • Nếu muốn viết code tốt, hãy đọc code tốt và phát triển gu phù hợp với bản thân
  • Có sự khó chịu với chính cái tên Clean Code

    • Không thể đo mức độ "sạch" của code một cách khách quan
    • Yếu tố vô thức rằng viết "code sạch" đương nhiên là điều tốt đã gây ra vấn đề
    • Nền tảng của "Uncle Bob" đã mục ruỗng ngay từ đầu