3 điểm bởi GN⁺ 2024-12-16 | 1 bình luận | Chia sẻ qua WhatsApp
  • Phát triển phần mềm khó có thể đi thẳng từ tài liệu thiết kế đến một PR gọn gàng; vì các giả định thường bị lung lay trong lúc viết code thực tế, việc khám phá thiết kế bằng mã dùng rồi bỏ có thể nhanh hơn
  • Đề xuất quy trình tạo prototype hoặc proof of concept trong một draft PR không định merge, nhận review sớm để căn chỉnh hướng tiếp cận, rồi để lại như một bản ghi về các ý tưởng thiết kế
  • Tiền đề của cách làm này là độ trưởng thành của tổ chức để sẵn sàng vứt bỏ giải pháp đầu tiên; thái độ có thể triển khai cùng một vấn đề theo 2–3 cách được xem là dấu hiệu của seniority
  • PR trở thành tài liệu có thể tìm thấy chứa ý định triển khai và thảo luận tại một thời điểm cụ thể, trong khi tài liệu thiết kế nếu không được cập nhật thường xuyên dễ trở thành “undead documentation” lệch khỏi thực tế
  • Tài liệu thiết kế vẫn cần thiết trong các trường hợp phải tổng hợp phản hồi từ nhiều bên liên quan, làm tài liệu North Star dài hạn, ghi lại ý tưởng ban đầu còn khó code ngay, hoặc ở các tổ chức có nguy cơ prototype bị triển khai nguyên trạng

Khám phá thiết kế bằng Throwaway PR

  • Quy trình phát triển lý tưởng thường gần với hình ảnh viết tài liệu thiết kế, lần lượt merge các PR nhỏ để phát hành tính năng, và giữ lịch sử Git sạch sẽ
  • Trên thực tế, thường chỉ sau khi bắt đầu code thì các giả định trong tài liệu thiết kế mới bị lung lay, và ta phải đánh giá lại thứ tự phát hành
  • Vì vậy, đôi khi sẽ hiệu quả hơn nếu trước tiên tạo một thử nghiệm code lớn, rồi lập kế hoạch thực tế dựa trên kết quả đó
  • Quy trình được đề xuất

    • Triển khai prototype hoặc proof of concept bằng một draft PR không có ý định merge
    • Nhận góc nhìn của người khác từ sớm về một đợt refactoring lớn hoặc hướng tiếp cận tính năng để đạt được căn chỉnh về hướng đi
    • Ghi lại cách tiếp cận ngay trong draft PR để để lại một bản ghi lịch sử về ý tưởng thiết kế
    • Chuẩn bị sẵn sàng vứt bỏ toàn bộ draft PR càng sớm càng tốt
    • Từ draft PR, dần tách ra các PR có thể triển khai thực tế; trong khoảng một tuần, chia chúng thành các PR sạch để phát hành
    • Khi chia từng PR theo giai đoạn, dần lấp đầy các khoảng trống về kiểm thử và độ vững chắc
  • Điều kiện cần có ở đội ngũ để áp dụng cách này

    • Điều kiện quan trọng nhất là độ trưởng thành để có thể vứt bỏ ý tưởng đầu tiên do chính mình code
    • Sự thoải mái khi có thể code cùng một vấn đề theo 2–3 cách là một dấu hiệu quan trọng của seniority
    • Giá trị được tạo ra không nằm ở số dòng code đã vào production, mà ở tri thức tổ chức thu được
    • Nếu đạt được sự căn chỉnh sớm ở những phần quan trọng, việc prototype về sau sẽ không chỉ kết thúc như một sự lãng phí
    • Cần đủ quen thuộc để nhanh chóng kết nối các phần cốt lõi của codebase; nhân sự senior cần có mức độ thoải mái như vậy
    • Cách làm này có thể được thực hiện không chỉ ở cấp cá nhân mà cả ở cấp đội nhóm

