it-swarm.com.de

Best Practices für die gemeinsame Nutzung winziger Codeausschnitte zwischen Projekten

Ich versuche immer, das TROCKENE Prinzip strikt bei der Arbeit zu befolgen; Jedes Mal, wenn ich Code aus Faulheit wiederholt habe, wird er später zurückgebissen, wenn ich diesen Code an zwei Stellen pflegen muss.

Aber oft schreibe ich kleine Methoden (vielleicht 10 - 15 Codezeilen), die in zwei Projekten wiederverwendet werden müssen, die können nicht aufeinander verweisen. Die Methode hat möglicherweise etwas mit Networking/Strings/MVVM usw. zu tun und ist eine allgemein nützliche Methode, die nicht spezifisch für das Projekt ist, in dem sie sich ursprünglich befindet.

Die Standardmethode zur Wiederverwendung dieses Codes besteht darin, ein unabhängiges Projekt für den wiederverwendbaren Code zu erstellen und bei Bedarf auf dieses Projekt zu verweisen. Das Problem dabei ist, dass wir in einem von zwei weniger als idealen Szenarien enden:

  1. Am Ende haben wir Dutzende/Hunderte winziger Projekte - jedes, um die kleinen Klassen/Methoden unterzubringen, die wir wiederverwenden mussten. Lohnt es sich, ein ganz neues .DLL nur für ein kleines bisschen Code?
  2. Am Ende haben wir ein einziges Projekt mit einer wachsenden Sammlung nicht verwandter Methoden und Klassen. Dieser Ansatz ist das, was ein Unternehmen getan hat, für das ich früher gearbeitet habe. Sie hatten ein Projekt namens base.common mit Ordnern für Dinge, die ich oben erwähnt habe: Netzwerk, String-Manipulation, MVVM usw. Es war unglaublich praktisch, aber das Verweisen darauf zog unnötigerweise den ganzen irrelevanten Code mit sich, den Sie nicht brauchten.

Meine Frage lautet also:

Wie geht ein Software-Team am besten vor, wenn kleine Code-Teile zwischen Projekten wiederverwendet werden?

Ich bin besonders interessiert, wenn jemand in einem Unternehmen gearbeitet hat, das Richtlinien in diesem Bereich hat, oder das persönlich auf dieses Dilemma gestoßen ist, wie ich es getan habe.


Hinweis: Meine Verwendung der Wörter "Projekt", "Lösung" und "Referenz" stammt aus einem Hintergrund in der .NET-Entwicklung in Visual Studio. Ich bin mir jedoch sicher, dass dieses Problem sprach- und plattformunabhängig ist.

103
George Powell

Wenn es sich wirklich um wiederverwendbare Methoden/Klassen handelt, können Sie sie in eine kleine Anzahl von 'Swiss Army Knife'-Bibliotheken schreiben. Wir machen das ziemlich oft in meiner Firma; Wir nennen sie Framework-Bibliotheken:

  • Framework.Data - Dienstprogramme zum Arbeiten mit Datenbankabfragen.
  • Framework.ESB - Standardmethoden für die Interaktion mit unserem Enterprise Service Bus
  • Framework.Logging - Einheitliches Protokollierungssystem
  • Framework.Services - Dienstprogramme für die Interaktion mit Webdiensten
  • Framework.Strings - Dienstprogramme für erweiterte String-Manipulation/Fuzzy-String-Suche usw.
  • ...

Insgesamt gibt es ungefähr ein Dutzend Bibliotheken. Sie können den Code wirklich verteilen, wie Sie es für richtig halten, sodass Sie nicht mit Hunderten enden oder alles in einer riesigen Assembly ablegen müssen. Ich finde, dieser Ansatz passt, weil nur einige unserer Projekte Framework.Data Und nur wenige jemals Framework.Strings Benötigen, sodass Verbraucher nur die Teile des Frameworks auswählen können, die für ihr bestimmtes Projekt relevant sind .

Wenn es sich wirklich nur um Snippets handelt und nicht um tatsächliche Methoden/Klassen, die leicht wiederverwendet werden können, können Sie versuchen, sie einfach als Code-Snippets in IDE (zB Visual Studio Code) zu verteilen) Snippets ). Teams, mit denen ich in der Vergangenheit zusammengearbeitet habe, hatten eine gemeinsame Snippet-Bibliothek, die es jedem leichter machte, unsere Standardcodierungspraktiken auch mit internem Code zu befolgen.

75
p.s.w.g

Ich bin aus vielen Gründen mit der akzeptierten Antwort nicht einverstanden.

Nach meiner Erfahrung sind "verschiedene" Bibliotheken wie die akzeptierte Antwort eine Ausrede für das Rad neu erfinden (oder hier nicht erfunden (NIH) ) - a weitaus größere Sünde als Verletzung Wiederhole dich nicht (TROCKEN) .

