Frage

Eines der häufigsten Argumente, die ich höre für nicht zu den anhaftenden SOLID Prinzipien in objekt- orientiertes Design ist YAGNI (obwohl die arguer oft nicht nennen es das):

"Es ist OK, dass ich beiden Features X und Y-Funktion in die gleiche Klasse setzen. Es ist so, warum einfach die Mühe, eine neue Klasse hinzugefügt (das heißt Komplexität)."

„Ja, ich kann alle Logik meines Geschäfts legt direkt in den GUI-Code ist es viel einfacher und schneller. Das wird immer die einzige GUI und es ist höchst unwahrscheinlich, dass wesentliche neue Anforderungen immer in werden kommen.“

„Wenn in dem unwahrscheinlichen Fall von neuen Anforderungen meines Code zu unübersichtlich wird noch ich für die neue Anforderung Refactoring kann. So Ihr‚Was ist, wenn Sie später brauchen, um ...‘Argument zählt nicht.“

Was wäre Ihr überzeugendsten Argumente gegen eine solche Praxis sein? Wie kann ich wirklich zeigen , dass dies eine teure Praxis ist, vor allem für jemanden, der nicht zu viel Erfahrung in der Softwareentwicklung hat.

War es hilfreich?

Lösung

Entwurf ist das Management und die Balance von Kompromissen YAGNI und SOLID sind widersprüchlich nicht. Erstere sagt , wenn Funktionen hinzufügen, letztere sagt wie, , aber sie sowohl den Design-Prozess führen. Meine Antworten, unten, für jede Ihrer spezifischen Anführungszeichen Prinzipien von beiden YAGNI und SOLID.

  
      
  1. Es ist dreimal so schwer wiederverwendbare Komponenten wie den einmaligen Gebrauch zu bauen   Komponenten.
  2.   
  3. Eine wiederverwendbare Komponente sollte in drei verschiedenen ausprobiert werden   Anwendungen, bevor es allgemein genug sein, um in eine Wiederverwendung zu akzeptieren   Bibliothek.
  4.   
     

- Robert Glass' Rules of Three , Fakten und Irrtümer des Software Engineering

Refactoring in wiederverwendbare Komponenten hat das Schlüsselelement der ersten den gleichen Zweck an mehreren Stellen zu finden, und und es bewegen. In diesem Zusammenhang gilt YAGNI durch diesen Zweck inlining, wo nötig, ohne sich um mögliche Doppel sich Gedanken, statt mit Generika oder wiederverwendbare Funktionen (Klassen und Funktionen).

Der beste Weg, in dem ursprünglichen Entwurf, um zu zeigen, wenn YAGNI gilt nicht konkrete Anforderungen zu identifizieren. Mit anderen Worten: hat einige Refactoring, bevor das Schreiben von Code , dass Doppelarbeit zu zeigen, ist nicht nur möglich, sondern bereits vorhanden ist. Dies rechtfertigt der zusätzliche Aufwand


  

Ja, ich kann all meine Business-Logik setzt direkt in den GUI-Code es viel einfacher und schneller ist. Dies wird immer die einzige GUI sein und es ist höchst unwahrscheinlich, dass signifcant neue Anforderungen werden immer kommen.

Ist es wirklich die einzige Benutzeroberfläche? Gibt es einen Hintergrund Batch-Modus geplant? Wird es jemals eine Web-Schnittstelle sein?

Was ist Ihr Testplan, und Sie werden ohne GUI Back-End-Funktionalität testen? Was wird die GUI einfach für Sie zu Test machen, da Sie in der Regel nicht an Ihrem Projekt außerhalb Code (wie Plattform-generic GUI-Controls) und stattdessen Konzentrat zu testen wollen.

  

Es ist OK, dass ich beiden Features X setzen und Funktion Y in die gleiche Klasse. Es ist so, warum einfach die Mühe, eine neue Klasse hinzugefügt (das heißt Komplexität).

Können Sie einen häufigen Fehler weisen darauf hin, dass der Bedarf vermieden werden? Manche Dinge sind einfach genug, wie eine Zahl (x * x vs squared(x)) für ein übermäßig einfaches Beispiel quadriert, aber wenn man einen konkreten Fehler jemand kann darauf hinweisen konfektionierte vor allem in Ihrem Projekt oder von denen auf Ihrem Team Sie können zeigen, wie eine gemeinsame Klasse oder Funktion wird in Zukunft vermeiden, dass.

  

