Best Practices für die gemeinsame Nutzung kleiner Codefragmente in Projekten


102

Ich versuche immer, das DRY- Prinzip bei der Arbeit strikt 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 sich nicht gegenseitig referenzieren können. Die Methode hat möglicherweise etwas mit Networking / Strings / MVVM usw. zu tun und ist im Allgemeinen eine nützliche Methode, die nicht spezifisch für das Projekt ist, in dem sie ursprünglich eingesetzt wurde.

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

  1. Wir haben am Ende Dutzende / Hunderte von kleinen Projekten - jedes um die kleinen Klassen / Methoden aufzunehmen, die wir wiederverwenden mussten. Lohnt es sich, .DLLfür ein kleines Stück Code ein ganz neues zu erstellen?
  2. Am Ende haben wir ein einziges Projekt mit einer wachsenden Sammlung von Methoden und Klassen, die nichts miteinander zu tun haben. Für diesen Ansatz habe ich in einem Unternehmen gearbeitet. Sie hatten ein Projekt mit dem Namen, base.commondas Ordner für Dinge enthielt, die ich oben erwähnte: Vernetzung, 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 kann ein Softwareteam kleine Codestücke zwischen Projekten am besten wiederverwenden?

Ich bin besonders interessiert, wenn jemand in einem Unternehmen gearbeitet hat, das Richtlinien in diesem Bereich hat, oder wenn dieses Dilemma wie ich persönlich aufgetreten ist.


Hinweis: Meine Verwendung der Wörter "Project", "Solution" und "Reference" stammt aus der .NET-Entwicklung in Visual Studio. Aber ich bin sicher, dass dieses Problem sprach- und plattformunabhängig ist.


21
+1, obwohl ich denke, dass jemand, der mit .NET arbeitet, ein humorvolles Element hat, wenn er Bedenken hat, irrelevanten Code über eine DLL-Referenz einzufügen.
JDB

2
@ColeJohnson .NET an sich ist eine riesige Referenz! Wahrscheinlich viel größer als die DLLs, die ich selbst gemacht hätte.
George Powell

2
Ich verstehe das. Der JIT-Compiler von .NET lädt jedoch nur die erforderlichen Methoden in den Arbeitsspeicher (wenn sie aufgerufen werden)
Cole Johnson,

1
Wahr. Obwohl Sie immer noch das gesamte .NET-Framework an alle verteilen müssen, die Ihr Produkt verwenden möchten, sind große Projekte und komplexe Lösungen schwieriger zu verwalten.
George Powell

Antworten:


75

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 für die Arbeit 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 möchten, damit Sie nicht mit Hunderten davon enden oder alles in eine einzige riesige Assembly packen müssen. Meiner Meinung nach passt dieser Ansatz, da nur einige unserer Projekte Framework.Dataund nur einige wenige jemals benötigt werden Framework.Strings, sodass die 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 einfach wiederverwendet werden können, können Sie versuchen, sie einfach als Code-Snippets in die IDE zu verteilen (z. B. Visual Studio-Code-Snippets ). Teams, mit denen ich in der Vergangenheit zusammengearbeitet habe, verfügten über eine gemeinsame Snippet-Bibliothek, die es für alle einfacher machte, unsere Standard-Codierungspraktiken auch mit internem Code zu befolgen.


4
+1 Das wäre auch mein Ansatz. Sie möchten wissen, wie Sie entschieden haben, wo Code abgelegt werden soll, der sich mit zwei oder mehr Aspekten befasst. Zum Beispiel IPAddressToString. Und ob Sie diesen Bibliotheken erlauben, sich gegenseitig zu benutzen. Zum Beispiel Dienste und Daten können wahrscheinlich viel von der Protokollierung profitieren ...
Marjan Venema

5
@MarjanVenema Für Cross-Cutting-Code kommt es darauf an, welche Konsumenten die Methode sinnvoller finden. Denn IPAddressToString, ist es wahrscheinlich , dass die Verbraucher mit Netzwerkprotokollen zu tun wird , das verwenden, aber die Verbraucher, die viel Hantieren mit Streichern tun Pflege kann nicht wirklich über IP - Adressen überhaupt. Das würde wahrscheinlich eher in einem Netzwerkpaket enden als Framework.Strings.
pswg

@MarjanVenema Wir versuchen, gegenseitige Abhängigkeiten zu vermeiden. Unsere Services und Daten-Frameworks sind so geschrieben, dass sie selbst keine Protokollierung durchführen, dem Verbraucher jedoch das Schreiben eines ordnungsgemäßen Protokollierungscodes erleichtern. Framework-Bibliotheken dürfen sich gegenseitig referenzieren, jedoch nur durch Erweiterung - z. B. durch Framework.Logging.Gibraltarein bestimmtes Add-On zum Protokollierungssystem.
pswg

