Ist diese Einschränkung von Test Driven Development (und Agile im Allgemeinen) praktisch relevant?

30

In Test Driven Development (TDD) beginnen Sie mit einer suboptimalen Lösung und erzeugen dann iterativ bessere, indem Sie Testfälle hinzufügen und umgestalten. Die Schritte sollten klein sein, was bedeutet, dass sich jede neue Lösung in der Nähe der vorherigen befindet.

Dies ähnelt mathematischen lokalen Optimierungsmethoden wie Gradientenabstieg oder lokale Suche. Eine bekannte Einschränkung solcher Verfahren besteht darin, dass sie nicht garantieren, das globale Optimum oder sogar ein akzeptables lokales Optimum zu finden. Wenn Ihr Ausgangspunkt von allen akzeptablen Lösungen durch eine große Anzahl fehlerhafter Lösungen getrennt ist, ist es unmöglich, dorthin zu gelangen, und die Methode schlägt fehl.

Genauer gesagt: Ich denke an ein Szenario, in dem Sie eine Reihe von Testfällen implementiert haben und dann feststellen, dass der nächste Testfall einen kompetent anderen Ansatz erfordert. Sie müssen Ihre bisherige Arbeit wegwerfen und von vorne beginnen.

Dieser Gedanke kann tatsächlich auf alle agilen Methoden angewendet werden, die in kleinen Schritten ablaufen, nicht nur auf TDD. Hat diese vorgeschlagene Analogie zwischen TDD und lokaler Optimierung irgendwelche gravierenden Mängel?

Frank Puffer
quelle
Beziehen Sie sich auf die TDD-Subtechnik namens Triangulation ? Meinen Sie mit "akzeptable Lösung" eine richtige oder eine wartbare / elegante / lesbare?
Guillaume31
6
Ich denke, das ist ein echtes Problem. Da es nur meine Meinung ist, werde ich keine Antwort schreiben. Aber ja, da TDD als Konstruktionspraxis angepriesen wird , ist es ein Fehler, dass es entweder zu lokalen Maxima oder gar zu keiner Lösung führen kann. Ich würde allgemein sagen, dass TDD für algorithmisches Design NICHT gut geeignet ist. Sehen Sie sich die damit verbundene Diskussion über die Grenzen der TDD: Lösen von Sudoku mit TDD , in denen Ron Jeffries einen Esel aus sich macht , während im Kreis laufen und „tun TDD“, während Peter Norvig die eigentliche Lösung bietet durch wirklich zu wissen , über den Gegenstand,
Andres F.
5
Mit anderen Worten, ich würde die (hoffentlich) unumstrittene Aussage machen, dass TDD gut für die Minimierung der Anzahl von Klassen geeignet ist, die Sie in "bekannten" Problemen schreiben, und daher saubereren und einfacheren Code erzeugt, aber für algorithmische Probleme oder für komplexe Probleme ungeeignet ist Es ist nützlicher, das Gesamtbild zu betrachten und domänenspezifisches Wissen zu besitzen, als schrittweise Tests zu schreiben und den Code zu "entdecken", den Sie schreiben müssen.
Andres F.
2
Das Problem besteht, ist aber nicht auf TDD oder sogar Agile beschränkt. Sich ändernde Anforderungen, die bedeuten, dass sich das Design zuvor geschriebener Software ständig ändern muss.
RemcoGerlich
@ guillaume31: Nicht unbedingt Triangulation, sondern jede Technik, die Iterationen auf Quellcode-Ebene verwendet. Mit akzeptabler Lösung meine ich eine, die alle Tests besteht und einigermaßen gut gewartet werden kann.
Frank Puffer

Antworten:

8

Eine bekannte Einschränkung solcher Verfahren besteht darin, dass sie nicht garantieren, das globale Optimum oder sogar ein akzeptables lokales Optimum zu finden.

Um Ihren Vergleich angemessener zu gestalten: Bei bestimmten Problemen führen iterative Optimierungsalgorithmen mit hoher Wahrscheinlichkeit zu guten lokalen Optima. In einigen anderen Situationen können sie fehlschlagen.