Wenn in dem unwahrscheinlichen Fall von neuen Anforderungen, wird mein Code zu überladen Ich kann immer noch für die neue Anforderung Refactoring. Also Ihr „Was ist, wenn Sie später brauchen, um ...“ Argument zählt nicht.

Das Problem hier ist die Annahme von „unwahrscheinlich“. Stimmen Sie zu, es ist unwahrscheinlich? Wenn ja, sind Sie mit dieser Person zustimmend. Wenn nicht, ist Ihre Vorstellung von der Gestaltung nicht einverstanden mit dieser Person im-Lösung, dass Diskrepanz wird das Problem lösen oder zumindest zeigen Ihnen, wo als nächstes gehen. :)

Andere Tipps

Es klingt wie Sie mit einer Mauer sind streiten. Ich bin ein großer Fan von YAGNI, aber zugleich, erwarte ich auch, dass mein Code immer in mindestens zwei Stellen verwendet werden: die Anwendung, und die Tests. Deshalb Dinge wie Business-Logik in UI-Code nicht funktionieren; Sie können unter diesen Umständen nicht Test von UI-Code trennen Geschäftslogik.

Doch aus den Antworten die Sie beschreiben, klingt es wie die Person einfach dabei bessere Arbeit desinteressiert ist. An diesem Punkt wird kein Prinzip gehen, ihnen zu helfen; sie wollen nur das Minimum zu tun. Ich würde sogar so weit gehen zu sagen, dass es nicht YAGNI ihre Aktionen fahren, sondern Faulheit, und Sie allein sind nicht zu schlagen Faulheit (fast nichts, außer einem bedrohlichen Manager oder der Verlust des Arbeitsplatzes).

Ich mag über YAGNI in Bezug auf denken, "die Hälfte, nicht halbherzig", die Phrase von 37signals zu leihen ( https://gettingreal.37signals.com/ch05_Half_Not_Half_Assed.php ). Es geht um Ihre Reichweite zu begrenzen, so dass Sie auf dem Handeln die wichtigsten Dinge gut konzentrieren können. Es ist keine Entschuldigung schlampig zu bekommen.

Die Geschäftslogik in der GUI kommt mir halbherzig. Wenn Ihr System nicht trivial ist, würde ich überrascht sein, wenn Ihre Geschäftslogik und GUI nicht bereits unabhängig geändert, mehrfach. So können Sie die SRP ( "S" in SOLID) und refactor folgen sollte -. YAGNI gilt nicht, weil Sie es schon brauchen

Das Argument YAGNI und unnötige Komplexität gilt absolut, wenn Sie heute zusätzliche Arbeit sind hypothetische zukünftige Anforderungen gerecht zu werden. Wenn diejenigen, „was ist, wenn später müssen wir ...“ Szenarien ausbleiben, sind Sie stecken mit höheren Wartungskosten von den Abstraktionen, die Sie tatsächlich haben in der Art und Weise der Veränderungen bekommen. In diesem Fall sprechen wir über das Design zu vereinfachen, indem Umfang zu begrenzen -. Hälfte tun, anstatt halbherzig

Es gibt keine Antwort, oder besser gesagt, es gibt eine Antwort weder Sie noch Ihr Gesprächspartner könnte:. Sowohl YAGNI und SOLID können falsche Ansätze sein

Der Versuch, für SOLID mit einem unerfahrenen Team zu gehen, oder einem Team mit kurzen Lieferzielen ziemlich garantieren Sie mit einer teueren, over-engineered Reihe von Code werden am Ende ..., die nicht solide sein, nur overengineered (willkommen aka zur realen Welt).

Der Versuch YAGNI für ein langfristiges Projekt zu gehen und hoffen, dass Sie Refactoring können später nur in einem Umfang funktioniert (gern gesehen aka der realen Welt). YAGNI zeichnet sich bei der Proof-of-Konzepte und Demonstratoren, immer den Markt / Vertrag und dann in der Lage sein, investieren in etwas fester.

Sie müssen beide an verschiedenen Punkten in der Zeit.

Die korrekte Anwendung dieser Grundsätze ist oft nicht sehr offensichtlich und hängt sehr stark von Erfahrung. Welches ist schwer zu bekommen, wenn Sie es nicht selbst getan haben. Jeder Programmierer sollte falsch, es zu tun Erfahrungen der Folgen gehabt haben, aber natürlich sollte es immer sein „nicht mein“ Projekt.

Erklären Sie ihnen, was das Problem ist, wenn sie nicht hören und du bist nicht in der Lage, sie hören zu machen, lassen sie die Fehler machen. Wenn Sie zu oft derjenige sind, das das Problem zu beheben, sollten Sie Ihren Lebenslauf polieren.

Nach meiner Erfahrung ist es immer eine Ermessenssache. Ja, Sie sollten sich keine Sorgen über jedes Detail Ihrer Implementierung, und manchmal ein Verfahren in eine bestehende Klasse kleben ist eine akzeptable, wenn auch hässliche Lösung.

Es ist wahr, dass Sie später Refactoring können. Der wichtige Punkt ist eigentlich tun, um das Refactoring . Deshalb glaube ich, das eigentliche Problem nicht die gelegentliche Design Kompromiss, aber Refactoring aufzuschieben, wenn klar wird, dass es ein Problem. Eigentlich geht mit ihm durch den harten Teil (wie bei vielen Dingen im Leben ...).

In Bezug auf Ihre individuellen Punkte:

  

Es ist OK, dass ich beide Feature X setzen   und verfügen über Y in der gleichen Klasse. Es   warum ist so einfach Mühe ein neues Hinzufügen   Klasse (das heißt Komplexität).

Ich mag darauf hinweisen, dass in einer Klasse alles mit ist komplexe (weil die Beziehung zwischen den Methoden ist intimer und schwerer zu verstehen). viele kleine Klassen zu haben, ist nicht komplex. Wenn Sie die Liste fühlen zu lange wird immer, organisieren sie nur in Paketen, und alles wird gut :-). Persönlich habe ich festgestellt, dass nur Splitting eine Klasse in zwei oder drei Klassen viel mit Lesbarkeit helfen können, ohne weitere Änderung.

