Đây có phải là hạn chế của Phát triển hướng thử nghiệm (và Agile nói chung) thực tế có liên quan không?


30

Trong Phát triển hướng thử nghiệm (TDD), bạn bắt đầu với một giải pháp tối ưu và sau đó lặp lại tạo ra những giải pháp tốt hơn bằng cách thêm các trường hợp thử nghiệm và bằng cách tái cấu trúc. Các bước được cho là nhỏ, có nghĩa là mỗi giải pháp mới sẽ bằng cách nào đó nằm trong vùng lân cận của giải pháp trước đó.

Điều này giống với các phương pháp tối ưu hóa địa phương toán học như giảm độ dốc hoặc tìm kiếm cục bộ. Một hạn chế nổi tiếng của các phương pháp như vậy là chúng không đảm bảo tìm thấy tối ưu toàn cầu, hoặc thậm chí là tối ưu cục bộ chấp nhận được. Nếu điểm xuất phát của bạn bị tách biệt khỏi tất cả các giải pháp có thể chấp nhận bởi một vùng lớn các giải pháp xấu, thì không thể đến đó và phương pháp sẽ thất bại.

Để cụ thể hơn: Tôi đang nghĩ về một kịch bản trong đó bạn đã thực hiện một số trường hợp thử nghiệm và sau đó thấy rằng trường hợp thử nghiệm tiếp theo sẽ yêu cầu một cách tiếp cận hoàn toàn khác. Bạn sẽ phải vứt bỏ công việc trước đây của bạn và bắt đầu lại.

Suy nghĩ này thực sự có thể được áp dụng cho tất cả các phương pháp nhanh, tiến hành theo các bước nhỏ, không chỉ với TDD. Điều này có tương tự đề xuất giữa TDD và tối ưu hóa cục bộ có bất kỳ sai sót nghiêm trọng nào không?


Bạn đang đề cập đến kỹ thuật phụ TDD được gọi là triangulation ? Theo "giải pháp có thể chấp nhận", bạn có nghĩa là một giải pháp chính xác hay duy trì / thanh lịch / có thể đọc được?
guillaume31

6
Tôi nghĩ rằng đây là một vấn đề thực sự. Vì đó chỉ là ý kiến ​​của tôi, tôi sẽ không viết câu trả lời. Nhưng vâng, vì TDD được quảng cáo là một thực tiễn thiết kế , đó là một lỗ hổng mà nó có thể dẫn đến cực đại cục bộ hoặc không có giải pháp nào cả. Tôi nói chung TDD KHÔNG phù hợp với thiết kế thuật toán. Xem các cuộc thảo luận liên quan về những hạn chế của TDD: Giải quyết Sudoku với TDD , trong đó Ron Jeffries tự khẳng định mình khi chạy trong vòng tròn và "làm TDD", trong khi Peter Norvig cung cấp giải pháp thực tế bằng cách thực sự hiểu về vấn đề này,
Andres F.

5
Nói cách khác, tôi đưa ra tuyên bố (hy vọng) không gây tranh cãi rằng TDD tốt cho việc giảm thiểu số lượng các lớp bạn viết trong các vấn đề "đã biết", do đó tạo ra mã sạch hơn và đơn giản hơn, nhưng không phù hợp với các vấn đề thuật toán hoặc cho các vấn đề phức tạp thực sự nhìn vào bức tranh lớn và có kiến ​​thức về miền cụ thể sẽ hữu ích hơn là viết các bài kiểm tra từng phần và "khám phá" mã bạn phải viết.
Andres F.

2
Vấn đề tồn tại, nhưng không giới hạn ở TDD hoặc thậm chí Agile. Thay đổi yêu cầu có nghĩa là thiết kế của phần mềm được viết trước đó phải thay đổi luôn luôn xảy ra.
RemcoGerlich

@ guillaume31: Không phải là tam giác không cần thiết nhưng bất kỳ kỹ thuật nào sử dụng phép lặp ở cấp mã nguồn. Bằng giải pháp có thể chấp nhận, ý tôi là một bài kiểm tra vượt qua tất cả các bài kiểm tra và có thể được duy trì hợp lý ..
Frank Puffer