Ich denke an ein Szenario, in dem Sie eine Reihe von Testfällen implementiert haben und dann feststellen, dass der nächste Testfall einen kompetent anderen Ansatz erfordert. Sie müssen Ihre bisherige Arbeit wegwerfen und von vorne beginnen.

Ich kann mir eine Situation vorstellen, in der dies in der Realität passieren kann: Wenn Sie die falsche Architektur auswählen , müssen Sie alle vorhandenen Tests erneut von Grund auf neu erstellen. Nehmen wir an, Sie beginnen mit der Implementierung Ihrer ersten 20 Testfälle in der Programmiersprache X auf Betriebssystem A. Leider enthält Anforderung 21, dass das gesamte Programm auf Betriebssystem B ausgeführt werden muss, auf dem X nicht verfügbar ist. Daher müssen Sie den größten Teil Ihrer Arbeit und Neuimplementierung in Sprache Y wegwerfen. (Natürlich würden Sie den Code nicht vollständig wegwerfen, sondern ihn auf die neue Sprache und das neue System portieren.)

Dies lehrt uns, dass es auch bei der Verwendung von TDD eine gute Idee ist, vorher eine Gesamtanalyse und ein Gesamtdesign durchzuführen. Dies gilt jedoch auch für jede andere Herangehensweise, sodass ich dies nicht als inhärentes TDD-Problem sehe. Und für die meisten realen Programmieraufgaben können Sie einfach eine Standardarchitektur auswählen (wie Programmiersprache X, Betriebssystem Y, Datenbanksystem Z auf Hardware XYZ), und Sie können relativ sicher sein, dass eine iterative oder agile Methodik wie TDD bringt dich nicht in eine Sackgasse.

Unter Berufung auf Robert Harvey: "Aus Unit-Tests lässt sich keine Architektur entwickeln." Oder pdr: "TDD hilft mir nicht nur, zum besten endgültigen Design zu gelangen, sondern hilft mir auch, in weniger Versuchen dorthin zu gelangen."

Also eigentlich was du geschrieben hast

Wenn Ihr Ausgangspunkt durch eine große Anzahl von fehlerhaften Lösungen von allen akzeptablen Lösungen getrennt ist, ist es unmöglich, dorthin zu gelangen, und die Methode schlägt fehl.

Wenn Sie sich für eine falsche Architektur entscheiden, erreichen Sie wahrscheinlich nicht die erforderliche Lösung.

Wenn Sie jedoch eine Gesamtplanung im Voraus durchführen und die richtige Architektur auswählen, sollte TDD so aussehen, als würde ein iterativer Suchalgorithmus in einem Bereich gestartet, in dem Sie ein "globales Maximum" (oder zumindest ein ausreichend hohes Maximum) erwarten können ) in wenigen Zyklen.

Doc Brown
quelle
20

Ich glaube nicht, dass TDD ein Problem mit lokalen Maxima hat. Der von Ihnen geschriebene Code könnte, wie Sie richtig bemerkt haben, umgestaltet werden (Code umschreiben, ohne die Funktionalität zu ändern). Grundsätzlich können Sie mit zunehmender Anzahl Ihrer Tests wichtige Teile Ihres Objektmodells neu schreiben, wenn dies erforderlich ist, während das Verhalten dank der Tests unverändert bleibt. Tests geben unveränderliche Wahrheiten über Ihr System an, die daher sowohl in lokalen als auch in absoluten Maxima gültig sein müssen.

Wenn Sie an Problemen im Zusammenhang mit TDD interessiert sind, kann ich drei verschiedene erwähnen, an die ich oft denke:

  1. Das Vollständigkeitsproblem : Wie viele Tests sind erforderlich, um ein System vollständig zu beschreiben? Ist "Codierung anhand von Beispielfällen" eine vollständige Beschreibung eines Systems?

  2. Das Problem der Aushärtung : Was auch immer die Schnittstelle testet, muss eine unveränderbare Schnittstelle haben. Tests repräsentieren unveränderliche Wahrheiten . Leider sind diese Wahrheiten für den größten Teil des Codes, den wir schreiben, überhaupt nicht bekannt, allenfalls für Objekte, die nach außen gerichtet sind.

  3. Der Test Schaden Problem: Um Behauptungen testbar zu machen, könnten wir brauchen Schreib suboptimalen Code (weniger performant, zum Beispiel). Wie schreiben wir Tests, damit der Code so gut wie möglich ist?


