80 điểm bởi GN⁺ 2025-08-26 | 5 bình luận | Chia sẻ qua WhatsApp
  • Tôi đang cố gắng cải thiện năng lực thiết kế phần mềm của mình và được khuyên rằng nên nghiên cứu những codebase hiện có được thiết kế tốt
  • Tôi tò mò không biết trong số các codebase có thể truy cập công khai, đâu là những cái được xem là tiêu chuẩn vàng về thiết kế phần mềm

1. Các codebase được đề xuất

  • Dự án lớn/tiêu biểu
    • Git, Postgres, CPython
    • "mô hình lieutenants" của Linux Kernel
    • UNIX v6, BSDs
  • Framework/thư viện
  • Hệ thống/máy chủ
  • Game/trường hợp đặc biệt
  • Tài liệu học tập/giảng dạy
  • Khác
    • Monocypher (thư viện mật mã)
    • phần triển khai ngôn ngữ Tcl

2. Đọc code vs học tài liệu/thiết kế

  • Giới hạn của chỉ đọc code
    • Codebase cho thấy phần triển khai, nhưng che giấu ý đồ thiết kế và các đánh đổi
  • Tầm quan trọng của tài liệu thiết kế
    • Các bản ghi quyết định như ADR (Architectural Decision Records), Rust RFCs, Python PEPs hữu ích hơn nhiều cho việc học thiết kế
    • Việc tự viết tài liệu thiết kế cũng có thể là một hình thức rèn luyện
  • Sách/tài liệu được khuyên đọc

3. Quan điểm học tập lấy thực hành làm trung tâm

  • Kinh nghiệm và thử-sai
    • Thiết kế là thứ được học bằng cách liên tục gặp vấn đề và học cách tránh chúng
    • Chỉ đọc code thì không đủ; bạn học được nhiều hơn khi tự viết và giải quyết các thất bại
  • Học dựa trên hứng thú
    • Bạn sẽ học sâu hơn nếu xây dựng dự án mà bản thân thực sự hứng thú
  • Chi phí thất bại thấp
    • So với kỹ thuật vật lý, phần mềm có chi phí thất bại thấp hơn nên việc học qua thử nghiệm và thất bại rất hiệu quả

4. Tranh luận về bản chất của kỹ nghệ phần mềm

  • Lập luận về tính chưa trưởng thành của một ngành kỹ thuật
    • Nếu năm kỹ sư đưa ra năm cách giải khác nhau, đó là bằng chứng cho thấy lĩnh vực này còn chưa trưởng thành với tư cách một ngành kỹ thuật
  • Quan điểm cho rằng phần mềm thân thiện với thử nghiệm
    • Phần mềm có ít ràng buộc hơn nên tồn tại nhiều cách giải; không có một đáp án cố định như trong kỹ thuật vật lý
  • Ranh giới giữa nghệ thuật và kỹ thuật
    • Thiết kế cũng là một hành vi mang tính nghệ thuật vì có yếu tố thẩm mỹ, nhưng ở khía cạnh đáp ứng yêu cầu chức năng thì nó vẫn là kỹ thuật
    • Phần mềm nằm giữa sự linh hoạt mang tính nghệ thuật và tính chặt chẽ của kỹ thuật

5. Các phương pháp học thay thế

  • Phân tích code tệ
    • Không chỉ code được thiết kế tốt, mà việc thử sửa một codebase kém chất lượng cũng mang lại hiệu quả học tập rất lớn
  • Học từ codebase của chính mình
    • Codebase nội bộ của nhóm thường được xem là tài liệu giúp học được nhiều nhất
    • Tuy vậy, nếu code của nhóm quá kém thì vẫn cần kết hợp với các ví dụ bên ngoài
  • Học theo đúng domain
    • Đọc những codebase tương tự với loại vấn đề bạn muốn giải quyết là cách hiệu quả nhất

Insight chính

  • Codebase được thiết kế tốt có ích, nhưng việc học cần đi kèm với hiểu được ý đồ thiết kế và trải qua thử-sai
  • So với việc chỉ đọc code, tài liệu thiết kế và bản ghi quyết định mới là nguồn học tập cốt lõi
  • Các dự án chất lượng cao tiêu biểu như Git, Postgres, CPython, thư viện std của Rust, v.v. có giá trị học tập rất cao
  • Về lâu dài, học từ code tốt thôi chưa đủ; code kém chất lượng và chính code của bạn còn mang lại giá trị thực tế hơn