Manchmal kann ein Verstoß gegen DRY ein vernünftiger Kompromiss sein, es ist besser als die Einführung einer engen Kopplung. Die Wiederverwendung ist im Vergleich zu einem guten objektorientierten Design ein zweitrangiges Problem. Ein bisschen (ich meine kleine Menge, wende das - an Dreierregel ) der Vervielfältigung ist leichter zu verstehen als eine Spaghetti-Codebasis.

Der Ansatz zahlreicher Universalbibliotheken ist ein schlechtes Beispiel. Dies führt zu einer feinen Granularität der Baugruppe, und zu viele Baugruppen sind schlecht. Ich habe kürzlich eine interne von 24 Bibliotheken auf 6 Bibliotheken reduziert. Die Kompilierungszeit wurde von einigen Minuten auf ~ 20 Sekunden verbessert. Visual Studio ist außerdem langsamer zu laden und reagiert mit mehr Assemblys weniger schnell. Zu viele Bibliotheken führen auch zu Unklarheiten darüber, wo Code leben soll. bevorzugen weniger, einfachere Regeln.

Warum ist das Zeug im .Net Framework nicht gut genug? Das Framework ist ziemlich groß; Ich habe oft Code gesehen, der Dinge neu implementiert, die dort bereits vorhanden sind. Stellen Sie wirklich sicher, dass Ihre Frameworks Lücken im .Net-Framework füllen und nicht nur aus ästhetischen Gründen existieren (zum Beispiel "Ich mag das .Net-Framework hier nicht" oder vielleicht einige vorzeitige Optimierung )

Das Einführen einer weiteren Ebene in Ihre Architektur ist mit erheblichen Komplexitätskosten verbunden. Warum existiert die Schicht? Ich habe eine falsche Wiederverwendung gesehen. Damit meine ich, dass der Code auf einem internen Framework basiert. Es wäre weitaus effizienter gewesen, es direkt über Standardbibliotheken zu implementieren.

Die Verwendung standardisierter Technologien (wie das .Net-Framework und beliebte Open-Source-Bibliotheken von Drittanbietern) bietet Vorteile, die häufig die vergleichbaren technologischen Vorteile des Selbstaufbaus überwiegen. Es ist einfacher, Talente zu finden, die diese Technologien kennen, und Ihre vorhandenen Entwickler werden mehr in das Erlernen dieser Technologien investieren.

Meine Empfehlungen:

  • Teilen Sie diesen Code nicht.
  • Erstellen Sie eine neue Bibliothek, wenn sie einen zusammenhängenden Zweck hat. Verwenden Sie nicht das Ball of Mud-Entwurfsmuster .
  • Verwenden Sie vorhandene Bibliotheken von Drittanbietern nach Möglichkeit wieder.
  • Bevorzugen Sie weniger Assemblys mit einfacheren Regeln, wo Code leben soll.
21
Dave Hillier

Bei kleinen Codebits - beispielsweise einer einzelnen Klasse ohne Abhängigkeiten - kopieren wir den Code in der Regel einfach und fügen ihn in Projekte ein. Das klingt nach einer Verletzung von DRY, und ich gebe zu, dass es manchmal sein kann. Aber auf lange Sicht war es aus mehreren Gründen viel besser als ein massives, vielköpfiges Commons-Projekt.

Erstens ist es einfacher, den Code zur Hand zu haben, insbesondere beim Erstellen und Debuggen von Inhalten.

Zweitens möchten Sie ausnahmslos den allgemeinen Code für dieses Projekt ein wenig optimieren. Wenn Sie eine lokale Kopie der Quelle haben, können Sie einfach die Optimierung vornehmen und sie einen Tag lang aufrufen. Wenn es eine gemeinsam genutzte Bibliothek gibt, können Sie diese Bibliothek optimieren und dann sicherstellen, dass Sie nicht alle anderen Apps beschädigen oder einen Alptraum für die Versionierung erstellen.

Wenn es also nicht bullig genug für seinen eigenen Namespace ist, neigen wir dazu, es einfach in die entsprechenden Teile des Projekts zu verschieben und es als Tag zu bezeichnen.

11
Wyatt Barnett

Die zweite Lösung, die Sie beschreiben, ist nicht so schlecht. In .NET verweisen Sie auch auf eine Assembly aus dem GAC, selbst wenn Sie nur eine einzige Klasse davon verwenden. 'Irrelevanten Code ziehen' ist kein Problem, wie Sie vielleicht denken. In diesem Fall ist es wichtig, zumindest verwandte Methoden und Klassen in verschiedenen Namespaces sauber zu organisieren. Darüber hinaus sollten bewährte Methoden für das API-Design angewendet werden, um zu verhindern, dass diese Lösung zu einem Chaos wird.