Bearbeitet, um einen Kommentar zu adressieren: Hier ist ein Beispiel für das Erhöhen eines lokalen Maximums für eine "doppelte" Funktion durch Refactoring

Test 1: Wenn der Eingang 0 ist, wird Null zurückgegeben

Implementierung:

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

Refactoring: nicht erforderlich

Test 2: Wenn die Eingabe 1 ist, wird 2 zurückgegeben

Implementierung:

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

Refactoring: nicht erforderlich

Test 3: Wenn die Eingabe 2 ist, wird 4 zurückgegeben

Implementierung:

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

Refactoring:

function double(x) {
  return x*2; // new maximum
}
Sklivvz
quelle
1
Was ich jedoch erlebt habe, ist, dass mein erstes Design nur für einige einfache Fälle funktioniert hat und ich später erkannte, dass ich eine allgemeinere Lösung brauche. Die Entwicklung der allgemeineren Lösung erforderte mehr Tests, während die ursprünglichen Tests für die Sonderfälle nicht mehr funktionieren. Ich fand es akzeptabel, diese Tests (vorübergehend) zu entfernen, während ich die allgemeinere Lösung entwickle, und sie wieder hinzuzufügen, sobald die Zeit abgelaufen ist.
5gon12eder
3
Ich bin nicht davon überzeugt, dass Refactoring eine Möglichkeit ist, Code zu verallgemeinern (natürlich außerhalb des künstlichen Raums für "Entwurfsmuster") oder lokalen Maxima zu entkommen. Das Refactoring räumt Code auf, hilft Ihnen jedoch nicht, eine bessere Lösung zu finden.
Andres F.
2
@Sklivvz Verstanden, aber ich denke nicht, dass es so außerhalb von Spielzeugbeispielen funktioniert, wie die, die Sie gepostet haben. Es hat Ihnen auch geholfen, dass Ihre Funktion "double" heißt. In gewisser Weise wussten Sie bereits die Antwort. TDD hilft auf jeden Fall, wenn Sie die Antwort mehr oder weniger kennen, sie aber "sauber" schreiben möchten. Es würde nicht helfen, Algorithmen zu entdecken oder wirklich komplexen Code zu schreiben. Aus diesem Grund konnte Ron Jeffries Sudoku nicht auf diese Weise lösen. Sie können keinen Algorithmus implementieren, mit dem Sie nicht vertraut sind, indem Sie ihn aus Unklarheit entfernen.
Andres F.
1
@VaughnCato Ok, jetzt bin ich in der Lage, dir entweder zu vertrauen oder skeptisch zu sein (was unhöflich wäre, also lass uns das nicht tun). Sagen wir einfach, nach meiner Erfahrung funktioniert es nicht so, wie Sie es sagen. Ich habe noch nie einen ziemlich komplexen Algorithmus gesehen, der sich aus TDD entwickelt hat. Vielleicht ist meine Erfahrung zu begrenzt :)
Andres F.
2
@Sklivvz "Solange Sie die entsprechenden Tests schreiben können" ist genau der Punkt: Es klingt, als würde ich die Frage stellen. Was ich sage ist, dass Sie oft nicht können . Das Nachdenken über einen Algorithmus oder einen Löser wird nicht dadurch erleichtert , dass zuerst Tests geschrieben werden . Sie müssen das ganze Bild aussehen zuerst . Das Ausprobieren von Szenarien ist natürlich notwendig, aber bei TDD geht es nicht darum, Szenarien zu schreiben: Bei TDD geht es darum , das Design zu testen ! Sie können das Design eines Sudoku-Lösers (oder eines neuen Lösers für ein anderes Spiel) nicht steuern, indem Sie zuerst Tests schreiben. Als anekdotischer Beweis (was nicht genug ist): Jeffries konnte nicht.
Andres F.
13