Câu trả lời:


8

Một hạn chế nổi tiếng của các phương pháp như vậy là chúng không đảm bảo tìm thấy tối ưu toàn cầu, hoặc thậm chí là tối ưu cục bộ chấp nhận được.

Để làm cho sự so sánh của bạn đầy đủ hơn: đối với một số loại vấn đề, thuật toán tối ưu hóa lặp rất có khả năng tạo ra tối ưu cục bộ tốt, đối với một số tình huống khác, chúng có thể thất bại.

Tôi đang nghĩ về một kịch bản trong đó bạn đã thực hiện một số trường hợp thử nghiệm và sau đó thấy rằng trường hợp thử nghiệm tiếp theo sẽ yêu cầu một cách tiếp cận hoàn toàn khác. Bạn sẽ phải vứt bỏ công việc trước đây của bạn và bắt đầu lại.

Tôi có thể tưởng tượng một tình huống mà điều này có thể xảy ra trong thực tế: khi bạn chọn sai kiến ​​trúc theo cách bạn cần tạo lại tất cả các thử nghiệm hiện tại của bạn một lần nữa từ đầu. Giả sử bạn bắt đầu triển khai 20 trường hợp thử nghiệm đầu tiên của mình bằng ngôn ngữ lập trình X trên hệ điều hành A. Thật không may, yêu cầu 21 bao gồm toàn bộ chương trình cần chạy trên hệ điều hành B, trong đó X không có sẵn. Do đó, bạn cần phải vứt bỏ hầu hết công việc của mình và thực hiện lại bằng ngôn ngữ Y. (Tất nhiên, bạn sẽ không vứt bỏ hoàn toàn mã, mà chuyển nó sang ngôn ngữ và hệ thống mới.)

Điều này dạy chúng ta, ngay cả khi sử dụng TDD, bạn nên thực hiện một số phân tích và thiết kế tổng thể trước đó. Tuy nhiên, điều này cũng đúng với bất kỳ cách tiếp cận nào khác, vì vậy tôi không thấy đây là một vấn đề TDD cố hữu. Và, đối với phần lớn các tác vụ lập trình trong thế giới thực, bạn chỉ cần chọn một kiến ​​trúc tiêu chuẩn (như ngôn ngữ lập trình X, hệ điều hành Y, hệ thống cơ sở dữ liệu Z trên phần cứng XYZ), và bạn có thể tương đối chắc chắn rằng một phương pháp lặp hoặc nhanh như TDD sẽ không đưa bạn vào ngõ cụt.

Trích dẫn Robert Harvey: "Bạn không thể phát triển kiến ​​trúc từ các bài kiểm tra đơn vị." Hoặc pdr: "TDD không chỉ giúp tôi đi đến thiết kế cuối cùng tốt nhất, nó giúp tôi đạt được điều đó trong ít nỗ lực hơn."

Vì vậy, thực sự những gì bạn đã viết

Nếu điểm xuất phát của bạn bị tách biệt khỏi tất cả các giải pháp có thể chấp nhận bởi một vùng rộng lớn các giải pháp xấu thì không thể đến đó và phương pháp sẽ thất bại.

có thể trở thành sự thật - khi bạn chọn một kiến ​​trúc sai, bạn có thể không đạt được giải pháp cần thiết từ đó.

Mặt khác, khi bạn thực hiện một số kế hoạch tổng thể trước đó và chọn kiến ​​trúc phù hợp, sử dụng TDD sẽ giống như bắt đầu một thuật toán tìm kiếm lặp trong một khu vực mà bạn có thể mong đợi đạt đến "tối đa toàn cầu" (hoặc ít nhất là tối đa đủ tốt ) trong một vài chu kỳ.


20