Tóm tắt các bình luận nổi bật

Gợi ý các codebase tiêu biểu (CraigJPerry)

  • Postfix mail server
    • Kiến trúc lấy bảo mật làm trung tâm, cho thấy một cấu trúc tương tự microservices từ trước cả khi khái niệm này trở nên phổ biến
    • Nếu microservices hiện đại tập trung vào sự phân tán ở quy mô tổ chức lớn, thì Postfix được thiết kế vì bảo mật và sự đơn giản
  • Spring Framework
    • Phản ánh một văn hóa phát triển rất chú trọng nhu cầu của lập trình viên Java trong môi trường doanh nghiệp
    • Có thể học được cách tiếp cận thiết kế lấy người dùng làm trung tâm
  • Git
    • Khi hiểu được cơ sở dữ liệu đối tượng (blob, tree, commit) và khái niệm reference, phần còn lại chỉ là sự mở rộng dần dần
    • Sự mở rộng nhất quán từ các khái niệm cốt lõi được nêu như một ví dụ điển hình của thiết kế tốt
  • Varnish
    • Vừa là reverse proxy hiệu năng cao, vừa là một codebase được tổ chức rất tốt đến mức có thể dùng như tài liệu học tập
  • Linux Kernel Lieutenants Model
    • Dù không phải là codebase, đây vẫn là một mô hình quản lý phần mềm quy mô lớn đáng để tham khảo
  • Đây không chỉ đơn thuần là những ví dụ về "code được thiết kế tốt", mà là những trường hợp mà các quyết định thiết kế để lại ấn tượng rất mạnh

Nhấn mạnh việc học từ codebase thực tế trong công việc (crystal_revenge)

  • Giá trị học tập lớn nhất đến từ codebase của chính nhóm bạn
  • Trong quá trình kết nối đầy lộn xộn giữa yêu cầu thực tế và phần triển khai, bạn sẽ cùng lúc trải nghiệm cả lựa chọn tốt lẫn lựa chọn tệ
  • Trong các ràng buộc thực tế, yếu tố lớn nhất là áp lực thời gian; điều cốt lõi là học cách cân bằng giữa thiết kế lý tưởng và hiện thực
  • Phần mềm tốt là phần mềm giải quyết được nhu cầu của người dùng; qua trải nghiệm lặp lại, bạn sẽ học được cách thiết kế để tăng khả năng thành công

Liên kết đến các thảo luận và tài liệu trước đây (sprobertson)

Code vs tài liệu thiết kế (alphazard)

  • Codebase chỉ là kết quả của phần triển khai, không phải bản thân thiết kế
  • Để học thiết kế, việc viết tài liệu thiết kế hiệu quả hơn
    • Tài liệu phải đủ rõ ràng để người khác có thể triển khai nguyên vẹn
    • Nếu liệt kê các phương án thay thế và ghi lại lý do loại bỏ chúng, đó sẽ là bằng chứng cho quá trình cân nhắc thiết kế
  • Một nhà thiết kế giỏi là người xem xét một không gian thiết kế rộng hơn và chọn ra điểm phù hợp

Nhấn mạnh việc hiểu toàn bộ hệ thống (RossBencina)

  • Quá trình hiểu được toàn bộ codebase là cực kỳ có giá trị
    • Không chỉ là đọc code được thiết kế tốt, mà còn là luyện khả năng nhìn ra bức tranh lớn của cả hệ thống
    • Việc trực quan hóa các mối quan hệ bằng sơ đồ như UML có thể rất hữu ích
  • Cách tiếp cận khi học:
    • Đọc code của những phần mềm tương tự với thứ bạn đang phát triển là rất hiệu quả
    • Nên bắt đầu từ code thuộc domain bạn đã quen, như web framework, web server, thư viện chuẩn Python, VSCode, v.v.
    • Ban đầu nên tiếp cận từ chương trình nhỏ và domain quen thuộc

Tiêu chí của thiết kế tốt (mamcx)

  • Thiết kế tốt là mục tiêu và ý tưởng, còn codebase cho thấy mức độ hiện thực hóa của chúng
  • Thiết kế tốt không chỉ là các nhãn như "nhanh" hay "an toàn", mà cần bao gồm những cân nhắc cụ thể và bản ghi về các đánh đổi
  • Ví dụ: có thể quan sát đặc điểm này trong Erlang, Pascal thời kỳ đầu, và thiết kế của nhiều RDBMS
  • Thư viện std của Rust là tài liệu học tốt vì nhấn mạnh bảo mật và tính nhất quán, và cả code lẫn tài liệu đều phản ánh điều đó rất trung thực