Was Sie in mathematischen Begriffen beschreiben, nennen wir sich selbst in einer Ecke malen. Dieses Vorkommen ist für TDD kaum exklusiv. Im Wasserfall können Sie monatelang Anforderungen sammeln und überfluten, in der Hoffnung, dass Sie das globale Maximum sehen können, um dorthin zu gelangen und zu erkennen, dass es eine bessere Idee gibt, wenn Sie den nächsten Hügel überqueren.

Der Unterschied liegt in einer agilen Umgebung, von der Sie nie erwartet haben, dass sie zu diesem Zeitpunkt perfekt ist. Sie sind also mehr als bereit, die alte Idee zu verwerfen und zur neuen Idee überzugehen.

Spezifischer für TDD gibt es eine Technik, die verhindert, dass Ihnen dies passiert, wenn Sie Funktionen unter TDD hinzufügen. Es ist die Prämisse der Transformationspriorität . Wenn TDD eine formale Möglichkeit zum Umgestalten bietet, können Sie auf diese Weise Funktionen formell hinzufügen.

kandierte_orange
quelle
13

In seiner Antwort hat @Sklivvz überzeugend argumentiert, dass das Problem nicht besteht.

Ich möchte argumentieren, dass es keine Rolle spielt: Die Grundvoraussetzung (und das Grundprinzip) von iterativen Methoden im Allgemeinen und von Agile und insbesondere von TDD im Besonderen ist, dass nicht nur das globale Optimum, sondern auch die lokalen Optimalwerte vorhanden sind. ' nicht bekannt. Mit anderen Worten: Auch wenn das ein Problem war, gibt es sowieso keinen Weg, es iterativ zu machen. Angenommen, Sie akzeptieren die Grundvoraussetzung.

Jörg W. Mittag
quelle
8

Können TDD- und Agile-Verfahren eine optimale Lösung versprechen? (Oder sogar eine "gute" Lösung?)

Nicht genau. Aber das ist nicht ihr Zweck.

Diese Methoden bieten lediglich einen "sicheren Übergang" von einem Zustand in einen anderen, wobei anerkannt wird, dass Änderungen zeitaufwändig, schwierig und riskant sind. Beide Vorgehensweisen zielen darauf ab, sicherzustellen, dass die Anwendung und der Code funktionsfähig sind und nachweislich die Anforderungen schneller und regelmäßiger erfüllen.

... [TDD] lehnt die Softwareentwicklung ab, mit der Software hinzugefügt werden kann, die nachweislich nicht den Anforderungen entspricht ... Kent Beck, dem zugeschrieben wird, dass er die Technik entwickelt oder "wiederentdeckt" hat, erklärte 2003, dass TDD simple fördert entwirft und schafft Vertrauen. ( Wikipedia )

TDD konzentriert sich darauf, sicherzustellen, dass jeder Codeabschnitt die Anforderungen erfüllt. Insbesondere wird sichergestellt, dass der Code den bereits bestehenden Anforderungen entspricht, anstatt dass die Anforderungen durch eine schlechte Codierung bestimmt werden. Es gibt jedoch kein Versprechen, dass die Implementierung in irgendeiner Weise "optimal" ist.

Wie bei agilen Prozessen:

Arbeitssoftware ist das primäre Maß für den Fortschritt ... Am Ende jeder Iteration überprüfen die Stakeholder und der Kundenvertreter den Fortschritt und bewerten die Prioritäten neu, um die Kapitalrendite zu optimieren ( Wikipedia )

Beweglichkeit sucht nicht nach einer optimalen Lösung ; Nur eine funktionierende Lösung - mit der Absicht, den ROI zu optimieren . Es verspricht eher früher als später eine funktionierende Lösung ; kein "optimaler".

Aber das ist in Ordnung, denn die Frage ist falsch.

Optimale Werte in der Softwareentwicklung sind unscharfe, sich bewegende Ziele. Die Anforderungen sind in der Regel im Fluss und voller Geheimnisse, die nur zu Ihrer großen Verlegenheit in einem Konferenzraum mit vielen Vorgesetzten Ihres Chefs auftauchen. Und die "eigentliche Güte" der Architektur und Codierung einer Lösung wird durch die geteilten und subjektiven Meinungen Ihrer Kollegen und derjenigen Ihres Manager-Overlords bewertet - von denen möglicherweise keiner etwas über gute Software weiß.

