it-swarm.com.de

Gibt es Ausnahmefälle, in denen wir doppelten Code akzeptieren können?

Ich arbeite an einem Softwareprojekt, bei dem wir drei APIs erstellen müssen. Eine für den Home Bankkanal, eine für den Agenturkanal und a dritter für den mobilen Kanal.

Die Agentur-API ist die vollständigste, da sie alle Funktionen bietet. Dann eine etwas kleinere Home-API und dann eine mobile API.

Die Architekten haben hier eine gemeinsame Schicht erstellt (kanalübergreifende EJB-Dienste, die von allen APIs gemeinsam genutzt werden). Aber dann sind die APIs anders.

Derzeit gibt es keinen großen Unterschied zwischen den APIs. Das große Team hat mit dem Agenturkanal begonnen und wir passen ihn jetzt für den Heimkanal an. Wir bereichern nur Objekte speziell für unsere Home-App. Andernfalls ist der Code zwischen den APIs zu 95% ähnlich. Die APIs bauen auf Spring MVC auf und verfügen über (Controller, Modelle und einige Dienstprogramme).

Grundsätzlich führen die Controller das Mapping BO zu ChannelObject durch (es scheint mir nicht der richtige Ort dafür zu sein) und einige zusätzliche Dienstprogramme und Serializer. Im Moment ist alles doppelt. Sie sagen, dass der Grund für die Duplizierung darin besteht, dass die APIs unabhängig sein sollen. "Wenn wir morgen ein anderes Verhalten für zu Hause wollen als für Agenturen oder Mobilgeräte, werden wir keine Probleme haben !!"

Gibt es einen Fall, in dem wir doppelten Code akzeptieren sollten?

57

Vervielfältigung kann das Richtige sein, aber nicht aus diesem Grund.

Die Aussage "Wir möchten möglicherweise, dass sich diese drei Stellen in der Codebasis unterschiedlich verhalten, obwohl sie derzeit identisch sind" ist kein guter Grund für eine groß angelegte Vervielfältigung. Dieser Begriff könnte für das System every gelten und zur Rechtfertigung der Vervielfältigung any verwendet werden, was offensichtlich nicht sinnvoll ist.

Eine Vervielfältigung sollte nur toleriert werden, wenn das Entfernen aus einem anderen Grund insgesamt teurer wäre jetzt (ich kann mir momentan keine gute vorstellen, aber seien Sie versichert, dass es eine geben kann - praktisch alles in Programmierung ist eher ein Kompromiss als ein Gesetz.

Für das, was Sie tun, könnte die richtige Lösung z. Extrahieren Sie das Verhalten, das gerade dupliziert wird, in eine Strategie oder ein anderes Muster, das das Verhalten als Klassen modelliert, und verwenden Sie dann drei Instanzen derselben Klasse. Auf diese Weise müssen Sie, wenn Sie do das Verhalten an einer der drei Stellen ändern möchten, nur eine neue Strategie erstellen und diese an einer Stelle instanziieren. Auf diese Weise müssen Sie nur einige Klassen hinzufügen und den Rest der Codebasis fast vollständig unberührt lassen.

70
Kilian Foth

Sandi Metz, eine renommierte Softwareentwicklerin und Autorin im Ruby Ökosystem), hat ein großartiges Blogpost und ein Talk , über das sie auch spricht die Beziehung zwischen Vervielfältigung und Abstraktion. Sie kommt zu folgendem Schluss

vervielfältigung ist weitaus billiger als die falsche Abstraktion

Und ich stimme ihr vollkommen zu. Lassen Sie mich Ihnen mehr Kontext zu diesem Zitat geben. Manchmal ist es sehr schwierig, die richtige Abstraktion zu finden. In solchen Fällen ist es verlockend, einfach eine Abstraktion zu wählen, um Doppelarbeit zu reduzieren. Später stellen Sie jedoch möglicherweise fest, dass Ihre Abstraktion nicht für alle Fälle gilt. Es ist jedoch kostspielig, alles wieder zu ändern und einen anderen Weg zu gehen (für eine weitaus bessere Erklärung sehen Sie zu, wie sie spricht!).