Tôi không nghĩ TDD có vấn đề về cực đại địa phương. Mã bạn viết có thể, như bạn đã nhận thấy chính xác, nhưng đó là lý do tại sao tái cấu trúc (viết lại mã mà không thay đổi chức năng) được đưa ra. Về cơ bản, khi các thử nghiệm của bạn tăng lên, bạn có thể viết lại các phần quan trọng của mô hình đối tượng nếu bạn cần trong khi giữ cho hành vi không thay đổi nhờ các thử nghiệm. Kiểm tra các sự thật bất biến về hệ thống của bạn, do đó, cần phải có giá trị cả về cực đại cục bộ và cực đại.

Nếu bạn quan tâm đến các vấn đề liên quan đến TDD, tôi có thể đề cập đến ba vấn đề khác nhau mà tôi thường nghĩ về:

  1. Các tính đầy đủ vấn đề: có bao nhiêu bài kiểm tra là cần thiết để mô tả hoàn toàn một hệ thống? Là "mã hóa bằng các trường hợp ví dụ" là một cách hoàn chỉnh để mô tả một hệ thống?

  2. Các cứng vấn đề: bất cứ thử nghiệm giao diện, cần phải có một giao diện không thể thay đổi. Các xét nghiệm đại diện cho sự thật bất biến , hãy nhớ. Thật không may, những sự thật này hoàn toàn không được biết đối với hầu hết các mã chúng ta viết, tốt nhất chỉ dành cho các đối tượng phải đối mặt bên ngoài.

  3. Các bài kiểm tra thiệt hại vấn đề: để thực hiện khẳng định kiểm chứng, chúng tôi có thể cần phải viết mã tối ưu (ít performant, ví dụ). Làm thế nào để chúng ta viết các bài kiểm tra để mã tốt nhất có thể?


Đã chỉnh sửa để giải quyết một nhận xét: đây là một ví dụ về việc trích xuất tối đa cục bộ cho chức năng "nhân đôi" thông qua tái cấu trúc

Kiểm tra 1: khi đầu vào bằng 0, trả về 0

Thực hiện:

function double(x) {
  return 0; // simplest possible code that passes tests
}

Tái cấu trúc: không cần thiết

Kiểm tra 2: khi đầu vào là 1, trả về 2

Thực hiện:

function double(x) {
  return x==0?0:2; // local maximum
}

Tái cấu trúc: không cần thiết

Kiểm tra 3: khi đầu vào là 2, trả về 4

Thực hiện:

function double(x) {
  return x==0?0:x==2?4:2; // needs refactoring
}

Tái cấu trúc:

function double(x) {
  return x*2; // new maximum
}

1
Tuy nhiên, những gì tôi đã trải nghiệm là thiết kế đầu tiên của tôi chỉ hoạt động cho một số trường hợp đơn giản và sau đó tôi nhận ra rằng tôi cần một giải pháp tổng quát hơn. Phát triển giải pháp tổng quát hơn yêu cầu nhiều thử nghiệm hơn trong khi các thử nghiệm ban đầu cho các trường hợp đặc biệt sẽ không hoạt động trở lại. Tôi thấy có thể chấp nhận (tạm thời) loại bỏ các thử nghiệm đó trong khi tôi phát triển giải pháp tổng quát hơn, thêm chúng trở lại sau khi thời gian đã sẵn sàng.
5gon12eder

3
Tôi không tin rằng tái cấu trúc là một cách để khái quát mã (bên ngoài không gian "mẫu thiết kế" nhân tạo, tất nhiên) hoặc thoát khỏi cực đại cục bộ. Tái cấu trúc mã hóa, nhưng nó sẽ không giúp bạn khám phá một giải pháp tốt hơn.
Andres F.