TDD- und Agile-Praktiken erkennen zumindest die Schwierigkeiten an und versuchen, zwei Dinge zu optimieren, die objektiv und messbar sind: Arbeiten gegen Nichtarbeiten und Früher gegen Später.

Und selbst wenn wir "arbeiten" und "früher" als objektive Metriken haben, hängt Ihre Fähigkeit zur Optimierung in erster Linie von den Fähigkeiten und der Erfahrung eines Teams ab.


Zu den Dingen, die Sie als Bemühungen zur Erzielung optimaler Lösungen auffassen könnten , gehören:

etc..

Ob aus all diesen Dingen tatsächlich optimale Lösungen hervorgehen, wäre eine weitere wichtige Frage!

Svidgen
quelle
1
Es stimmt, aber ich habe nicht geschrieben, dass das Ziel von TDD oder einer anderen Softwareentwicklungsmethode eine optimale Lösung im Sinne eines globalen Optimums ist. Meine einzige Sorge ist, dass Methoden, die auf kleinen Iterationen auf Quellcodeebene basieren, in vielen Fällen keine akzeptable (ausreichend gute) Lösung finden könnten
Frank Puffer
@Frank Meine Antwort soll sowohl das lokale als auch das globale Optimum abdecken. Und die Antwort lautet wie auch immer: "Nein, dafür sind diese Strategien nicht konzipiert - sie sollen den ROI verbessern und das Risiko mindern." ... oder etwas ähnliches. Und das liegt auch daran, worauf Jörg antwortet: Die "Optimalwerte" sind bewegliche Ziele. Ich würde sogar noch einen Schritt weiter gehen. Sie bewegen nicht nur Ziele, sondern sind auch nicht ganz objektiv oder messbar.
Svidgen
@FrankPuffer Vielleicht ist es ein Nachtrag wert. Der grundlegende Punkt ist jedoch, dass Sie sich fragen, ob diese beiden Dinge etwas bewirken, das sie überhaupt nicht beabsichtigt oder geplant haben. Sie fragen sich, ob sie etwas erreichen können, das nicht einmal gemessen oder verifiziert werden kann.
Svidgen
@FrankPuffer Bah. Ich habe versucht, meine Antwort zu aktualisieren, um sie besser auszudrücken. Ich bin nicht sicher, ob ich es besser oder schlechter gemacht habe! ... Aber ich muss SE.SE verlassen und mich wieder an die Arbeit machen.
Svidgen
Diese Antwort ist in Ordnung, aber das Problem, das ich damit habe (wie bei einigen anderen Antworten), ist, dass "Risikominderung und Verbesserung des ROI" nicht immer die besten Ziele sind. Sie sind in der Tat keine wirklichen Ziele für sich. Wenn Sie etwas brauchen, um zu arbeiten, wird die Risikominimierung nicht schaden. Manchmal funktionieren relativ ungerichtete kleine Schritte wie bei TDD nicht - Sie minimieren das Risiko in Ordnung, erreichen aber am Ende nichts Nützliches.
Andres F.
4

Was bisher noch niemand hinzugefügt hat, ist, dass die von Ihnen beschriebene "TDD-Entwicklung" sehr abstrakt und unrealistisch ist. In einer mathematischen Anwendung, in der Sie einen Algorithmus optimieren, mag dies ähnlich sein, in den Geschäftsanwendungen, an denen die meisten Programmierer arbeiten, passiert dies jedoch nicht häufig.

In der realen Welt werden bei Ihren Tests im Wesentlichen Geschäftsregeln ausgeführt und validiert:

Zum Beispiel - Wenn ein Kunde ein 30-jähriger Nichtraucher mit einer Frau und zwei Kindern ist, lautet die Premium-Kategorie "x" usw.

Sie werden die Premium-Berechnungs-Engine erst dann iterativ ändern, wenn sie sehr lange korrekt ist - und mit ziemlicher Sicherheit nicht, wenn die Anwendung aktiv ist;).