Haben Sie keine Angst vor kleinen Klassen nicht, sie beißen nicht; -).

  

Ja, ich kann alle meine Business-Logik setzen   direkt in den GUI-Code ist es viel   einfacher und schneller. Dies wird immer   die einzige GUI und es ist sehr   unwahrscheinlich, dass signifcant neue   Anforderungen werden immer kommen.

Wenn jemand kann sagen: „Es ist höchst unwahrscheinlich, dass signifcant neue Anforderungen werden immer kommen.“ mit ernstem Gesicht, ich glaube, dass Person wirklich, wirklich einen Reality-Check muss. Stumpf, aber sanft ...

  

Wenn in dem unwahrscheinlichen Fall neue   Anforderungen meinen Code zu bekommt   Überfüllte Ich kann immer noch für das Refactoring   neue Anforderung. Also Ihr ‚Was ist, wenn Sie   später Notwendigkeit, ...‘Argument nicht   count

Das hat einen gewissen Wert, aber nur, wenn sie tatsächlich refactor später tun. So akzeptieren sie und halten sie ihr Versprechen: -).

SOLID Prinzipien erlauben, dass Software auf Veränderungen anzupassen - in beiden Anforderungen und techical Veränderungen (neue Komponenten, usw.), zwei Ihrer Argumente für unveränderliche Anforderungen:

  • „Es ist höchst unwahrscheinlich, dass signifcant neue Anforderungen immer in werden kommen.“
  • "Wenn in dem unwahrscheinlichen Fall von neuen Anforderungen"

Könnte das wirklich wahr sein?

Es gibt keinen Ersatz für Erfahrung, wenn es um die verschiedenen Ausgaben der Entwicklung kommt. Für viele Praktiker denke ich, die Dinge in den lausigen tun, schwierig zu warten Weise noch nie für sie in Problemen geführt (hey! Arbeitsplatzsicherheit). Langfristig ein Produktes denke ich, diese Kosten deutlich worden, sondern um sie vor der Zeit ist jemand andere Arbeit, etwas zu tun.

Es gibt einige andere tolle Antworten hier.