5
+1 Sie können diese Framework-Bibliotheken in einem internen NuGet-Repository (so einfach wie ein Netzwerkordner) bereitstellen und haben eine gute Möglichkeit, sie zu verwalten.
Steven Evers

2
@SteveEvers Ich arbeite gerade daran, das einzurichten. : P
pswg

21

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

Wenn ich "verschiedene" Bibliotheken wie die akzeptierte Antwort sehe, sind sie meiner Erfahrung nach eine Ausrede, um das Rad neu zu erfinden (oder hier nicht erfunden (NIH) ) - eine weitaus größere Sünde, als Dont Repeat Yourself (DRY) zu verletzen .

Manchmal kann die Verletzung von DRY ein vernünftiger Kompromiss sein, es ist besser als die Einführung einer engen Kopplung. Die Wiederverwendung ist im Vergleich zu einer guten objektorientierten Gestaltung ein zweitrangiges Anliegen. Ein bisschen (ich meine kleine Menge, wende die Dreierregel an ) von Duplizierung 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 Datenbank von 24 Bibliotheken auf 6 Bibliotheken reduziert. Die Kompilierungszeit wurde von einigen Minuten auf ~ 20 Sekunden verbessert. Visual Studio ist auch langsamer zu laden und reagiert weniger mit mehr Assemblys. Zu viele Bibliotheken führen auch zu Unklarheiten darüber, wo Code gespeichert werden soll. lieber weniger, einfachere Regeln.

Warum ist das Zeug im .Net Framework nicht gut genug? Das Framework ist ziemlich groß; Oft habe ich Code gesehen, der bereits vorhandene Inhalte neu implementiert. Stellen Sie wirklich sicher, dass Ihre Frameworks Lücken im .Net-Framework schließen und nicht nur aus ästhetischen Gründen existieren (zum Beispiel "Ich mag das .Net-Framework hier nicht" oder vielleicht eine vorzeitige Optimierung ).

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

Die Verwendung standardisierter Technologien (wie das .Net-Framework und beliebte Drittanbieter- / Open Source-Bibliotheken) bietet Vorteile, die oftmals die vergleichbaren technologischen Vorteile einer Eigenerstellung aufwiegen. Es ist einfacher, Talente zu finden, die diese Technologien kennen, und Ihre vorhandenen Entwickler werden mehr in das Erlernen investieren.

Meine Empfehlungen:

  • Teilen Sie diesen Code nicht.
  • Erstellen Sie eine neue Bibliothek, wenn sie einen zusammenhängenden Zweck hat. Verwenden Sie nicht das Muster für Schlammballen .
  • Verwenden Sie vorhandene Bibliotheken von Drittanbietern nach Möglichkeit erneut.
  • Bevorzugen Sie weniger Assemblys mit einfacheren Regeln für den Speicherort des Codes.

1
Ein Zusatznutzen für die Verwendung von Open Source-Bibliotheken, sofern verfügbar. Wenn Sie Verbesserungen erzielen, können Sie diese der Community wieder zur Verfügung stellen! Zum Beispiel mit .Net MS veröffentlicht eine EnterpriseLibrary (jetzt Open Source), die eine ziemlich gute Reihe von Tools für gängige Szenarien bietet, etwas finden, das verbessert werden kann und hey presto! Jeder profitiert!
Glenatron

2
Ich sehe hier keine wirkliche Meinungsverschiedenheit mit der akzeptierten Antwort :-). "Weniger Assemblys mit einfacheren Regeln für den Speicherort von Code" ist kein Widerspruch zur akzeptierten Antwort. In der Antwort wird auch empfohlen, nur so viele verschiedene Baugruppen zu verwenden, wie angemessen erscheint.
sleske

Fünf Jahre später hat sich auch Microservice Guidance dieser Praxis angenähert
Dave Hillier

11

Für kleine Code-Teile - beispielsweise eine einzelne Klasse ohne Abhängigkeiten - wird der Code in der Regel nur kopiert und in Projekte eingefügt. Dies klingt wie eine Verletzung von DRY, und ich gebe zu, dass es manchmal sein kann. Aber auf lange Sicht war es aus einigen Gründen viel besser als ein massives, vielköpfiges Commons-Projekt.

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

Zweitens sollten Sie den allgemeinen Code für dieses Projekt stets ein wenig anpassen. 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, müssen Sie möglicherweise die Bibliothek optimieren und dann sicherstellen, dass Sie nicht alle anderen Apps beschädigen oder einen Versions-Albtraum erstellen.

Wenn es also nicht stark genug für seinen eigenen Namespace ist, tendieren wir dazu, es einfach in die entsprechenden Teile des Projekts zu schieben und es einen Tag lang zu nennen.