Wenn es um sehr kleine Code-Teile geht, ist der folgende Ansatz meiner Meinung nach eine gute Ergänzung zu einem gemeinsamen Projekt: Ermöglichen Sie, dass sie in verschiedenen Lösungen dupliziert werden. Behandeln Sie sie wie Best Practices: Dokumentieren Sie sie und teilen Sie sie dem Team mit.

6
Theo Lenndorff

Ich habe bisher nur in "Unternehmens" -Umgebungen gearbeitet, in denen solche Probleme aufgetreten sind und jedes Mal die zweite Option gewählt wurde. Zum größten Teil hat es in Ordnung funktioniert, da der Anwendungs-Footprint nicht eingeschränkt wurde.

Nachdem ich die letzte Woche mit einem Start-up verbracht habe, das einen eigenen Nuget-Server betreibt, neige ich dazu, dies als praktikable Alternative vorzuschlagen. Natürlich werden die Probleme, die ich erwarten werde, die Entdeckbarkeit sein.

Wenn die Projekte angemessen detailliert sind und die Namespaces sinnvoll sind, kann ich sehen, dass dies stellenweise zu einem beliebten Ansatz wird.

6
Kofi Sarfo

Ich habe kürzlich darüber nachgedacht und mir fiel eine große Bibliothek gängiger Methoden ein, wie bisher erwähnt, aber mit einer Wendung. Mit dem Bibliotheksprojekt können Sie zur Kompilierungszeit konfigurieren, welche Teile ähnlich wie das BusyBox-Projekt enthalten sind. Mit diesem Ansatz können Sie ein Bibliotheks-Repo im Stil einer Küchenspüle erstellen, aber nur die Tools verwenden, die Sie beim Kompilieren benötigen.

6
Harvey

GitHub hat ein ziemlich nützliches Tool zum Speichern von Codefragmenten https://Gist.github.com/

Es speichert Ihre Snippets als Git-Repositorys, die Sie privat halten oder zum Teilen von Snippets mit anderen Personen verwenden können.

5
blacksh33p

Abhängig von der Größe des Teams/Projekts/Unternehmens ist dies ziemlich schwierig, es sei denn, es ist bereits in Ihre Umgebung integriert, und jede Lösung, die Sie finden (wenn Sie sie implementieren), kostet etwas Geld. (Es kann Sie mehr schützen, aber dass Sie nicht leicht messen können). Sie müssen überprüfen, ob es den Preis wert ist. Denken Sie auch daran, dass wiederverwendbare Lösungen tendenziell abstrakt werden und oft in viele Situationen passen, ohne jedoch optimal zu sein.

Wenn Sie dies für den Code tun möchten, der von mehr als einer Person erstellt wurde, müssen Sie zunächst alle kennen und zusammenarbeiten. Dies schließt Entwickler und Manager ein.

Dann müssen Sie sicherstellen, dass Sie den Umfang kennen, in dem Sie dies tun möchten. Mannschaft? Projekt? Abteilung? Unternehmen? Abhängig von der Antwort variiert die Art des Codes, den Sie in solche Lösungen einfügen, ebenso wie die Granularität, mit der Sie die DLLs anpassen. Sobald Sie sich für jemanden entschieden haben (vorzugsweise mit einer gewissen Begeisterung für die Idee - Sie?), Sollten Sie sich hinsetzen und anfangen, etwas Struktur in diese zu bringen.

Das Erstellen solcher DLLs reicht jedoch nicht aus, um den Trick auszuführen. Um sie nützlich zu machen, müssen Sie sie (für Benutzer und Mitwirkende) bewerben und wie jede andere Software warten. Dies bedeutet normalerweise, dass Sie jemanden für lange Zeit für sie verantwortlich machen müssen. Sie benötigen ebenfalls eine zuverlässige Dokumentation, die dann ebenfalls gewartet werden muss. Mit etwas Glück und Zusammenarbeit erhalten Sie möglicherweise einige Best Practices, die sich jedoch je nach Größe und Anzahl der beteiligten Teams leicht zu einem eigenen Projekt entwickeln können. Und dafür benötigen Sie noch Managementunterstützung.

3
Thomas