Những quyết định thiết kế vô hình (ben30)

  • Khi nhìn vào một codebase được thiết kế tốt, phần quan trọng nhất là những gì không nhìn thấy
    • Loại bỏ độ phức tạp, tránh các lớp trừu tượng không cần thiết, từ chối một số pattern nhất định — những quyết định về sự vắng mặt này mới là cốt lõi
  • Để bù lại, có thể dùng ADR (Architectural Decision Records)
    • Ghi lại các phương án thay thế, lý do loại bỏ và căn cứ lựa chọn để lưu giữ ngữ cảnh
    • Điều này rất hữu ích cho cả người bảo trì sau này lẫn các công cụ AI
  • Khi học, ngoài code, sẽ hiệu quả hơn nếu xem các dự án có kèm tài liệu quyết định thiết kế như ADR, RFC, PEP

5 bình luận

 
shaffr0n 2025-08-27

Tôi đã vài lần đọc mã sau khi xem một cuộc phỏng vấn trong đó Evan You (người tạo ra Vue.js và Vite) nói rằng TJ Holowaychuk, tác giả của express.js, đã thiết kế nó gọn gàng và đẹp mắt. Dù chưa thể hiểu được bức tranh tổng thể, tôi vẫn có cảm giác rằng nhìn chung mã không phức tạp, rất sạch sẽ và chỉ triển khai đúng phần logic cần thiết.

Chú thích cũng được viết rất tốt, nên dù là mã từ 10 năm trước thì vẫn rất dễ để suy luận kiểu và hiểu định dạng DTO.

 
wedding 2025-08-27