5
Ich stimme diesem Ansatz nicht zu. Ich schätze die Wartungsprobleme bei der Verwaltung kleiner Codeteile, aber ich würde argumentieren, dass eine gemeinsame Bibliothek aus allen erstellt werden könnte, wie @psw vorschlägt. Wenn Sie doppelte Kopien von Code mit geringfügigen Änderungen haben, ist dies problematisch. Annahmen werden gemacht, Fehlerkorrekturen werden übersehen.
Andrew T Finnell

2
-1 (zur Antwort). Es ist sicherlich einfacher, dass jeder seine eigenen Kopien seiner eigenen Programmversionen hat. So wurde Software in den 80er Jahren entwickelt. Ich habe seitdem erfahren, dass dies langfristig zu einem Durcheinander führt. Es ist schwieriger, das Richtige zu tun und eine gemeinsame Bibliothek zu haben, da die Leute dann viel mehr über ihre Arbeit kommunizieren müssen. Nun, sie sollten es tun.
Michael Durrant

3
+1 - Ich denke, es lohnt sich, diesen Ansatz zu erwähnen, auch wenn Sie ihn nicht sehr oft verwenden möchten. Einige Schnipsel ähneln eher Designmustern - Sie werden sie wiederverwenden, aber überall etwas anders und vielleicht in verschiedenen Sprachen, und vielleicht möchten Sie sie ändern. Außerdem ist eine weitgehend wiederverwendete Bibliothek insofern unflexibel, als Änderungen an ihrer API sehr riskant sind. Wenn Sie diesen Ansatz als Fallback verwenden, wird die Qualität von gemeinsam genutzten Bibliotheken erhöht, indem experimentelle Inhalte etwas länger ferngehalten werden.
Eamon Nerbonne

6

Die zweite Lösung, die Sie beschreiben, ist nicht so schlecht. In .NET verweisen Sie auch dann auf eine Assembly aus dem GAC, wenn Sie nur eine einzige Klasse davon verwenden. Das Ziehen von irrelevantem Code ist kein Problem, wie Sie vielleicht denken. In diesem Fall ist es wichtig, dass verwandte Methoden und Klassen in verschiedenen Namespaces sauber organisiert sind. Außerdem 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 Codestücke 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. Gehen Sie mit ihnen wie mit Best Practices um: Dokumentieren Sie sie und teilen Sie sie dem Team mit.


1
Mit Ausnahme von Nicht-Standardbibliotheken bedeutet dies, dass Sie eine große Baugruppe nur aufgrund einer einzigen (oder weniger) Verwendung versenden müssen. Dies ist kein Problem für Standardprodukte, da es sowieso verfügbar ist, aber ich würde definitiv vermeiden, große, aber meist nicht verwendete Baugruppen zu versenden, wenn Sie es auf eine gute Weise aufteilen können.
Poke

6

Ich habe bisher nur in "Unternehmens" -Umgebungen gearbeitet, in denen solche Probleme aufgetreten sind, und jedes Mal war dies die zweite Option, die übernommen wurde. Zum größten Teil funktioniert es einwandfrei, da der Platzbedarf der Anwendung nicht eingeschränkt wurde.

Nachdem ich die letzte Woche mit einem Start-up verbracht habe, das einen eigenen Nuget-Server betreibt, kann ich dies als Alternative vorschlagen. Natürlich werden die Probleme, die ich zu erwarten habe, die Entdeckungsfähigkeit sein.

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


Inwiefern erwarten Sie, dass sie nicht auffindbar sind? Auf diese Weise verwenden wir eine große und wachsende Anzahl von Nuget-Paketen. Das größte Problem ist das Verwalten von Versionierung und Abhängigkeiten.
pdr

Ah ja. Die auch. Mit Problemen im Zusammenhang mit der Entdeckbarkeit meine ich, dass es bei einer ausreichenden Anzahl kleiner Pakete mit einer bestimmten Funktion möglicherweise schwieriger wird, die einzelnen Pakete zu katalogisieren (und zu finden). Wie macht Ihr Team beispielsweise bekannt, welche Pakete verschiedene Funktionen enthalten? (Nuget Search Ignoranz hier zeigen)
Kofi Sarfo

Oh, ich verstehe. Ja, Sie können definitiv alles in die Beschreibung einfügen, was Sie möchten, und das wird durchsuchbar, aber ich denke, wir haben die Pakete gut genug gruppiert, dass es kein Problem zu sein scheint.
pdr

@sarfeast Es wäre schön, wenn Sie einen Link zu einem beliebigen Nuget-Server freigeben und ein wenig darüber erzählen könnten.
Hans-Peter Störr

6