2
@Sklivvz Hiểu, nhưng tôi không nghĩ rằng nó hoạt động theo cách đó bên ngoài các ví dụ đồ chơi như những gì bạn đã đăng. Ngoài ra, nó đã giúp bạn rằng chức năng của bạn được đặt tên là "gấp đôi"; theo cách bạn đã biết câu trả lời. TDD chắc chắn sẽ giúp khi bạn ít nhiều biết câu trả lời nhưng muốn viết nó một cách "sạch sẽ". Nó sẽ không giúp ích cho việc khám phá các thuật toán hoặc viết mã thực sự phức tạp. Đây là lý do Ron Jeffries thất bại trong việc giải Sudoku theo cách này; bạn không thể thực hiện thuật toán mà bạn không quen thuộc bằng cách sử dụng thuật toán này không rõ ràng.
Andres F.

1
@VaughnCato Ok, bây giờ tôi đang ở trong tình trạng tin tưởng bạn hoặc bị hoài nghi (điều đó sẽ là thô lỗ, vì vậy chúng ta đừng làm điều đó). Hãy nói, theo kinh nghiệm của tôi, nó không hoạt động như bạn nói. Tôi chưa bao giờ thấy một thuật toán khá phức tạp được phát triển từ TDD. Có lẽ kinh nghiệm của tôi quá hạn chế :)
Andres F.

2
@Sklivvz "Miễn là bạn có thể viết các bài kiểm tra phù hợp" chính xác là vấn đề: nghe có vẻ như đang cầu xin câu hỏi cho tôi. Điều tôi đang nói là bạn thường không thể . Suy nghĩ về một thuật toán hoặc một người giải không được thực hiện dễ dàng hơn bằng cách viết các bài kiểm tra trước . Bạn phải nhìn vào toàn bộ bức tranh trước . Tất nhiên, việc thử các kịch bản là cần thiết, nhưng lưu ý TDD không phải là viết kịch bản: TDD là về thử nghiệm thiết kế ! Bạn không thể lái thiết kế bộ giải Sudoku (hoặc bộ giải mới cho một trò chơi khác) bằng cách viết bài kiểm tra trước. Như một bằng chứng giai thoại (không đủ): Jeffries không thể.
Andres F.

13

Những gì bạn đang mô tả bằng thuật ngữ toán học là những gì chúng ta gọi là vẽ chính mình vào một góc. Sự xuất hiện này hầu như không dành riêng cho TDD. Trong thác nước, bạn có thể tập hợp và đổ các yêu cầu trong nhiều tháng với hy vọng bạn chỉ có thể nhìn thấy mức tối đa toàn cầu để đến đó và nhận ra rằng có một ý tưởng tốt hơn chỉ là ngọn đồi tiếp theo.

Sự khác biệt là trong một môi trường nhanh nhẹn mà bạn không bao giờ mong đợi là hoàn hảo vào thời điểm này vì vậy bạn đã sẵn sàng để từ bỏ ý tưởng cũ và chuyển sang ý tưởng mới.

Cụ thể hơn đối với TDD, có một kỹ thuật để ngăn điều này xảy ra với bạn khi bạn thêm các tính năng trong TDD. Đó là tiền đề ưu tiên chuyển đổi . Trong đó TDD có một cách chính thức để bạn cấu trúc lại, đây là cách chính thức để thêm các tính năng.


13

Trong câu trả lời của mình , @Sklivvz đã lập luận một cách thuyết phục rằng vấn đề không tồn tại.

