Ich arbeite an einem Softwareprojekt, in dem wir drei APIs erstellen müssen. Ein für den Heim- Banking - Kanal, eine für die Agentur Kanal und ein dritte für den mobilen Kanal.
Die Agentur-API ist die vollständigste, da sie alle Funktionen bietet. Dann die etwas kleinere Home-API und dann die mobile API.
Die Architekten haben hier eine gemeinsame Ebene erstellt (kanalübergreifende EJB-Services, 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 startete mit dem Agentur-Channel und wir passen ihn jetzt für den Home-Channel an. Wir bereichern nur Objekte speziell für unsere Home-App. Ansonsten ist der Code zwischen den APIs zu 95% ähnlich. Die APIs basieren auf Spring MVC und enthalten Controller, Modelle und einige Dienstprogramme.
Grundsätzlich machen die Controller das Mapping von BO zu ChannelObject (es scheint mir nicht der richtige Ort dafür zu sein) und einige zusätzliche Dienstprogramme und Serializer. Alles ist vorerst doppelt vorhanden. Sie sagen, dass der Grund für die Duplizierung ist, dass sie die APIs unabhängig wollen. "Wenn wir morgen ein anderes Verhalten für zu Hause als für die Agentur oder das Handy wollen, werden wir keine Probleme haben !!"
Gibt es einen Fall, in dem wir doppelten Code akzeptieren sollten?
Antworten:
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 im Moment identisch sind" ist kein guter Grund für eine Duplizierung in großem Maßstab. Dieser Begriff könnte für jedes System gelten und zur Rechtfertigung von Duplikaten herangezogen werden , was offensichtlich nicht zumutbar ist.
Vervielfältigung nur toleriert werden , wenn das Entfernen es wäre insgesamt teurer jetzt aus einem anderen Grunde (kann nicht von einem guten Augenblick, aber da kann man sicher sein , sein - praktisch alles , was in der Programmierung ist ein Kompromiss und nicht als Gesetz).
Für das, was Sie tun, könnte die richtige Lösung beispielsweise darin bestehen, das gerade duplizierte Verhalten in eine Strategie oder ein anderes Muster zu extrahieren, das das Verhalten als Klassen modelliert und dann drei Instanzen derselben Klasse verwendet. Auf diese Weise, wenn Sie tun das Verhalten in einer der drei Stellen ändern möchten, müssen Sie nur eine neue Strategie erstellen und instanziieren , dass an einem Ort. Auf diese Weise müssen Sie nur einige Klassen hinzufügen und den Rest der Codebasis nahezu unberührt lassen.
quelle
Sandi Metz, eine renommierte Softwareentwicklerin und Autorin im Ruby-Ökosystem, hat einen großartigen Blogbeitrag und einen Vortrag, in dem sie auch über die Beziehung zwischen Vervielfältigung und Abstraktion spricht. Sie kommt zu folgendem Schluss
Und ich stimme ihr vollkommen zu. Lassen Sie mich 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 beliebige Abstraktion zu wählen, um Doppelarbeit zu vermeiden. Aber später werden Sie vielleicht feststellen, dass Ihre Abstraktion nicht für alle Fälle gilt. Es ist jedoch kostspielig, alles noch einmal zu ändern und einen anderen Weg zu gehen (für eine weitaus bessere Erklärung sehen Sie sich ihr Gespräch an!).
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 derzeit viele Überschneidungen gibt, aber Ihre Kollegen schlagen vor, dass sich dies ändern könnte und nicht beide Anwendungen miteinander gekoppelt werden. Meiner Meinung nach ist dies ein gültiges Argument und kann im Allgemeinen nicht außer Acht gelassen werden.
quelle
Wenn die Leute mit den Worten "Wenn morgen" über Design nachdenken , ist dies oft ein großes Warnsignal für mich, besonders wenn das Argument verwendet wird, um eine Entscheidung zu rechtfertigen, die zusätzlichen Arbeitsaufwand beinhaltet, für den niemand wirklich weiß, ob dies jemals der Fall sein wird zahlen sich aus und was schwieriger zu ändern oder rückgängig zu machen ist als die gegenteilige Entscheidung.
Die Vervielfältigung von Code reduziert den Aufwand nur kurzfristig, erhöht jedoch den Wartungsaufwand fast sofort, proportional zur Anzahl der vervielfältigten Codezeilen. Beachten Sie auch, dass es nach dem Duplizieren des Codes schwierig wird, die Duplizierung zu entfernen, wenn sich herausstellt, dass dies die falsche Entscheidung war. Wenn Sie den Code jetzt nicht duplizieren, können Sie die Duplizierung später problemlos einführen, wenn Sie sich an DRY halten 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 das Entfernen der Duplizierung durch Extrahieren der zu 95% gemeinsamen Teile der APIs zwei einer neuen Komponente zu einer Kopplung von zwei ansonsten unabhängigen Teams führt, 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 es sicher in ihrem eigenen Interesse, keinen doppelten Aufwand zu betreiben und unnötige Code-Duplikationen zu vermeiden.
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 wird, eine Komponente zu schreiben, die auf den APIs aufbaut, die auch in einem "Home" -Kontext verwendet werden können wie in einem "Agentur" -Kontext. In diesem Fall wird die Entwicklung einer solchen Komponente wahrscheinlich viel einfacher, wenn die gemeinsamen Teile der APIs genau identisch sind (was nur garantiert werden kann, wenn die gemeinsamen Teile nicht dupliziert werden).
Wenn sich also herausstellt, dass es wirklich unterschiedliche Subteams gibt, die jeweils für die einzelnen APIs verantwortlich sind, jeweils einen anderen Zeitplan und andere Ressourcen haben, ist es an der Zeit, den Code zu duplizieren, aber nicht "nur für den Fall".
quelle
Vervielfältigung, um eine Kopplung zu verhindern . Nehmen wir an, Sie haben zwei große Systeme und zwingen sie, dieselbe Bibliothek zu verwenden. Möglicherweise koppeln Sie den Release-Zyklus beider Systeme. Das mag nicht so schlimm sein, aber sagen wir mal, 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 zu vielen Besprechungen kommen, die Manager, Tests, Abhängigkeiten und das Ende des kleinen autonomen Teams durchlaufen.
Sie zahlen also den Preis für duplizierten Code, um Autonomie und Unabhängigkeit zu erlangen.
quelle