XP, TDD và vibe coding: Bản dịch một phần cuộc phỏng vấn Kent Beck trên Programmatic Engineer
(stdy.blog)- Tóm tắt vài phần khiến tôi ấn tượng trong cuộc phỏng vấn Programnatic Engineer với Kent Beck, cha đẻ của XP và TDD
- Nếu bạn yêu thích Kent Beck thì nên xem bản đầy đủ
Q. Cốt lõi của XP là gì?
Là thực hiện 4 hoạt động sau.
- Xác định cần phải làm gì
- Xác định cấu trúc giúp chúng ta có thể làm được điều ở bước 1
- Dùng bước 2 để hiện thực hóa bước 1
- Kiểm tra xem bước 3 có hoạt động đúng như dự kiến hay không
Chỉ có vậy thôi. Và chia nhỏ thời gian thật vụn, để trong mỗi đơn vị thời gian đều làm một chút của cả 4 hoạt động đó.
Q. Vậy pair programming không phải là thứ bắt buộc trong XP sao?
Khi lần đầu vận hành một team XP, chúng tôi phát hành 3 tuần một lần, và dĩ nhiên có bug.
Khi phân tích pattern của các bug được phát hiện sau khi phát hành, tôi thấy toàn bộ chúng đều phát sinh từ phần code được phát triển một mình. Nói ngược lại, ở phần code được phát triển theo cặp thì không có defect nào được báo cáo trong môi trường production
Q. Vậy không phải bắt buộc, mà là mức độ rất nên khuyến nghị?
Cũng không hẳn. Ý là hãy thử nghiệm. Bạn cứ phát triển theo cách vốn dĩ mình làm cũng được. Chỉ cần làm trong trạng thái tỉnh táo.
Dù là thiết kế liên tục, kiểm chứng liên tục, triển khai liên tục, hay tương tác liên tục với khách hàng, nếu bạn muốn nhận lợi ích từ điều đó mà vẫn cứ làm mãi theo cách cũ thì sẽ không được. Khi đó phải thay đổi cách làm.
Nếu ai đó đến gặp tôi và nói: "Kent, tôi không làm TDD." thì tôi sẽ đáp: "Thì sao?"
Nếu bạn hài lòng với mật độ lỗi trong code hiện tại và mức độ feedback đối với các quyết định thiết kế, thì không sao cả. Nhưng nếu không hài lòng thì hãy thử pair programming hoặc TDD.
Q. Nhân tiện, vì sao ông tạo ra TDD?
Tôi là người hay lo lắng và bất an, và với tôi, lập trình là nguồn gốc của sự bất an không ngừng. Mình quên cái gì rồi? Mình làm hỏng cái gì rồi?
Nhưng khi phát triển với TDD thì sự bất an đó biến mất. Không nghĩ ra thêm test case nào có khả năng thất bại nữa à? Vậy thì tôi có thể tin rằng chương trình của mình đang hoạt động. Chỉ cần nảy sinh chút bất an thôi sao? Vậy thì cứ viết test case tiếp theo là được.
Dĩ nhiên TDD còn có nhiều lợi ích kỹ thuật như giảm mật độ lỗi, nhận feedback nhanh hơn về các quyết định thiết kế, và tiến hóa thiết kế triển khai. Nhưng với tôi, điều quan trọng nhất là được giải phóng khỏi sự bất an về lập trình, và trải nghiệm cảm xúc mà việc lập trình mang lại đã thay đổi hoàn toàn. Đó là lý do tôi tạo ra TDD.
Q. Ông nghĩ gì về lời phê bình của John Ousterhout rằng làm TDD thì không còn chỗ cho thiết kế tốt xen vào?
(Của người dịch: John Ousterhout là tác giả của cuốn sách nổi tiếng Philisophy of Software Design, và vài tháng trước ông cũng xuất hiện trên podcast Programmatic Engineer để thể hiện góc nhìn phê phán với TDD)
Ông ấy đã hiểu nhầm ở một khía cạnh. Đó đơn giản là kết quả của việc ra quyết định. Nếu coi TDD chỉ là vòng lặp Red-Green thì đương nhiên trong đó không có chỗ cho thiết kế chen vào.
Là một người thực hành TDD, tôi luôn làm việc qua lại giữa nhiều mức độ trừu tượng. Ví dụ:
- Hiện tại đang ở trạng thái Red. Muốn cho test case tiếp theo thành công (Green) thì phải triển khai thế nào?
- Có gì đó khó nhỉ. Vì sao lại khó?
- Muốn việc triển khai để đạt Green trở nên dễ hơn thì phải thay đổi thiết kế thế nào?
- Nên đưa ý tưởng đó vào lúc nào? Bây giờ hay sau này?
- Nếu đưa vào ngay bây giờ thì ở mức nào? Chỉ làm một chút trong phạm vi có thể làm ngay, hay làm theo một chunk lớn hơn?
Tức là trước khi viết test, tôi luôn có một khoảnh khắc dành cho thiết kế.
Trước khi triển khai, tôi đưa ra quyết định về interface, tạo ra test Red, và vì tôi ghét trạng thái Red nên sẽ đưa nó về Green nhanh nhất có thể. Khi đã Green thì sự bất an tạm thời biến mất, và tôi có khoảng trống để suy nghĩ. "Ừm, tuy đã pass nhưng cách này sẽ không ổn với các trường hợp khác. Mình cần khái quát hóa phần triển khai hơn nữa."
Red à? Đưa nó về Green. Green à? Thở ra một chút rồi suy nghĩ. Đó là chu kỳ TDD của tôi.
Q. Đôi khi tôi thấy phần triển khai quá hiển nhiên, nên tôi làm phần triển khai trước rồi mới chạy kiểm thử Red-Green. Ông nghĩ sao về cách này?
Có lẽ vì bạn đang giả định rằng "cách triển khai này là đúng", và giả định đó càng đúng thì lợi ích của cách viết test trước đương nhiên càng giảm đi.
Nhưng tôi thì luôn nghĩ thế này: "Tôi sẽ tiếp tục học hỏi và tích lũy kinh nghiệm, và hiện tại chính là thời điểm tôi ngu ngơ nhất."
Nói cách khác, tôi giả định rằng mình sẽ tiếp tục học, và hoàn cảnh sẽ thay đổi. Tôi càng cần học thêm nhiều và mọi thứ càng thay đổi nhiều, tôi càng muốn trì hoãn quyết định tối đa. Đây là một nguyên tắc phổ quát. Hẹn hò hay nấu ăn cũng vậy thôi.
Càng dự đoán được nhiều thì bạn càng có thể nhảy những bước lớn hơn. Nhưng khoảnh khắc tôi yêu nhất khi lập trình là lúc tôi tưởng mình đã biết hết và đang tiến rất trơn tru, rồi bất chợt nhận ra có một cách triển khai tốt hơn rất nhiều. Tôi muốn trải nghiệm những khoảnh khắc như vậy thường xuyên nhất có thể. Vì thế tôi làm TDD.
Nếu trong đầu bạn đã có hình dung rất rõ, và bạn có thể chắc chắn đầu vào nào tạo ra đầu ra nào, thì cứ triển khai thôi. Nhưng bạn càng dễ mắc sai lầm, càng học được nhiều hơn, và thế giới càng thay đổi khó lường hơn, thì việc chưa cam kết ngay lúc này mà để dành đến sau sẽ càng có lợi.
Q. Khi code cùng AI, ông còn phát triển bằng TDD như trước không?
Rất khó trả lời đơn giản.
Tôi dùng test như một phương tiện giao tiếp với AI, chủ yếu là để cho AI biết nó đã làm sai điều gì. Tên này cứ liên tục tìm cách xóa và sửa test của tôi, và mỗi lần như vậy tôi đều mắng nó. Test của tôi đúng, nên hãy làm cho đàng hoàng.
AI thường đưa ra những quyết định không tốt về dài hạn. Nó cũng rất kém trong việc giảm coupling và tăng cohesion. Nếu nói cho nó biết cực kỳ rõ ràng cần làm gì thì đôi khi nó làm được, nhưng nói chung phải xem là nó không giỏi thiết kế.
Vì vậy tôi chuẩn bị rất nhiều test. Tôi dùng chúng như một cách để phát hiện xem AI có đang đập phá thứ gì không.
(Của người dịch: Tham khảo bài viết này để xem Kent Beck dùng TDD với vibe coding như thế nào)
Q. Có vẻ sẽ tiện hơn nếu các agent rule như "tuyệt đối không sửa test, nếu chưa pass test thì chỉ sửa code triển khai cho đến khi pass" trở nên phổ biến. Cũng có cảm giác đây là thời điểm chúng ta đang khám phá lại những thứ từng quan trọng trong thập niên 2000. Ông nghĩ sao?
Cứ phải tiếp tục thử nghiệm thôi. Phải thử mọi thứ có thể. Vì hiện tại chúng ta chưa biết điều gì thực sự là tốt nhất.
Chân trời về việc cái gì là "rẻ" và cái gì là "đắt" đã thay đổi hoàn toàn. Rất nhiều thứ trước đây bị xem là tốn kém hoặc khó khăn nên không làm, giờ đã trở nên rẻ đến mức khó tin.
Nếu một ngày nào đó ô tô đột nhiên miễn phí thì theo bạn chuyện gì sẽ xảy ra? Chắc chắn sẽ có điều gì đó thay đổi, nhưng các thay đổi cấp hai, cấp ba kéo theo sẽ như thế nào? Không ai dự đoán nổi. Vì vậy, lúc này chỉ còn cách thử nhiều thứ khác nhau.
Q. Ông từng nói dù đã lập trình hơn 50 năm nhưng dạo này mới là lúc vui nhất. Ý ông là gì?
Việc hiện thực hóa những ý tưởng lớn lao của tôi giờ đây dễ hơn bao giờ hết. Việc quan sát xem AI có thể hiện thực hóa ý tưởng này hay không, và điều chỉnh để nó làm được, cực kỳ gây nghiện. Không biết khi nào nó sẽ làm tốt, và khi nó làm tốt như có phép màu thì cảm giác thật mê hoặc, nên cũng giống máy đánh bạc. Trước khi đi dạo hay đi ăn trưa, tôi luôn bị thôi thúc rằng hay là viết thêm một prompt nữa rồi mới đi, vì không muốn để tên này rảnh rỗi chơi không.
Hai năm trước, tôi từng đăng một tweet: "Tôi đã có cảm giác kháng cự với việc dùng ChatGPT, và hôm nay tôi vượt qua được cảm giác đó. Giờ thì tôi hiểu vì sao mình từng kháng cự. 90% kỹ năng của tôi giờ đã về $0. Và 10% còn lại đã được khuếch đại lên 1000 lần. Đã đến lúc tôi phải hiệu chỉnh lại kỹ năng của mình."
> I've been reluctant to try ChatGPT. Today I got over that reluctance. Now I understand why I was reluctant.
>
> The value of 90% of my skills just dropped to $0. The leverage for the remaining 10% went up 1000x. I need to recalibrate.
>
> -- Kent Beck 🌻 (@KentBeck) April 18, 2023
(Của người dịch: Khi tweet này trở thành chủ đề nóng, Kent cũng đã viết thêm một bài dài hơn.)
Khi đó ông nói vẫn đang khám phá xem 90% là gì và 10% là gì, nhưng giờ đây đã có thể đưa ra câu trả lời ở mức độ nào đó. Khả năng có một tầm nhìn táo bạo, đặt ra các milestone hướng đến tầm nhìn đó, và liên tục điều chỉnh thiết kế trong khi vẫn tiến về phía trước để kiểm soát độ phức tạp. Đây là kỹ năng quan trọng hơn rất rất nhiều so với kiến thức về cú pháp của một ngôn ngữ cụ thể (ví dụ: trong Rust thì nên đặt &, *, [ ở đâu).
Chưa có bình luận nào.