Tôi muốn tranh luận rằng điều đó không thành vấn đề: tiền đề cơ bản (và raison d'être) của các phương pháp lặp nói chung và Agile và đặc biệt là TDD nói riêng, không chỉ là tối ưu toàn cầu, mà còn là tối ưu cục bộ. t biết Vì vậy, nói cách khác: ngay cả khi đó là một vấn đề, không có cách nào để thực hiện theo cách lặp đi lặp lại. Giả sử rằng bạn chấp nhận tiền đề cơ bản.


8

Các thực hành TDD và Agile có thể hứa hẹn sẽ tạo ra một giải pháp tối ưu không? (Hoặc thậm chí là một giải pháp "tốt"?)

Không chính xác. Nhưng, đó không phải là mục đích của họ.

Các phương pháp này chỉ đơn giản cung cấp "lối đi an toàn" từ trạng thái này sang trạng thái khác, thừa nhận rằng những thay đổi là tốn thời gian, khó khăn và rủi ro. Và quan điểm của cả hai thực tiễn là đảm bảo rằng ứng dụng và mã đều khả thi và được chứng minh là đáp ứng các yêu cầu nhanh hơn và thường xuyên hơn.

... [TDD] trái ngược với phát triển phần mềm cho phép thêm phần mềm mà không được chứng minh là đáp ứng yêu cầu ... Kent Beck, người được cho là đã phát triển hoặc 'khám phá lại' kỹ thuật, tuyên bố năm 2003 rằng TDD khuyến khích đơn giản thiết kế và truyền cảm hứng cho sự tự tin. ( Wikipedia )

TDD tập trung vào việc đảm bảo mỗi "đoạn" mã thỏa mãn các yêu cầu. Cụ thể, nó giúp đảm bảo rằng mã đáp ứng các yêu cầu có sẵn, trái ngược với việc để các yêu cầu được điều khiển bởi mã hóa kém. Nhưng, không có gì hứa hẹn rằng việc thực hiện là "tối ưu" theo bất kỳ cách nào.

Đối với các quy trình Agile:

Phần mềm làm việc là thước đo chính của tiến trình ... Vào cuối mỗi lần lặp, các bên liên quan và đại diện khách hàng xem xét tiến độ và đánh giá lại các ưu tiên nhằm tối ưu hóa lợi tức đầu tư ( Wikipedia )

Agility không tìm kiếm một giải pháp tối ưu ; chỉ là một giải pháp làm việc - với mục đích tối ưu hóa ROI . Nó hứa hẹn một giải pháp làm việc sớm hơn là sau này ; không phải là một "tối ưu".

Nhưng, điều đó ổn, bởi vì câu hỏi là sai.

Tối ưu trong phát triển phần mềm là mục tiêu mờ, di chuyển. Các yêu cầu thường là thay đổi liên tục và đánh đố với những bí mật chỉ xuất hiện, khiến bạn bối rối, trong một phòng hội nghị đầy sếp của sếp. Và "lòng tốt nội tại" của kiến ​​trúc và mã hóa của giải pháp được phân loại theo ý kiến ​​chia rẽ và chủ quan của các đồng nghiệp của bạn và của cấp trên quản lý của bạn - không ai trong số họ thực sự có thể biết bất cứ điều gì về phần mềm tốt.

Trong Ít nhất, TDD và Agile thực hành thừa nhận những khó khăn và cố gắng để tối ưu hóa cho hai điều đó khách quan và đo lường được: . Working v Không-Workingv Sớm sau..

Và, ngay cả khi chúng tôi đã "làm việc" và "sớm hơn" như các số liệu khách quan, khả năng tối ưu hóa của bạn đối với họ chủ yếu phụ thuộc vào kỹ năng và kinh nghiệm của một đội.


Những điều bạn có thể hiểu là những nỗ lực tạo ra các giải pháp tối ưu bao gồm những thứ như:

v.v.

Cho dù mỗi người trong số những điều thực sự tạo ra các giải pháp tối ưu sẽ là một câu hỏi tuyệt vời để đặt!


1
Đúng, nhưng tôi đã không viết rằng mục tiêu của TDD hoặc bất kỳ phương pháp phát triển phần mềm nào khác là một giải pháp tối ưu theo nghĩa tối ưu toàn cầu. Mối quan tâm duy nhất của tôi là các phương pháp dựa trên các lần lặp nhỏ ở cấp mã nguồn có thể không tìm thấy bất kỳ giải pháp nào (đủ tốt) trong nhiều trường hợp
Frank Puffer

@Frank Câu trả lời của tôi nhằm mục đích bao gồm cả tối ưu địa phương và toàn cầu. Và câu trả lời là "Không, đó không phải là những gì các chiến lược này được thiết kế cho - chúng được thiết kế để cải thiện ROI và giảm thiểu rủi ro." ... hoặc điều tương tự. Và đó là một phần nhờ vào câu trả lời của Jorg: "tối ưu" là mục tiêu di chuyển. ... Tôi thậm chí còn tiến thêm một bước nữa; họ không chỉ di chuyển mục tiêu, mà, họ không hoàn toàn khách quan hay đo lường được.
Svidgen

@FrankPuffer Có lẽ nó đáng để bổ sung. Nhưng, điểm cơ bản là, bạn đang hỏi liệu hai điều này có đạt được điều gì đó mà chúng không được thiết kế hay dự định đạt được hay không. Hơn thế nữa, bạn đang hỏi liệu họ có thể đạt được thứ gì đó thậm chí không thể đo lường hoặc xác minh được không.
Svidgen

@FrankPuffer Bah. Tôi đã cố gắng cập nhật câu trả lời của tôi để nói nó tốt hơn. Tôi không chắc tôi đã làm cho nó tốt hơn hay tồi tệ hơn! ... Nhưng, tôi cần phải rời khỏi SE.SE và trở lại làm việc.
Svidgen

Câu trả lời này là ổn, nhưng vấn đề tôi gặp phải (như với một số câu trả lời khác) là "giảm thiểu rủi ro và cải thiện ROI" không phải lúc nào cũng là mục tiêu tốt nhất. Trên thực tế, chúng không phải là mục tiêu. Khi bạn cần một cái gì đó để làm việc, giảm thiểu rủi ro sẽ không cắt giảm. Đôi khi các bước nhỏ tương đối không được định hướng như trong TDD sẽ không hoạt động - bạn sẽ giảm thiểu rủi ro, nhưng cuối cùng bạn sẽ không đạt được bất kỳ nơi nào hữu ích.
Andres F.

4

Một điều mà không ai thêm vào cho đến nay là "Phát triển TDD" mà bạn đang mô tả là rất trừu tượng và không thực tế. Nó có thể giống như trong một ứng dụng toán học nơi bạn đang tối ưu hóa một thuật toán nhưng điều đó không xảy ra nhiều trong các ứng dụng kinh doanh mà hầu hết các lập trình viên đều làm việc.

Trong thế giới thực, các bài kiểm tra của bạn về cơ bản đang thực hiện và xác thực Quy tắc kinh doanh:

Ví dụ: Nếu một khách hàng là một người không hút thuốc 30 tuổi có vợ và hai con thì loại cao cấp là "x", v.v.

Bạn sẽ không thay đổi lặp đi lặp lại công cụ tính toán cao cấp cho đến khi nó chính xác trong thời gian rất dài - và gần như chắc chắn là không trong khi ứng dụng đang hoạt động;).