Verständlich, flexibel und in der Lage Korrekturen und Verbesserungen sind immer Dinge, die Sie sind zu müssen gehen. Tatsächlich geht davon aus YAGNI, dass Sie zurückkommen können und neue Funktionen hinzufügen, wenn sie mit relativer Leichtigkeit als notwendig erweisen, weil niemand etwas verrückt wie bunging irrelevant Funktionalität in einer Klasse (YAGNI in dieser Klasse!) Tun wird oder Business-Logik UI-Logik drückt .

kann es vorkommen, dass was scheint verrückt war jetzt vernünftig in der Vergangenheit - manchmal ist die Grenzlinien von UI vs Unternehmen oder zwischen verschiedenen Arten von Aufgaben, die in einer anderen Klasse sein sollen, sind nicht so klar, oder sogar bewegen. Es kann vorkommen, wenn 3 Stunden Arbeit in 2 Stunden Zeit unbedingt notwendig sind. Es gibt Zeiten, wenn die Leute einfach nicht die richtige Entscheidung treffen. Aus diesen Gründen gelegentlich Pausen in dieser Hinsicht passieren wird, aber sie gehen in die Quere kommen, die YAGNI Prinzip der Verwendung, nicht eine Ursache davon sein.

Qualitäts Unit-Tests, und ich meine Unit-Tests nicht Integrationstests, müssen Code, hält sich an SOLID. Nicht unbedingt 100%, in der Tat selten so, aber in Ihrem Beispiel zu stopfen zwei Funktionen in eine Klasse wird Unit-Tests härter machen, bricht das einzige Verantwortung Prinzip und Code-Wartung macht von Team Neulingen viel schwieriger (wie es ist viel schwieriger zu verstehen) .

Mit den Unit-Tests (gut Codeabdeckung vorausgesetzt) ??Sie Refactoring-Funktion 1 sicher können und sichern Sie Feature nicht brechen 2, jedoch ohne Unit-Tests und mit den Merkmalen in derselben Klasse (einfach faul in sein Ihr Beispiel) Refactoring ist riskant bestenfalls katastrophal am besten.

Fazit: folgt dem KIS Prinzip (Keep it simple) oder für das intellektuelle das KISS-Prinzip (kis dumm). Nehmen Sie jeden Fall auf Verdienst, gibt es keine globale Antwort, aber immer bedenken, wenn andere Programmierer lesen müssen / halten Sie den Code in der Zukunft und den Nutzen von Unit-Tests in jedem Szenario.

TLDR;

SOLID geht davon aus, Sie verstehen (etwas atleast), die zukünftigen Änderungen am Code, WRT SRP. Ich werde sagen, dass wird optimistisch Fähigkeit zur Vorhersage. YAGNI auf der anderen Seite nimmt die meiste Zeit Sie wissen nicht, zukünftige Richtung der Veränderung, die über eine Fähigkeit pessimistisch zu prognostizieren.

Daraus folgt, dass SOLID / SRP Sie fragt Klassen für den Code zu bilden, so dass es einzigen Grund für den Wandel hat. Z.B. eine kleine GUI Änderung oder Servicecall ändern.

YAGNI sagt (wenn Sie erzwingen möchten wenden Sie es in diesem Szenario), da Sie nicht wissen, was zu ändern wird, und wenn eine GUI-Änderung eine GUI + Servicecall Änderung verursacht (ähnlich Eine Änderung Backend verursacht GUI + SeviceCall ändern), setzen Sie einfach alle, dass Code in einzelnen Klasse.

Lange Antwort:

Lesen Sie das Buch 'Agile Softwareentwicklung, Grundsätze, Muster und Praktiken'

Ich stelle kurzen Auszug aus es über SOLID / SRP: „Wenn [...] die Anwendung nicht ändert in einer Weise, die beiden Aufgaben zu ändern zu unterschiedlichen Zeiten führen, gibt es keine Notwendigkeit, sie zu trennen. In der Tat, trennt sie von unnötiger Komplexität riechen würden.

Es gibt eine corrolary hier. Eine Achse des Wandels ist eine Achse der Änderung nur, wenn die Änderungen auftreten. Es ist ratsam, nicht SRP-oder anderes Prinzip anzuwenden, denn das ist selbst wenn es kein Symptom. "

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top