Ja, für mich gibt es Ausnahmefälle, in denen das Akzeptieren von Duplikaten die richtige Entscheidung ist, insbesondere wenn Sie sich nicht sicher sind, was kommen wird und sich die Anforderungen wahrscheinlich ändern werden. Aus Ihrem Beitrag gehe ich davon aus, dass es jetzt viele Überschneidungen gibt, aber Ihre Kollegen schlagen vor, dass sich dies ändern könnte und nicht beide Anwendungen miteinander zu koppeln. Meiner Meinung nach ist dies ein gültiges Argument und kann im Allgemeinen nicht außer Acht gelassen werden.

87
larsbe

Wenn Leute anfangen, über Design mit den Worten "wenn morgen" nachzudenken, ist dies oft ein großes Warnsignal für mich, insbesondere wenn das Argument verwendet wird, um eine Entscheidung zu rechtfertigen, die zusätzliche Arbeit und Mühe beinhaltet, für die Niemand weiß wirklich, ob sich dies jemals auszahlt und was schwieriger zu ändern oder rückgängig zu machen ist als die gegenteilige Entscheidung.

Das Duplizieren von Code reduziert den Aufwand nur für kurze Zeit, erhöht jedoch den Wartungsaufwand fast sofort, proportional zur Anzahl der duplizierten Codezeilen. Beachten Sie auch, dass es nach dem Duplizieren von Code schwierig wird, die Duplizierung zu entfernen, wenn sich herausstellt, dass dies die falsche Entscheidung war. Wenn Sie jetzt keinen Code duplizieren, ist es dennoch einfach, die Duplizierung später einzuführen, wenn sich herausstellt, dass Sie bei = bleiben DRY war die falsche Entscheidung.

In größeren Organisationen ist es manchmal vorteilhaft, die Unabhängigkeit verschiedener Teams gegenüber dem DRY -Prinzip) zu bevorzugen. Wenn die Duplizierung durch Extrahieren der 95% gemeinsamen Teile der APIs zwei entfernt wird, führt eine neue Komponente Bei einer Kopplung von zwei ansonsten unabhängigen Teams ist dies möglicherweise nicht die klügste Entscheidung. Wenn Sie jedoch nur über begrenzte Ressourcen verfügen und nur ein Team beide APIs verwaltet, liegt dies sicher in ihrem eigenen Interesse Erstellen Sie doppelte Anstrengungen und vermeiden Sie unnötige Codeduplizierungen.

Beachten Sie außerdem, dass es einen Unterschied macht, ob "Home" - und "Agency" -APIs ausschließlich von völlig unterschiedlichen Anwendungen verwendet werden oder ob versucht werden könnte, eine Komponente zu schreiben, die auf diesen APIs aufbaut, die auch in einem "Home" -Kontext verwendet werden können wie in einem "Agentur" -Kontext. In dieser Situation wird die Entwicklung einer solchen Komponente wahrscheinlich viel einfacher, wenn die gemeinsamen Teile der APIs genau identisch sind (was Sie nur garantieren können, wenn die gemeinsamen Teile nicht dupliziert werden).

Wenn sich herausstellt, dass es wirklich unterschiedliche Subteams gibt, die jeweils für die einzelnen APIs verantwortlich sind und jeweils einen anderen Zeitplan und unterschiedliche Ressourcen haben, ist es an der Zeit, den Code zu duplizieren, aber nicht "nur für den Fall".

34
Doc Brown

Vervielfältigung zur Verhinderung der Kopplung. Angenommen, Sie haben zwei große Systeme und zwingen sie, dieselbe Bibliothek zu verwenden. Möglicherweise koppeln Sie den Freigabezyklus beider Systeme. Das mag nicht schlecht sein, aber nehmen wir an, dass ein System eine Änderung einführen muss. Der andere muss die Änderung analysieren und kann betroffen sein. Manchmal kann es Dinge brechen. Selbst wenn beide Parteien in der Lage sind, die Änderungen zu koordinieren, kann es sich um viele Besprechungen handeln, die Manager, Tests, Abhängigkeiten und das Ende des kleinen autonomen Teams durchlaufen.

Sie zahlen also den Preis für doppelten Code, um Autonomie und Unabhängigkeit zu erlangen.

13
Borjab