Những gì bạn thực sự đã tạo là một mạng lưới an toàn để khi thêm một phương pháp tính toán mới cho một danh mục khách hàng cụ thể, tất cả các quy tắc cũ không đột nhiên phá vỡ và đưa ra câu trả lời sai. Mạng an toàn thậm chí còn hữu ích hơn nếu bước đầu tiên của quá trình gỡ lỗi là tạo một thử nghiệm (hoặc loạt thử nghiệm) tái tạo lỗi trước khi viết mã để sửa lỗi. Sau đó, một năm sau, nếu ai đó vô tình tạo lại lỗi ban đầu, kiểm tra đơn vị bị hỏng trước khi mã được kiểm tra. Có, một điều TDD cho phép là giờ đây bạn có thể thực hiện tái cấu trúc lớn và dọn dẹp công cụ gọn gàng nhưng nó không nên là một phần lớn trong công việc của bạn.


1
Đầu tiên, khi tôi đọc câu trả lời của bạn, tôi nghĩ "vâng, đó là điểm cốt lõi". Nhưng sau khi suy nghĩ lại câu hỏi một lần nữa, tôi nghĩ rằng nó không nhất thiết phải quá trừu tượng hoặc không thực tế. Nếu một người chọn mù quáng kiến ​​trúc hoàn toàn sai, TDD sẽ không giải quyết được điều đó, không phải sau 1000 lần lặp.
Doc Brown