Tài liệu hóa PR và vai trò thực tế của tài liệu thiết kế

  • PR là một trong những dạng tài liệu hữu ích đối với lập trình viên
    • Đây là một trong những nơi đầu tiên nên tìm khi muốn hiểu vì sao một triển khai cụ thể lại được làm như vậy
    • Nó không tuyên bố phản ánh trạng thái hiện tại, mà tồn tại như một sản phẩm lịch sử ghi lại trạng thái tại một thời điểm cụ thể
  • Nếu tài liệu thiết kế không được giữ cập nhật thường xuyên, nó dễ trở thành undead documentation phản ánh một thực tế đã cũ
  • Prototype phù hợp với “cho thấy hơn là nói”, và khi tạo ra thay đổi, code có thể hiệu quả hơn tài liệu
  • Tuy nhiên, trong các tổ chức thiếu kỷ luật, prototype có nguy cơ bị tiếp nhận như “câu trả lời” thay vì “câu hỏi”
    • Ý định ban đầu gần với “chúng ta nên làm cái này, hay nên làm cái khác?”
    • Vấn đề sẽ phát sinh nếu tổ chức tiếp nhận nó thành “chúng ta phải làm cái này”
  • Khi tài liệu thiết kế vẫn phù hợp

    • Hữu ích khi cần tổng hợp và lưu giữ phản hồi từ nhiều bên liên quan, quản lý hoặc các đội bên ngoài
    • Chỉ dùng GitHub có thể khó xử lý kiểu cộng tác đó
    • Nếu ý tưởng quá mang tính khái niệm và dài hạn nên khó code ngay, một mức độ tài liệu North Star nhất định sẽ hữu ích
    • Hữu ích khi diễn đạt bằng văn bản hiệu quả hơn bản nháp code đầu tiên, hoặc khi chưa onboarding đủ vào codebase và muốn để lại bản nháp để nhận phản hồi
    • Nếu công ty thúc ép triển khai thẳng lên production mà không có kỷ luật để vứt bỏ giải pháp đầu tiên, prototype có thể bị đóng cứng nguyên trạng thành “giải pháp”
    • Trong tổ chức nơi nhân sự junior khó phản biện việc triển khai ý tưởng của lập trình viên senior, có thể cần một sản phẩm mềm để đặt câu hỏi an toàn hơn
  • Khi tài liệu thiết kế được dùng vì lý do không tốt

    • Nó có thể trở thành công cụ làm chậm quy trình trong những đội thiếu kỷ luật hoặc thiếu kỹ năng
    • Dù được dùng cho mục đích tài liệu hóa, nó thường nhanh chóng trở nên lỗi thời
    • Khó trả lời trước mọi câu hỏi thiết kế, và vấn đề thực tế thường chỉ lộ ra sau khi viết code
    • Nếu đội có đủ kỷ luật, cách hack để học có thể hiệu quả hơn “thiết kế”