Was Sie tatsächlich erstellt haben, ist ein Sicherheitsnetz, damit beim Hinzufügen einer neuen Berechnungsmethode für eine bestimmte Kundenkategorie nicht plötzlich alle alten Regeln brechen und die falsche Antwort geben. Das Sicherheitsnetz ist noch nützlicher, wenn der erste Schritt des Debuggens darin besteht, einen Test (oder eine Reihe von Tests) zu erstellen, der den Fehler reproduziert, bevor der Code zur Behebung des Fehlers geschrieben wird. Dann, ein Jahr später, bricht der Unit-Test ab, wenn jemand versehentlich den ursprünglichen Fehler wieder herstellt, bevor der Code überhaupt eingecheckt wurde Aber es sollte kein massiver Teil Ihres Jobs sein.

mcottle
quelle
1
Als ich Ihre Antwort las, dachte ich zuerst "Ja, das ist der Kernpunkt". Aber nachdem ich die Frage noch einmal überlegt hatte, dachte ich, dass sie nicht unbedingt so abstrakt oder unrealistisch ist. Wenn man blind die völlig falsche Architektur auswählt, löst TDD das nicht, nicht nach 1000 Iterationen.
Doc Brown
@ Doc Brown Einverstanden, es wird dieses Problem nicht lösen. Sie erhalten jedoch eine Reihe von Tests, die alle Annahmen und Geschäftsregeln erfüllen, damit Sie die Architektur iterativ verbessern können. Eine Architektur, die so schlecht ist, dass sie von Grund auf neu geschrieben werden muss, ist sehr selten (ich hoffe), und selbst in diesem extremen Fall wären die Business-Rule-Unit-Tests ein guter Ausgangspunkt.
Mcottle
Wenn ich "falsche Architektur" sage, habe ich Fälle im Sinn, in denen man die vorhandene Testsuite wegwerfen muss. Hast du meine Antwort gelesen?
Doc Brown
@ DocBrown - Ja, ich habe. Wenn Sie "falsche Architektur" als "Änderung der gesamten Testsuite" bezeichneten, hätten Sie das vielleicht sagen sollen. Das Ändern der Architektur bedeutet nicht, dass Sie alle Tests verwerfen müssen, wenn sie auf Geschäftsregeln basieren. Sie müssen wahrscheinlich alle ändern, um alle neu erstellten Schnittstellen zu unterstützen und einige sogar vollständig neu zu schreiben. Die Geschäftsregeln werden jedoch nicht durch eine technische Änderung ersetzt, sodass die Tests erhalten bleiben. Eine Investition in Unit-Tests sollte nicht durch die unwahrscheinliche Möglichkeit, die Architektur vollständig zu verbessern, zunichte gemacht werden
mcottle
Selbst wenn man jeden Test in einer neuen Programmiersprache neu schreiben muss, muss man nicht alles wegwerfen, zumindest kann man die vorhandene Logik portieren. Und ich stimme Ihnen zu 100% für die großen realen Projekte zu, die Annahmen in dieser Frage sind ziemlich unrealistisch.
Doc Brown
3

Ich glaube nicht, dass es im Weg steht. Die meisten Teams haben niemanden, der in der Lage ist, eine optimale Lösung zu finden, selbst wenn Sie diese auf ihr Whiteboard geschrieben haben. TDD / Agile werden ihnen nicht in die Quere kommen.

Viele Projekte erfordern keine optimalen Lösungen, und diejenigen, die dies tun, werden die notwendige Zeit, Energie und Konzentration in diesem Bereich aufbringen. Wie alles andere neigen wir dazu, es zuerst zum Laufen zu bringen. Dann mach es schnell. Sie könnten dies mit einer Art Prototyp tun, wenn die Leistung so wichtig ist, und dann das Ganze mit der Weisheit, die durch viele Iterationen gewonnen wurde, neu aufbauen.

Ich denke an ein Szenario, in dem Sie eine Reihe von Testfällen implementiert haben und dann feststellen, dass der nächste Testfall einen kompetent anderen Ansatz erfordert. Sie müssen Ihre bisherige Arbeit wegwerfen und von vorne beginnen.