@Doc Brown Đồng ý, nó sẽ không giải quyết vấn đề đó. Nhưng nó sẽ cung cấp cho bạn một bộ các bài kiểm tra thực hiện mọi quy tắc kinh doanh và giả định để bạn có thể cải thiện kiến ​​trúc. Kiến trúc tệ đến mức nó cần phải viết lại để sửa chữa là rất hiếm (tôi hy vọng) và ngay cả trong trường hợp cực đoan đó, các bài kiểm tra đơn vị quy tắc kinh doanh sẽ là điểm khởi đầu tốt.
đánh dấu

Khi tôi nói "kiến trúc sai", tôi có trường hợp trong đó người ta cần phải vứt bỏ bộ thử nghiệm hiện có. Bạn đã đọc câu trả lời của tôi?
Doc Brown

@DocBrown - Có tôi đã làm. Nếu bạn có nghĩa là "kiến trúc sai" có nghĩa là "thay đổi toàn bộ bộ kiểm tra" thì có lẽ bạn nên nói điều đó. Thay đổi Kiến trúc không có nghĩa là bạn phải bỏ qua tất cả các bài kiểm tra nếu chúng dựa trên Quy tắc kinh doanh. Bạn có thể sẽ phải thay đổi tất cả chúng để hỗ trợ bất kỳ giao diện mới nào bạn tạo và thậm chí viết lại hoàn toàn một số, nhưng Quy tắc kinh doanh sẽ không bị thay thế bởi thay đổi kỹ thuật nên các bài kiểm tra sẽ vẫn còn. Chắc chắn đầu tư vào các thử nghiệm đơn vị không nên bị vô hiệu bởi khả năng không thể hoàn toàn chiếm lĩnh kiến ​​trúc
phá hủy

chắc chắn, ngay cả khi người ta cần viết lại mọi bài kiểm tra bằng ngôn ngữ lập trình mới, người ta không cần phải vứt bỏ mọi thứ, ít nhất một người có thể chuyển logic hiện có. Và tôi đồng ý với bạn 100% cho các dự án lớn trong thế giới thực, các giả định trong câu hỏi khá phi thực tế.
Doc Brown

3

Tôi không nghĩ rằng nó cản trở. Hầu hết các đội không có ai có khả năng đưa ra giải pháp tối ưu ngay cả khi bạn viết nó lên bảng trắng của họ. TDD / Agile sẽ không cản trở họ.

Nhiều dự án không yêu cầu giải pháp tối ưu và những dự án đó, thời gian, năng lượng và sự tập trung cần thiết sẽ được thực hiện trong lĩnh vực này. Giống như mọi thứ khác chúng ta có xu hướng xây dựng, đầu tiên, làm cho nó hoạt động. Sau đó làm cho nó nhanh. Bạn có thể làm điều này với một số loại nguyên mẫu nếu hiệu suất là quan trọng và sau đó xây dựng lại toàn bộ với sự khôn ngoan có được qua nhiều lần lặp lại.

Tôi đang nghĩ về một kịch bản trong đó bạn đã thực hiện một số trường hợp thử nghiệm và sau đó thấy rằng trường hợp thử nghiệm tiếp theo sẽ yêu cầu một cách tiếp cận hoàn toàn khác. Bạn sẽ phải vứt bỏ công việc trước đây của bạn và bắt đầu lại.

Điều này có thể xảy ra, nhưng những gì có nhiều khả năng xảy ra là nỗi sợ thay đổi các phần phức tạp của ứng dụng. Không có bất kỳ bài kiểm tra nào có thể tạo ra cảm giác sợ hãi lớn hơn trong lĩnh vực này. Một lợi ích của TDD và có một bộ thử nghiệm là bạn đã xây dựng hệ thống này với khái niệm rằng nó sẽ cần phải được thay đổi. Khi bạn đưa ra giải pháp tối ưu hóa nguyên khối này ngay từ đầu, có thể rất khó thay đổi.