1 bình luận

 
GN⁺ 2024-12-16
Các ý kiến trên Hacker News
  • Cái này được gọi là prototyping, là một phần có giá trị trong quá trình thiết kế, và một số người còn gọi là “pathfinding”
    Tất cả những thứ này đều là đầu vào của thiết kế, nhưng một bản thiết kế có quy mô phù hợp vẫn cần thiết. Nếu không thì chỉ là làm đến đâu hay đến đó. Cần định nghĩa vấn đề muốn giải quyết là gì và lời giải là gì. Đôi khi một tài liệu 1 trang không cần rà soát chính thức là đủ, đôi khi lại cần một tài liệu nhiều trang với vài tuần rà soát và lặp lại phản hồi
    Đừng quên: “Bạn có thể tiết kiệm vài giờ lập kế hoạch bằng vài tuần viết code” ;)

    • Thiết kế nhất thiết phải được hiểu rõ, nhưng điều đó không nhất thiết đồng nghĩa với tài liệu hay sản phẩm bàn giao lâu dài. Nếu cần một bản ghi lâu dài, PR cũng có thể là một phương tiện đủ tốt
      Thực ra điều ngược lại thường đúng hơn nhiều. Người ta lập kế hoạch rồi lại lập kế hoạch, đến mức kế hoạch đó vượt qua ngưỡng vô nghĩa và chủ động làm hại năng suất
    • Chuyện này gần với một lựa chọn hai vế. Cần cả thiết kế lẫn prototype
      Vài tuần viết code có thể tiết kiệm vài giờ lập kế hoạch, nhưng vài tuần lập kế hoạch cũng có thể bị lãng phí. Trên giấy rất dễ viết ra những thứ vô lý hoặc bất khả thi. Ví dụ như “sơn một hạm đội kỳ lân bằng màu hơi buồn”
      Lý tưởng nhất là thiết kế và prototype nên cùng tiến hóa, trong đó mỗi vòng lặp của bên này thúc đẩy vòng lặp tiếp theo của bên kia, phát triển theo dạng xoắn ốc như chuỗi xoắn kép DNA. Lợi thế lớn khi nghiêng về phía làm prototype là sau một vòng, bạn còn lại phần mềm thực sự làm được điều gì đó. Sau một vòng thiết kế thì về thực chất chẳng còn lại được bao nhiêu
    • Không có lý do gì để không làm cả hai. Theo tôi, tốt hơn là trước hết viết phần lý thuyết, dùng prototype để cho thấy nó có chạy được hay không, rồi sau đó viết tài liệu thiết kế thực sự
      Và cả đến giai đoạn triển khai cũng nên tiếp tục ưu tiên khả năng vứt bỏ code. Càng dễ xóa càng tốt
    • Nói chính xác: prototyping và pathfinding hoàn toàn ổn và hầu như là cần thiết
      Nhưng kỹ nghệ phần mềm mà không có tài liệu thiết kế hay bất kỳ loại đặc tả nào, dù ngắn gọn đến đâu, thì không phải kỹ nghệ mà giống dựng một căn chòi trên cây hơn
      Quy mô và tầm quan trọng của dự án càng lớn thì vấn đề và nợ kỹ thuật càng bắt đầu lộ ra nhanh hơn
    • “Bạn cũng có thể tiết kiệm vài giờ viết code bằng vài tuần lập kế hoạch” :)
  • Viết lách thật sự hữu ích trong việc khám phá không gian vấn đề
    Nhiều lần tôi tưởng mình đã hiểu chắc vấn đề, nhưng khi bắt đầu viết ra thì lại nảy sinh những câu hỏi mới và quan trọng. Những điều này thường dễ thấy hơn từ một góc nhìn trừu tượng, hoặc có thể không lộ ra trong vài mốc phát hành đầu tiên
    Tôi nhớ đến một mentor gặp hồi đầu sự nghiệp. Người đó đã thiết kế bổ sung cấu hình active/active cho một cổng thanh toán, rồi mở Lucidchart lên và nói: “Sơ đồ này đại diện cho 6 tháng cuộc đời tôi”
    Không phải lúc nào cũng cần hoặc hữu ích, nhưng khi cần thì vài ngày lập kế hoạch có thể tiết kiệm vài tuần viết code

    • Tôi từng có một sếp có bằng toán, người đó vẽ luồng từ đầu đến cuối lên whiteboard như các nhà toán học trên TV hay trong phim
      Ông ấy có thể dự đoán từ rất sớm những điểm sẽ phát sinh vấn đề, nên dự án lúc nào cũng trơn tru. Khi thấy vấn đề hoặc điểm bất định, ông ấy chỉ mô hình hóa đúng phần đó rồi quay lại whiteboard và tiếp tục
      Nói ví von thì giống như lên kế hoạch cho một chuyến đi ô tô bằng bản đồ. Tài liệu thiết kế ngày nay chỉ đánh dấu đường đi rồi lập tức lái, còn bản đồ whiteboard của vị sếp đó thì “lập kế hoạch quá mức” cả nơi đổ xăng, giờ mở cửa điểm tham quan, giấy tờ qua biên giới, tổng ngân sách, bộ đồ khẩn cấp, Plan A và Plan B
      Cực kỳ nhàm chán, nhưng tốt hơn nhiều so với code dùng rồi bỏ. Giờ thì việc không lập kế hoạch quá mức khiến tôi thấy như lười biếng
      Tất nhiên câu “ai cũng có kế hoạch cho đến khi bị đấm một cú” là đúng, nhưng nó áp dụng cho chiến tranh, chính trị, đàm phán chứ không đúng với coding
    • Tôi đồng ý rằng viết lách hữu ích. Nhưng tôi nghĩ coding cũng tạo ra hiệu quả tương tự. Theo kinh nghiệm của tôi, trong khám phá thì hai việc này phải đi cùng nhau
      Rốt cuộc một PR tốt cũng chứa rất nhiều phần viết và tạo ra hiệu quả tương tự. Tôi cho rằng một PR nháp được tài liệu hóa tốt còn hơn một đề xuất thiết kế thuần túy. Vì nếu chỉ viết, bạn sẽ quên những ràng buộc quan trọng chỉ nảy ra khi ở trong code
    • “Viết lách là cách tự nhiên cho bạn biết suy nghĩ của mình lỏng lẻo đến mức nào”
      -- Dick Guindon
  • Vấn đề lớn nhất tôi gặp với tài liệu thiết kế là không ai đọc chúng. Ngay cả khi nhà tuyển dụng yêu cầu cũng vậy
    Vấn đề lớn nhất tôi gặp với prototyping là mọi người xem nó như “code phát hành” và ép dùng làm code cuối cùng
    Vì vậy cách tiếp cận kết hợp là phù hợp nhất. Dành nhiều thời gian cho lập kế hoạch và tài liệu hóa, nhưng về cơ bản làm cho chính mình, đồng thời viết code prototype đạt chất lượng phát hành để sau này nếu dùng trong sản phẩm cuối cùng cũng ổn

    • Lý do mọi người không muốn đọc tài liệu thiết kế trung bình là vì kỹ sư phần mềm trung bình không có đủ kỹ năng viết để diễn đạt khái niệm một cách rõ ràng và súc tích
      Tài liệu thiết kế trở thành một mớ ghi chú thô mà chẳng ai ngoài tác giả thật sự hiểu được, và mọi người bắt đầu sợ phải đọc những ghi chú như vậy
      Nhưng nếu nói với tác giả tài liệu thiết kế rằng đây giống như bài báo cáo cuối kỳ được chấm điểm ở trường, thì sau vài lần viết lại, bài viết có thể khá hơn đáng kể. Triệu chứng giống với prototyping. Người ta viết tài liệu thiết kế ở chất lượng bản nháp rồi kỳ vọng nó sẽ kỳ diệu biến thành một bài viết tốt phù hợp với nhóm độc giả rộng hơn. Cũng như code prototype cần được refactor vài lần, tài liệu thiết kế cũng cần vài lượt biên tập
  • Để tránh phải gia hạn hợp đồng, chúng tôi phải xây dựng và phát hành một thứ gì đó trước hạn chót, mà hợp đồng đó dự kiến sẽ tốn hàng triệu đô la. Nhưng rồi nhận ra rằng với tài nguyên và cách tiếp cận đã lên kế hoạch thì không thể hoàn thành đúng hạn
    Vì vậy, tôi được phê duyệt cho phép nhanh chóng tạo một phiên bản tạm thời, một phần và không tối ưu, nhờ đó có thể cất cánh đúng giờ
    Nhờ vậy, chúng tôi có thể bay tạm trong lúc những người khác hoàn thiện phiên bản lâu dài và đúng đắn cho phần đó của cánh
    Thực tế, trong lúc bay, chúng tôi còn phát hiện ra những yêu cầu bị thiếu trong thiết kế ban đầu. Điều này làm trì hoãn bản phát hành production của phiên bản đúng đắn, nhưng tôi có thể nhanh chóng thêm vào phiên bản hack của mình để tiếp tục duy trì chuyến bay
    Phiên bản hack của tôi cũng đóng vai trò như công cụ hỗ trợ production. Khi phiên bản lâu dài có lỗi và phải dừng lại, nó cũng trở thành tuyến thay thế. Dù là một bản hack cục bộ và chưa hoàn chỉnh, nó vẫn có ưu điểm
    Cũng có người phàn nàn vì ngôn ngữ tôi dùng ít phổ biến hơn. Nhưng cần nhớ rằng với tài nguyên và cách tiếp cận hiện có thì ngay từ đầu đã không thể cất cánh
    Để kịp hạn chót, lẽ ra cần nhiều lập trình viên hơn hoặc lập trình viên nhanh hơn bằng ngôn ngữ được ưa chuộng. Nếu trong số nhân viên hiện tại có ai đó, kể cả tôi, có đủ thời gian và năng lực để làm bằng ngôn ngữ được ưa chuộng với năng suất ngang bản hack bằng ngôn ngữ ngoài luồng của tôi, thì người đó hẳn đã được phân công làm giải pháp lâu dài kịp thời hạn. Không có lựa chọn như vậy
    Dù sao thì nếu đã có một công cụ hỗ trợ production hiện hữu, đó cũng là nơi để tính năng nguyên mẫu có thể ở lại một thời gian

    • Đó là ngôn ngữ nào?
  • Lại là một bài nêu quan điểm nữa, không có dữ liệu, thậm chí không có ví dụ cụ thể
    Tôi biết mọi kỹ sư phần mềm đều có ý kiến mạnh mẽ, nhưng đây là một lập luận yếu. Nếu bạn nghĩ công việc của mình là viết thật nhiều code để xem điều gì đúng, bạn sẽ sớm bị GPT thay thế. Vì nó có thể làm nhanh hơn và rẻ hơn. Phần khó luôn là đạt được đồng thuận về việc cần xây dựng cái gì, và bạn không thể thoát khỏi vấn đề đó bằng cách viết code

    • Rất đồng ý. Tôi không chắc gọi là “tài liệu thiết kế” có đúng không, tôi gọi đó là phân tích kỹ thuật, nhưng việc viết tài liệu kết nối nhu cầu kinh doanh và sản phẩm với chi tiết triển khai rất hữu ích để mọi người có cùng hiểu biết về yêu cầu và đầu ra
      Nếu yêu cầu đã rõ ràng và mọi người cũng rõ tôi sẽ bàn giao gì thì không cần. Có thể đi thẳng vào làm prototype. Nhưng trong các dự án nghiêm túc, trường hợp này hiếm. Luôn có những ẩn số chưa biết cần khai thác từ các bên liên quan, và phân tích kỹ thuật là một cách tốt để làm điều đó
    • Đó chính là ý của tôi. Tôi cho rằng “đừng nói, hãy cho xem” tạo ra sự đồng thuận tốt hơn
      Hình chữ nhật và đường nét đứt có giới hạn của chúng. Khi tách khỏi code thật, ta dễ quên các ràng buộc thật. Những thứ thực sự làm chậm tiến độ không xuất hiện trong Google Docs. Theo kinh nghiệm của tôi, chỉ vào một draft PR và nói “đây là thứ tôi đang nghĩ tới” sẽ đi được xa hơn
      Và đúng, đây 100% là quan điểm. Đây là blog cá nhân chứ không phải bài báo bình duyệt :) Sai cũng không sao
    • Code dùng để bỏ đi tốt hơn tài liệu thiết kế vì nó là ví dụ cụ thể
      Nếu không có một thực thể như code để neo cuộc thảo luận lại, các cuộc thảo luận về thiết kế trừu tượng rốt cuộc thường trôi thành những tranh luận không hồi kết kiểu “sợi dây trong tưởng tượng của tôi dài hơn sợi dây trong tưởng tượng của bạn”
    • Người có niềm tin như vậy nhiều khả năng sẽ tiến nhanh hơn rất nhiều với LLM, hơn là khả năng LLM thay thế toàn bộ công việc này
    • “Dữ liệu” trong những bài như thế này đôi khi có thể là kinh nghiệm cá nhân tích lũy qua hàng chục năm
  • Theo kinh nghiệm của tôi, phản hồi về code và phản hồi về thiết kế là hai loại cực kỳ khác nhau
    Tài liệu thiết kế khơi gợi các câu hỏi “tại sao”, khiến mọi người suy nghĩ về không gian vấn đề. Ví dụ có thể có bình luận như “Công ty mình chưa có ai thành thạo Rust, vậy tại sao lại đề xuất web server bằng Rust?”
    Những câu hỏi tinh tế như vậy sẽ khó nêu ra hơn nhiều sau khi prototype bắt đầu chạy được. Rất dễ thành “Tại sao kinh nghiệm của đội lại quan trọng? Nó chạy tốt thế này cơ mà! Nếu không bị cản, chúng ta chỉ cần đánh bóng prototype là có thể đưa vào production trong vòng một tuần!”

    • Điều đó không nhất thiết là xấu. Nhiều câu hỏi “tại sao” thực ra là tranh luận chuyện nhà để xe đạp rất kém hiệu quả
      Đặc biệt là khi chỉ review thiết kế chứ không phải code đang chạy
  • Chúng ta tưởng tượng rằng công việc phần mềm đi theo một luồng gọn gàng, ngăn nắp
    Viết tài liệu thiết kế, tạo các thay đổi nhỏ và tăng dần để phát hành tính năng trong PR, lịch sử Git sạch sẽ và có trật tự. Trông như tiến đều về phía trước
    Ai tưởng tượng như vậy? Các giáo sư dạy lớp kỹ nghệ phần mềm à?
    Điều này làm tôi nhớ đến những người nghĩ rằng văn xuôi, tiểu luận, truyện, tiểu thuyết, v.v. được viết bằng cách lập dàn ý rồi “điền” văn xuôi vào đó. Như thể trong quá trình ấy không hề có phát hiện nào buộc phải viết lại hay tái cấu trúc tài liệu. Không ai viết như vậy cả. Bản nháp luôn tệ, và hầu như mọi bài viết hay đều là kết quả của việc sửa chữa lớn
    Viết code gần với viết lách hơn rất nhiều so với xây nhà hay xây cầu

    • Tôi luôn thấy giá trị lớn trong việc debug code mới viết
      Quá trình lần theo logic mới từng dòng, xem biến và bộ nhớ thật sự giúp cải thiện code. Tôi phát hiện ra những thứ như “à, biến cục bộ này không cần”, “chỗ này nên thêm biến tạm để dễ debug hơn”, “nếu collection đang lặp là rỗng thì đoạn code này kỳ lạ”
      Dù bạn bao nhiêu tuổi, viết bao nhiêu code đi nữa, khi debug code mới viết bạn luôn phát hiện điều mới. Có thể so với việc một nhà văn viết bản nháp rồi đọc lại, hoặc đọc to cho chính mình hay người khác nghe
  • Tôi rất thích quá trình ghi lại các quyết định thiết kế dưới dạng luồng bình luận đang diễn ra, thay vì cố chính thức hóa chúng thành một tài liệu duy nhất
    Tôi dùng GitHub issue theo cách này, nhưng về chức năng thì cũng giống như dùng PR. PR thực chất là một GitHub issue có kèm nhánh code
    Tôi có viết thêm về cách làm của mình ở đây: https://simonwillison.net/2022/Jan/12/how-i-build-a-feature/...

    • Vậy bạn truyền đạt đồng thuận mới nhất cho từng issue như thế nào? Ví dụ với người mới tham gia không muốn rà qua nhiều tháng trao đổi, hoặc thành viên trong đội đã theo dõi thread liên tục nhưng không dễ tìm được nhóm đã thống nhất ở đâu về một vấn đề cụ thể thì sao?
      Nói cách khác, bạn tóm tắt thread đó thành tài liệu cuối cùng như thế nào?
  • Tôi không nghĩ hai thứ này loại trừ lẫn nhau
    Tài liệu thiết kế là một khái niệm rộng hơn, và mục tiêu là giao tiếp
    Đôi khi cần truyền đạt bằng cách không phải là code. Cần sơ đồ, hình ảnh, bài viết, v.v.

    • Đồng ý
      Với người không phải tác giả hoặc không quá quen thuộc với code, rất khó để hiểu ngay các thay đổi. Để người đọc nhanh chóng xây dựng được mô hình tư duy đúng nhằm hiểu thay đổi trong ngữ cảnh, cần có phần giải thích và tài liệu ở mức cao
      Nếu bạn có thể nhìn vào một diff 1000 dòng và nói chính xác nó làm gì, và quan trọng hơn là nó ảnh hưởng thế nào đến thượng nguồn và hạ nguồn, thì hoặc là bạn đang nói dối, hoặc là bạn đang làm việc trong một môi trường khép kín và có thể kiểm chứng hoàn hảo đến mức tôi thật sự phải ghen tị
  • Tài liệu thiết kế giúp giảm số prototype xuống còn 2–3 trong số các lựa chọn khả thi. Đặc biệt hữu ích khi khám phá để thêm một thứ hoàn toàn mới
    Tôi thấy cho xem thì tốt hơn nói, nhưng người mới tham gia sẽ dễ hiểu qua tài liệu thiết kế hơn là qua code