Lấy một bài viết năm 2009 trên blog đầy rẫy bình luận spam làm tài liệu tham khảo sao..

 
GN⁺ 2025-08-26
Ý kiến Hacker News
  • Không biết có phải chỉ mình tôi không, nhưng tôi thấy cách hiệu quả nhất là thực sự đụng phải vấn đề nhiều lần rồi tự rút ra cách tránh nó. Làm vậy dần dần sẽ giúp bạn có khả năng mô phỏng trong đầu những vấn đề nào có thể xảy ra về sau, và cuối cùng design cũng là việc dự đoán trước nhiều vấn đề tương lai để né tránh, cân nhắc cẩn thận các trade-off như nên tránh vấn đề nào với mức công sức bao nhiêu, hay liệu một design có thể giải quyết nhiều vấn đề cùng lúc hay không

    • Tôi cũng vậy. Những cách như "giải bài tập luyện tập" hay "nghiên cứu codebase" không hợp với tôi. Khi tự xây thứ gì đó mà mình thực sự hứng thú, tôi học một cách tự nhiên bằng cách theo đuổi sự chính xác và cẩn thận trong từng ví dụ. Nhưng đôi khi tôi vẫn thấy khả năng của mình còn thiếu. Tôi nghĩ nếu có thể đọc code trôi chảy như đọc sách và hình dung được cách nó vận hành trong đầu, thì việc học bản thân nó cũng sẽ thú vị hơn

    • Khi nghe chuyện học bằng cách đụng phải vấn đề nhiều lần, tôi cảm thấy lĩnh vực software engineering vẫn chưa đủ trưởng thành. Hãy thử tưởng tượng nếu người ta xây cầu hay xây nhà theo kiểu đó, hoặc bác sĩ phẫu thuật được đào tạo như vậy, thì quá nguy hiểm. Có lẽ theo thời gian, các tiêu chuẩn hay quy chuẩn sẽ dần được thiết lập, nhưng hiện tại đúng là vẫn rất linh động. Gom năm software engineer lại, đưa ra một vấn đề, không chỉ sẽ có năm lời giải hoàn toàn khác nhau, mà còn có thể xảy ra tranh cãi gay gắt về việc cách nào đúng. Tôi không nghĩ thái độ kiểu "thấy giải pháp tốt thì sẽ tự nhận ra" là đủ để gọi là engineering đúng nghĩa

    • Tôi cũng đã học đều đặn theo cách này cho đến giờ và chắc sau này vẫn sẽ tiếp tục như vậy. Việc học từ production code thật sự có lẽ sẽ là một thử thách mới với tôi. Không biết nó giá trị đến đâu, nhưng dù sao cũng có vẻ thú vị

    • Tôi nghĩ nó hơi giống việc học lái xe bằng cách lần đầu ngồi lên xe rồi gây tai nạn, sau đó rút kinh nghiệm để lần sau không đâm nữa. Thực tế thì cần cả hai cách. Khi lái xe trên đường bình thường, ta hiếm khi vượt quá giới hạn nên khó áp dụng trực tiếp, nhưng với đua xe chẳng hạn, việc biết chính xác giới hạn có thể đẩy tới đâu là điều bắt buộc. Dĩ nhiên tôi không nghĩ cần xem nghề của chúng ta như một môn thi đấu. Nhưng nếu không đọc sách và không học hành, thì theo nghĩa đen sẽ mất rất nhiều thời gian, chưa kể tai nạn và hỏng hóc sẽ xảy ra liên miên. Vì vậy tôi luôn muốn nói là cứ đọc, rồi đọc nữa. Có thể lúc này bạn chưa thấy cần, nhưng về sau khi tích lũy kinh nghiệm, kiến thức đó chắc chắn sẽ được dùng ở đâu đó, và bạn sẽ không bị bối rối như lần đầu học chuyện rà phanh bằng động cơ và chuyển xuống số thấp khi đổ đèo

    • Đây chính là cốt lõi

  • Khi nghe câu hỏi này, điều đầu tiên tôi nghĩ đến là "codebase của đội mình". Không có cách nào học software design hiệu quả hơn việc hiểu sâu vì sao với một vấn đề thực tế, có giải pháp tốt và giải pháp dở nào đã được chọn. Phần mềm về bản chất chính là một lớp trung gian phức tạp nối giữa yêu cầu của người dùng và cách máy móc vận hành. Nếu không có sự hỗn loạn đó thì nó đã được tự động hóa từ lâu, và bản thân phần mềm cũng chẳng còn cần thiết. Trong software, nếu chỉ mải theo đuổi một hình mẫu lý tưởng thì ngược lại rất dễ đưa ra quyết định tệ. Trên thực tế, bạn giảm bớt thử-sai bằng cách hiểu được "vì sao dưới những áp lực này người ta lại chọn phương án đó". Đồng thời bạn cũng phải học các phương pháp thực chiến để làm việc nhanh và hiệu quả. Thách thức lớn nhất ngoài đời là giới hạn thời gian. Điều này gần như không được bàn tới trong lý thuyết software design, nhưng ngoài đời thì lúc nào bạn cũng làm việc dưới áp lực phải ship code thật nhanh. Rất thường xuyên không có đủ thời gian để làm theo cách mình muốn hay theo cách tốt nhất. Phần mềm tốt là phần mềm giải quyết được nhu cầu thực tế của người dùng. Có những giải pháp design sẽ tạo ra nhiều lần triển khai thành công hơn trong tương lai, và cách tốt nhất để tìm ra chúng là nhìn thật sâu vào chính đoạn code mà mình đang viết

    • Nếu người hỏi đang đi tìm lời khuyên bên ngoài vì cảm thấy phần mềm của team mình quá tệ thì sao? Hoặc nếu chỉ đơn giản là một sinh viên đại học hỏi thì sao?

    • Tôi chưa từng nghĩ thời gian cần để triển khai cũng có thể là một thước đo đánh giá chất lượng design, nhưng thấy điều đó rất hợp lý. Bản thân tôi cũng học được rất nhiều từ codebase của team mình. Phần lớn là học những điều tốt từ những chỗ design xuất sắc, còn ở những phần chưa tốt thì tôi lại tiếp tục học bằng cách tự Google

  • Dù là tài liệu đã vài năm tuổi, nhưng có loạt "The Architecture of Open Source Applications" với bài viết đóng góp từ nhiều leader của các dự án open source, và có thể đọc miễn phí online
    https://aosabook.org/en/index.html

  • Câu hỏi này đã xuất hiện nhiều lần rồi, nên tôi gom vài link để tham khảo

  • Source code của Yanderedev

  • Tôi không đủ tư cách để nói đâu là đáp án đúng, nhưng khoảng 15 năm trước tôi đã đọc cuốn "Code Reading" và thấy cực kỳ thú vị. Đây là một cuốn sách rất khớp với chủ đề này
    https://www.spinellis.gr/codereading/
    Xem mục lục: https://www.spinellis.gr/codereading/toc.html
    Hình như cũng có một cuốn sách khác tên gần giống vậy, nhưng tôi không nhớ chính xác

  • Trên thực tế, codebase thường chứa implementation nhiều hơn là design. Ví dụ, dù bạn có viết lại hoàn toàn bằng ngôn ngữ khác thì design vẫn có thể được giữ nguyên. Tôi khuyên nên luyện viết tài liệu design. Đừng quá bận tâm tài liệu phải trông như thế nào, cũng không cần bị trói bởi template. Điều quan trọng nhất là người khác cầm tài liệu đó lên và có thể implement đúng theo nó. Và bản thân tài liệu có thể đóng vai trò như một "dấu vết của quá trình suy nghĩ". Chỉ cần ghi rõ bạn đã chọn cách nào, có những phương án thay thế nào và vì sao bạn không chọn chúng. Việc thừa nhận và so sánh các lựa chọn từ trước sẽ giúp người đọc tin rằng bạn đã cân nhắc đầy đủ. Điều mà một system designer "giỏi" làm là nhìn bao quát một không gian design rộng hơn người khác và nhất quán tìm ra những điểm tốt. Chỉ cần chọn một vấn đề, thử nghiệm nhiều không gian design khác nhau, rồi giải thích vì sao cái nào tốt hơn và ghi lại tất cả

  • Trước hết phải bắt đầu từ câu hỏi: "Mình đang muốn giải quyết vấn đề gì?" Hãy tìm codebase đã giải quyết vấn đề đó và tập trung phân tích cách nó được implement trong thực tế. Cần nhớ rằng design tốt gắn rất chặt với bối cảnh domain cụ thể. Tôi nghĩ Internal Model Principle của Wonham cũng áp dụng cho code. Ví dụ, tôi từng muốn giải quyết bài toán unit test cho embedded target nên đã phân tích các dự án open source liên quan, rồi xem xét một cách phản biện vì sao từng đoạn code lại được viết như vậy. Trong lúc tự làm giải pháp của riêng mình, tôi lại tiếp tục tham khảo những đoạn code trước đó, và càng hiểu sâu domain của mình thì tôi càng học được nhiều hơn

  • Theo kinh nghiệm của tôi (30 năm làm phần mềm, 25 năm làm kiến trúc, thạc sĩ hệ thống kiến trúc ở MIT), không hề tồn tại một design "tốt" theo nghĩa trừu tượng. Chắc chắn có những thiết kế tệ, tức là những design dẫn tới kết quả xấu, nhưng tiêu chuẩn của "tốt" thì thay đổi theo bối cảnh. Nó phụ thuộc rất nhiều vào việc bạn đang xây cái gì, các yêu cầu như safety/security, và hơn hết là đội sẽ implement nó cùng cấu trúc của đội đó. Một team toàn junior có thể hiểu sai rồi phá hỏng cả một thiết kế tinh vi. Giống như Conway's Law, cấu trúc của đội phát triển sẽ được phản chiếu nguyên vẹn vào phần mềm

    • Điều tôi nhận ra rất rõ khi học software design là không có lời giải vạn năng. Giá mà có thì tốt biết mấy, vì giữa đủ loại architecture và paradigm khác nhau, việc chọn ra giải pháp tối ưu đôi khi rất bức bối. Dù vậy, chỉ cần phản ánh đúng yêu cầu thì số lựa chọn cũng giảm đi khá nhiều. Hiện tại tôi đang làm với embedded system mà safety đặc biệt quan trọng, và chính môi trường này khiến tôi thường xuyên phải đưa ra những quyết định mà ở bối cảnh khác sẽ chẳng bao giờ dùng tới

    • Cuối cùng thì mấu chốt là tránh những phương án thỏa hiệp thật sự ngớ ngẩn, và khi nhìn ở góc độ rộng hơn cũng tránh được các lựa chọn tệ nhất. Cảm giác thường trực ngoài thực tế là công việc này không phải cuộc chiến để tìm ra kiến trúc tốt nhất, mà là một cuộc chiến liên tục để "tránh các quyết định tệ hại từ gốc"

  • Trước đây tôi từng làm một danh sách gợi ý rất đơn giản, và đến giờ nó vẫn còn đúng
    https://medium.com/@012parth/what-source-code-is-worth-studying-8755f88f8de5

 
roxie 2025-08-27

Có một cái bẫy ở giữa..

 
ffdd270 2025-08-27

Là source code của Yanderedev à... hahaha