Ngoài ra, hãy đặt vấn đề này trong bối cảnh bạn quan tâm đến việc tối ưu hóa và bạn không thể dành thời gian tối ưu hóa những thứ bạn không nên có và tạo ra các giải pháp không linh hoạt vì bạn quá tập trung vào hiệu suất của chúng.


0

Có thể lừa dối khi áp dụng khái niệm toán học như "tối ưu cục bộ" vào thiết kế phần mềm. Sử dụng các thuật ngữ như vậy làm cho việc phát triển phần mềm nghe có vẻ định lượng và khoa học hơn nhiều so với thực tế. Ngay cả khi "tối ưu" tồn tại cho mã, chúng tôi không có cách nào để đo lường nó và do đó không có cách nào để biết liệu chúng tôi có đạt được nó hay không.

Phong trào nhanh nhẹn thực sự là một phản ứng chống lại niềm tin rằng sự phát triển phần mềm có thể được lên kế hoạch và dự đoán bằng các phương pháp toán học. Dù tốt hay xấu, phát triển phần mềm giống như một nghề thủ công hơn là khoa học.


Nhưng đó có phải là một phản ứng quá mạnh mẽ? Nó chắc chắn giúp ích trong rất nhiều trường hợp trong đó kế hoạch trả trước nghiêm ngặt tỏ ra khó sử dụng và tốn kém. Tuy nhiên, một số vấn đề phần mềm phải được giải quyết như một vấn đề toán học và với thiết kế trả trước. Bạn không thể TDD chúng. Bạn có thể TDD giao diện người dùng và thiết kế tổng thể của Photoshop, nhưng bạn không thể TDD thuật toán của nó. Chúng không phải là những ví dụ tầm thường như lấy "tổng" hoặc "nhân đôi" hoặc "pow" trong các ví dụ TDD điển hình [1]). Bạn có thể không thể trêu chọc một bộ lọc hình ảnh mới bằng cách viết một số kịch bản thử nghiệm; bạn tuyệt đối phải ngồi xuống và viết và hiểu các công thức.
Andres F.

2
[1] Trên thực tế, tôi khá chắc chắn fibonacci, điều mà tôi đã thấy được sử dụng như một ví dụ / hướng dẫn TDD, ít nhiều là một lời nói dối. Tôi sẵn sàng đặt cược không ai từng "phát hiện" Dailymotion hoặc bất kỳ loạt tương tự nào bằng cách TDD'ing nó. Mọi người bắt đầu từ đã biết đến Wikipedia, đó là gian lận. Nếu bạn cố gắng khám phá điều này bằng cách TDD'ing nó, bạn có thể sẽ đi đến ngõ cụt mà OP đã hỏi về: bạn sẽ không bao giờ có thể khái quát hóa chuỗi bằng cách viết thêm các bài kiểm tra và tái cấu trúc - bạn phải áp dụng toán học lý luận!
Andres F.

Hai nhận xét: (1) Bạn đúng rằng điều này có thể lừa dối. Nhưng tôi đã không viết rằng TDD giống như tối ưu hóa toán học. Tôi chỉ sử dụng nó như một sự tương tự hoặc một mô hình. Tôi tin rằng toán học có thể (và nên) được áp dụng cho hầu hết mọi thứ miễn là bạn nhận thức được sự khác biệt giữa mô hình và thực tế. (2) Khoa học (công việc khoa học) thường ít dự đoán hơn so với phát triển phần mềm. Và tôi thậm chí sẽ nói rằng công nghệ phần mềm giống như công việc khoa học hơn là thủ công. Thủ công thường đòi hỏi nhiều công việc thường xuyên hơn.
Frank Puffer

@AndresF.: TDD không có nghĩa là bạn không phải suy nghĩ hay thiết kế. Nó chỉ có nghĩa là bạn viết bài kiểm tra trước khi bạn viết bài thực hiện. Bạn có thể làm điều đó với các thuật toán.
JacquesB

@FrankPuffer: OK, vậy giá trị có thể đo được là gì có "tối ưu cục bộ" trong phát triển phần mềm?
JacquesB
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.