Dies könnte passieren, aber was wahrscheinlicher ist, ist die Angst, komplexe Teile der Anwendung zu ändern. Keine Tests zu haben, kann ein größeres Gefühl der Angst in diesem Bereich hervorrufen. Ein Vorteil von TDD und einer Reihe von Tests besteht darin, dass Sie dieses System mit der Vorstellung erstellt haben, dass es geändert werden muss. Wenn Sie von Anfang an auf diese monolithisch optimierte Lösung kommen, kann es sehr schwierig sein, sie zu ändern.

Stellen Sie dies auch in den Zusammenhang mit Ihrer Sorge um Unteroptimierung, und Sie müssen Zeit darauf verwenden, Dinge zu optimieren, die Sie nicht haben sollten, und unflexible Lösungen zu entwickeln, weil Sie sich so sehr auf deren Leistung konzentriert haben.

JeffO
quelle
0

Es kann trügerisch sein, mathematische Konzepte wie "lokales Optimum" auf das Software-Design anzuwenden. Mit solchen Begriffen klingt Softwareentwicklung viel quantifizierbarer und wissenschaftlicher als es wirklich ist. Selbst wenn es für Code ein "Optimum" gab, haben wir keine Möglichkeit, es zu messen und können daher nicht wissen, ob wir es erreicht haben.

Die agile Bewegung war wirklich eine Reaktion gegen den Glauben, dass Softwareentwicklung mit mathematischen Methoden geplant und vorhergesagt werden könnte. Softwareentwicklung ist eher ein Handwerk als eine Wissenschaft.

JacquesB
quelle
Aber war es eine zu starke Reaktion? Es hilft sicherlich in vielen Fällen, in denen sich strikte Vorausplanung als unhandlich und kostspielig erwiesen hat. Einige Softwareprobleme müssen jedoch als mathematisches Problem und mit vorausschauendem Design angegangen werden. Sie können sie nicht TDD. Sie können die Benutzeroberfläche und das allgemeine Design von Photoshop TDD, die Algorithmen jedoch nicht TDD. Sie sind keine trivialen Beispiele wie die Ableitung von "Summe" oder "Doppel" oder "Potenz" in typischen TDD-Beispielen [1]. Sie können einen neuen Bildfilter wahrscheinlich nicht testen, wenn Sie einige Testszenarien schreiben. Sie müssen sich unbedingt hinsetzen und Formeln schreiben und verstehen.
Andres F.
2
[1] Tatsächlich bin ich mir ziemlich sicher fibonacci, dass das , was ich als TDD-Beispiel / Tutorial gesehen habe, mehr oder weniger eine Lüge ist. Ich bin bereit zu wetten, dass niemand jemals Fibonacci oder eine ähnliche Serie durch TDD entdeckt hat. Jeder beginnt damit, Fibonacci bereits zu kennen, was betrügt. Wenn Sie versuchen, dies durch TDD zu entdecken, erreichen Sie wahrscheinlich die Sackgasse, nach der das OP gefragt hat: Sie können die Reihe niemals verallgemeinern, indem Sie einfach mehr Tests und Refactoring schreiben - Sie müssen mathematisch vorgehen Argumentation!
Andres F.
Zwei Bemerkungen: (1) Sie haben Recht, dass dies täuschen kann. Aber ich habe nicht geschrieben, dass TDD das Gleiche ist wie mathematische Optimierung. Ich habe es nur als Analogie oder Modell benutzt. Ich glaube, dass Mathematik auf fast alles angewendet werden kann (und sollte), solange Sie sich der Unterschiede zwischen dem Modell und der Realität bewusst sind. (2) Wissenschaft (wissenschaftliches Arbeiten) ist in der Regel noch weniger vorhersehbar als Softwareentwicklung. Und ich würde sogar sagen, dass Software Engineering eher wie wissenschaftliches Arbeiten als wie ein Handwerk ist. Handwerk erfordert in der Regel viel mehr Routinearbeit.
Frank Puffer
@AndresF .: TDD bedeutet nicht, dass Sie nicht denken oder entwerfen müssen. Es bedeutet nur, dass Sie den Test schreiben, bevor Sie die Implementierung schreiben. Sie können das mit Algorithmen tun.
JacquesB
@FrankPuffer: OK, welcher messbare Wert hat ein "lokales Optimum" in der Softwareentwicklung?
JacquesB