Ich habe kürzlich darüber nachgedacht, und mir ist eine große Bibliothek gängiger Methoden eingefallen, wie sie bisher erwähnt wurden, jedoch mit einer Wendung. Mit dem Bibliotheksprojekt können Sie beim Kompilieren konfigurieren, welche Teile wie das BusyBox-Projekt enthalten sind . Mit diesem Ansatz können Sie eine Bibliothek im Stil eines Spülbeckens erstellen, aber nur die Werkzeuge verwenden, die Sie beim Kompilieren benötigen.


5

GitHub hat ein ziemlich nützliches Tool zum Speichern von Code-Snippets https://gist.github.com/

Es speichert Ihre Snippets als Git-Repositorys, die Sie für sich behalten oder zum Teilen von Snippets mit anderen Personen verwenden können.


3

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

Wenn Sie dies auf jeden Fall für den Code tun möchten, der von mehr als einer Person erstellt wurde, müssen Sie zunächst alle Beteiligten kennen und mit ihnen 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 variieren die Art des Codes, den Sie in solche Lösungen einfügen, sowie die Granularität, mit der Sie die DLLs anpassen. Sobald Sie sich für diesen entschieden haben (am liebsten mit einer gewissen Begeisterung für die Idee - Sie?), Sollten Sie sich hinsetzen und anfangen, etwas Struktur in diesen zu stecken.

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 pflegen, was normalerweise bedeutet, dass Sie jemanden für lange Zeit damit beauftragen müssen. Sie benötigen außerdem eine zuverlässige Dokumentation, die auch gewartet werden muss. Mit ein wenig Glück und Zusammenarbeit können Sie einige Best Practices finden, 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 immer noch Managementunterstützung.


3

Ich habe eine Menge Probleme, und meine bevorzugte Lösung ist, den Code in einem Github / Pubic-Web-fähigen Repository zu veröffentlichen. es löst viele Probleme -

  1. einfacher zugang und einfach zu teilen. cvs / svn / enterprise-repos bedeutet, dass ein Projekt in mehrere IDE-Arbeitsbereiche ausgecheckt wird und manchmal Arbeitsbereiche oder Computer gewechselt werden müssen, um auf einen kleinen Codeausschnitt zu verweisen.
  2. Angenommen, diese Codefragmente sind keine proprietären / klassifizierten Codeteile und stellen Variationen von öffentlich verfügbarem Wissen dar. Wenn sie in einem öffentlichen Repo wie Github veröffentlicht werden, bedeutet dies, dass andere sie sich ansehen und möglicherweise sogar dazu beitragen.
  3. Das Posten von etwas in der Öffentlichkeit unter Ihrem Namen hat den zusätzlichen Druck des Ansehens. Sie werden die Dinge überprüfen und aktualisieren, da dies Ihre Fähigkeiten als Programmierer widerspiegelt.
  4. Aktualisierung. Die Sache bei der Pflege von Code-Snippets in einem Repo ist, dass ein Snippet, das lange nicht mehr verwendet wurde, möglicherweise veraltet ist (veraltete apis / libs enthalten). Beispiel - Java-Code-Snippet zum Lesen einer Datei. Vielleicht haben Sie 2009 herausgefunden, wie dies am besten funktioniert, aber 2014 wird eine neue Datei-API veröffentlicht, die alles ändert. dein Schnipsel? 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 korrigieren Möglicherweise hast du lange Zeit etwas falsch gemacht.

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


2

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

Wenn ein Projekt ein Hilfsprogramm benötigt, fügt es einfach die Quelldatei mit der erforderlichen Methode mit "Als Verknüpfung 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 bei allen anderen ist auch hier eine genaue Analyse des Dienstprogramms erforderlich. Das Anfordern einer hohen Testabdeckung hat sich für uns bewährt, und Tests sind auch eine gute Dokumentation für die Verwendung. Die Entdeckung ist für uns immer noch ein ungelöstes Problem.

Eine Komplexität des Hilfsprojekts besteht darin, die Sichtbarkeit von Elementen zu bestimmen. Als Faustregel gilt, dass Methoden intern und Datenstrukturen öffentlich sein sollten.


2

Mein Unternehmen verwendet intranetlokale Webdienste. Wir haben einige Webservices, die als gemeinsame interne Webservices eingerichtet sind. Wenn ein anderes Projekt Zugriff auf einen der Services 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.

Dies funktioniert natürlich nur mit Internet-Apps (und funktioniert nur in Millisekunden, wenn Sie sich im selben lokalen Netzwerk befinden), hat aber einige wirklich schöne Vorteile.


0

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

Es ist eine interessante Möglichkeit, nur Ihre Snippets (nicht nur 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, es gibt jedoch keine 100% ige Abdeckung.

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

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

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.