ich bin häufig auf Probleme gestoßen, und meine bevorzugte Lösung besteht darin, den Code in einem webfähigen Github/Pubic-Repository zu veröffentlichen. es löst viele Probleme -

  1. einfacher Zugriff und einfach zu teilen. cvs/svn/Enterprise-Repos bedeuten das Auschecken eines Projekts in mehrere IDE Arbeitsbereiche) und manchmal das Wechseln von Arbeitsbereichen oder Computern, um nur auf ein kleines Codefragment zu verweisen.
  2. unter der Annahme, dass diese Codefragmente keine proprietären/klassifizierten Codeteile sind und Variationen des öffentlich verfügbaren Wissens darstellen, bedeutet das Posten in einem öffentlichen Repo wie Github, dass andere sich das ansehen und möglicherweise sogar dazu beitragen.
  3. wenn Sie unter Ihrem Namen etwas gemeinfrei veröffentlichen, entsteht ein zusätzlicher Reputationsdruck. Sie werden die Dinge überprüfen und aktualisieren, da dies Ihre Fähigkeiten als Programmierer widerspiegelt.
  4. aktualisierung. Die Sache beim Verwalten von Code-Snippets in einem Repo ist, dass ein Snippet, wenn es lange Zeit nicht verwendet wurde, möglicherweise veraltet ist (veraltete apis/libs enthält). Beispiel - Java Code-Snippet zum Lesen einer Datei. Sie haben vielleicht 2009 herausgefunden, wie dies am besten funktioniert, aber 2014 erscheint eine neue Datei-API, die alles ändert. Ihr Snippet? In einem öffentlichen Repo werden die Dinge entweder von Ihnen (weil Punkt 3), Ihren Teamkollegen oder einem Mitglied der allgemeinen Programmiererpopulation aktualisiert, und dabei erhalten Sie möglicherweise sogar Vorschläge, um etwas zu reparieren, das Sie tun könnte schon lange falsch gemacht haben.

Eine Sache würde ich empfehlen - egal wo Sie Ihre Schnipsel aufbewahren, googeln Sie immer, bevor Sie sie verwenden. Dinge ändern sich ständig. gespeicherte Schnipsel sparen Zeit, aber auch Selbstzufriedenheit.

3
Quest Monger

Mein Unternehmen verwendet lokale Intranet-Webdienste. Wir haben einige Webdienste, die als allgemeine interne Webdienste eingerichtet sind. Wenn ein anderes Projekt Zugriff auf einen der Dienste benötigt, sendet es eine http-Anfrage mit einer definierten Schnittstelle. Da es sich im Intranet befindet, das sich in derselben Serverfarm befindet, sind diese Anforderungen sehr schnell.

Natürlich funktioniert dies nur mit Internet-Apps (und nur in Millisekunden, wenn Sie sich im selben lokalen Netzwerk befinden), aber es hat einige wirklich nette Vorteile.

2
Ben Lee

Wir haben ein separates Projekt "Dienstprogramme", in dem wir all diese kleinen Methoden zusammen mit Tests speichern.

Wenn ein Projekt ein Dienstprogramm benötigt, fügt es einfach die Quelldatei mit der erforderlichen Methode mit "Als Link hinzufügen" hinzu.

Dies bedeutet, dass keine Laufzeitabhängigkeiten hinzugefügt werden (es sei denn, die enthaltene Datei benötigt eine).

Das System hat gut funktioniert, aber wie alle anderen benötigt es eine Disziplin, was ein Dienstprogramm ist. Das Erfordernis einer hohen Testabdeckung hat für uns gut funktioniert, und Tests sind auch eine gute Dokumentation für die Verwendung. Entdeckung ist für uns immer noch ein ungelöstes Problem.

Eine Komplexität des Hilfsprojekts besteht darin, die Sichtbarkeitsstufe für Elemente zu bestimmen. Als Faustregel gilt, dass Methoden intern und Datenstrukturen öffentlich sein sollten.

2
adrianm

Ich habe mir kürzlich diesen Service ausgedacht: Snip2Code ( http://www.snip2code.com ).

Es ist eine interessante Möglichkeit, nur Ihre Snippets (nicht ausschließlich Bibliotheken) mit Ihrem Team zu teilen. Es bricht den üblichen Punkt, gemeinsame Bibliotheken zu erstellen, auf die in anderen Projekten verwiesen werden sollte, und meiner Meinung nach ist dies eine wertvolle Vision.

Darüber hinaus gibt es viele Szenarien, in denen die Verwendung einer gemeinsamen Bibliothek einfach nicht zutrifft: Betrachten wir zum Beispiel einige Entwurfsmuster wie Singleton, Strategy oder Observer. Sie können Bibliotheken erstellen, um solche Muster zu unterstützen, aber es gibt immer noch keine 100% ige Abdeckung.

Die wirkliche Notwendigkeit besteht darin, ein Werkzeug zu haben, um gemeinsame Praktiken im Team auszutauschen. Ich habe versucht, Githubs Kern zu verwenden, aber ich bin bei der Suche nach ihnen (wirklich arm) und bei der Tatsache, dass ich sie nicht nur unter meinem Team und nicht mit anderen teilen kann ...

(Haftungsausschluss: Ich bin einer der Gründer von Snip2Code und war - zusammen mit meinen Mitbegründern - vor einiger Zeit in derselben Denkweise: Deshalb haben wir beschlossen, dieses Projekt zu starten !!)

0