Wie kann man beweisen, dass eine Anwendung auf einer fehlerhaften Codebasis basiert?


23

Ich überprüfe derzeit ein System, das von einigen Entwicklern erstellt wurde, die zuvor in meinem Job gearbeitet haben. Das System funktioniert aus Sicht des Benutzers ziemlich gut, aber wenn man sich mit der Codeüberprüfung befasst, ist es ein völliges Durcheinander. Ich bin mehr als überzeugt, dass die Art und Weise, wie die Anwendung erstellt wird, zukünftige Aktualisierungen nicht aushält, geschweige denn die Nutzung stark zunimmt.

Das Problem ist, dass ich weiß, wie schlimm es ist, aber meine Vorgesetzten nicht. Wie kann ich es meinem Manager beweisen, damit er das Problem tatsächlich erkennt und überzeugt ist, die aktuelle Codebasis auf ein Minimum zu beschränken und in naher Zukunft eine neue Entwicklungslinie für die nächste Version der Anwendung zu starten?


6
programmers.stackexchange.com/questions/59050/... Vielleicht beherzigen , wie schlecht die „große Rewrite“ zu tun in der Regel aus betriebswirtschaftlicher Sicht endet. Das wäre, was ein Programmierer auf "höherem Niveau" tun würde.
Quentin-Starin

22
@qes, das einzige, was schlimmer ist als das "große Umschreiben", ist die lähmende Angst vor dem "großen Umschreiben". Als ich meine derzeitige Position einnahm, erbte ich eine Menge Perl CGI von zwei oder drei verschiedenen Programmierern ohne Quellcodeverwaltung, Fehlerverfolgung oder Tests. Es hat einiges an Überzeugungsarbeit gekostet, aber ich habe die Genehmigung erhalten, Ruby on Rails unter Beibehaltung des alten Codes umzuschreiben. 5 Monate später waren die Tools benutzerfreundlicher und wir konnten neue Funktionen in Tagen oder Wochen anstelle von Monaten hinzufügen. Die Benutzer sind begeistert und ich verliere nicht den Verstand. Das "große Umschreiben" erfordert eine solide Rechtfertigung, keine völlige Vermeidung.
Jason Lewis

1
@JasonLewis: (Ich nehme an, Sie sind dem Link in meinem vorherigen Kommentar nicht gefolgt?) Es scheint für jemanden schlecht beraten zu sein, der vor weniger als einem Jahr selbst beschrieben hat, dass ihm wichtige Fähigkeiten fehlen, die ein Senior-Level besitzen würde und nicht. ' Sie wissen nicht, wo Sie anfangen sollen, wenn Sie ein neues Projekt starten.
Quentin-Starin

5
@JasonLewis Ich stimme dir vollkommen zu. Jedes Mal, wenn jemand nach dem Umschreiben einer App in SE fragt, kommen viele Leute mit dieser Ideologie "Mach kein großes Umschreiben". Ich denke, es gibt sicherlich viele Gründe, es nicht zu tun, aber Sie sollten es nicht um jeden Preis vermeiden. Ich habe an einer Überarbeitung einer 100.000-Zeilen-Code-App teilgenommen und wir hatten viel Erfolg, sehr ähnlich dem, was Sie beschrieben haben. Wir konnten es sogar Modul für Modul neu schreiben (erster Teil der Benutzeroberfläche, dann der Server, dann der Rest). 12 Monate später haben wir einen sehr sehr zufriedenen Kundenstamm und jeder ist stolz auf die Entscheidung, die wir getroffen haben.
Alex

2
Dies ist Teil eines allgemeineren Problems: Das Ihres Vorgängers, das auf langfristige Kosten sofortige Ergebnisse erzielt. Bei der Übernahme müssen Sie erklären, warum Sie nicht die gleiche Leistung erbringen können.
David Thornley

Antworten:


23

"Aber es funktioniert jetzt" ist die Standardantwort des Managements auf die berechtigten Frustrationen der Softwareentwickler. Das erste, was ich tun würde, wäre, die Dokumentation (falls vorhanden) zu kompilieren und diese zu verwenden, um Widersprüche zwischen dem Code und der Dokumentation aufzuzeigen.

Wenn Sie können, stellen Sie eine umfassende Suite von Komponententests zusammen. Führen Sie diese bei jeder Änderung aus, damit Sie Regressionen dokumentieren können, die auf die vorhandene Codebasis zurückgeführt werden können.

Wenn Sie einen Entwickler aus einer anderen Abteilung anwerben können, dessen Arbeit Sie vertrauen, erhalten Sie ein zweites Paar Augen für den Code. Ein Entwickler, der sagt, "das ist Mist", ist leichter zu verwerfen, als wenn ein leitender Entwickler, der schon eine Weile für ihn bürgt und sagt: "Nein, Jim, er hat Recht." Das ist Mist auf einem Mistknacker. '

Natürlich hängt alles von Ihrer Umgebung, der Unternehmensgröße usw. ab.

Ich empfehle immer einen Blick auf The Pragmatic Programmer zu werfen, wenn Sie es nicht gelesen haben. Es sollte nicht nur für jeden Software-Fachmann eine Lektüre erforderlich sein, sondern es enthält auch einige gute Vorschläge für den Umgang mit Management, Mitarbeitern, Benutzern usw., die Software-Engineering nicht als Handwerk betrachten.


7
Es gibt keine Dokumente, und der Code ist so gut wie nicht testbar, es sei denn, wir werden ihn verdammt noch mal überarbeiten. Ich bin ziemlich zuversichtlich, dass ich von mehreren Kollegen unterstützt werde, sodass es hilfreich sein könnte, einen anderen Entwickler in die Diskussion einzubeziehen.
ChrisR

@ ChrisRamakers Das sind hervorragende Neuigkeiten (der Support, nicht der Mangel an Dokumenten!). Es ist schwieriger (wenn auch nicht unmöglich) für Manager, die professionelle Meinung mehrerer Entwickler abzulehnen . Und wenn Ihre Unterstützer länger im Unternehmen sind, verfügen sie möglicherweise über wertvolle Erfahrungen im Umgang mit der internen Politik der Organisation. Viel Glück!
Jason Lewis

Außerdem können Sie, wenn Sie eine Lasttest-Software erwerben können, zeigen, wie sie unter hoher Last beschädigt werden kann.
HLGEM

13

Aus Sicht des Managements ist das System nicht in Ordnung, und Sie beschweren sich nur, weil [Sie es einfach umschreiben möchten / Sie nicht verstehen, was frühere Ingenieure getan haben / Sie möchten, dass Ihre Arbeit einfach ist]. Ein bisschen wie ein Strohmann, aber wenn jemand an der Spitze sieht, dass die Dinge gerade gut funktionieren, ist er nicht geneigt, eine Krise zu sehen, in der Sie sich befinden (ich bin sicher, dass es irgendwo eine Allegorie des Klimawandels gibt ...) .

Bis zu einem gewissen Grad haben sie einen Punkt. Das Management sieht Probleme, wenn die Veröffentlichungen weit über die ursprüngliche Schätzung hinausgehen, die Schätzungen für die auszuführende Arbeit zu hoch erscheinen, "dies ist mit unserer vorhandenen Codebasis unmöglich" und das Auftreten von Fehlern, die über die Qualitätssicherung hinausgehen. Wenn die Dinge gut laufen, ist es einfach, dir auf den Kopf zu klopfen und dir zu sagen, dass du dein Bestes geben sollst, da dies keinen Einfluss auf das Endergebnis hat.

Was zu tun ist, hängt von Ihrer Organisation und der Software selbst ab. Grundsätzlich empfehle ich jedoch, alle Komplikationen zu dokumentieren, die als Ergebnis eines schlechten Legacy-Codes auftreten. Machen Sie dem Management beim Abschätzen von Aufgaben klar, warum dies Ihrer Meinung nach so lange dauern wird, und erläutern Sie ausführlich, welche Aspekte der alten Codebasis diese zusätzlichen Kosten verursachen. Geben Sie bei der Einführung von Fehlern in den Code an, warum dieser Fehler aufgetreten ist und wie die Probleme in der alten Codebasis verursacht werden.

Ich würde vorschlagen, Ihre Bedenken gegenüber den Stakeholdern so auszudrücken, dass die Software über das ursprüngliche Design hinausgewachsen ist und nun problematisch ist, die Verbesserungen fortzusetzen.


5

Es stehen verschiedene Tools zur Verfügung, mit denen Code-Coverage und Code-Review durchgeführt werden können. Google-Tools, die für Ihre Technologie geeignet sind. Dies sind normalerweise branchenübliche Tools. Ich würde vorschlagen, dass Sie diese Tools verwenden, einen Bericht zur Codequalität erstellen und dem Manager vorlegen. Stellen Sie sicher, dass Ihre Kritik konstruktiv und unpolitisch ist.


Ja, ich habe darüber nachgedacht, die durchschnittliche zyklomatische Komplexität zu berechnen und als Argument zu verwenden, aber ich bin mir sicher, dass dies für das Management kein Problem darstellt. Aber es ist einen Versuch wert, danke
ChrisR

5
@ChrisRamakers: Man kann einem Manager nichts "beweisen". Vergiss den "Beweis". Daten sammeln. Fakten sind alles, was Sie haben. Mehr Fakten sind überzeugender. Aber es gibt keinen "Beweis".
S.Lott

4

Wählen Sie ein Beispiel aus, das leicht zu verstehen ist, wo das Management es für eine einfache Änderungsanforderung hält, das jedoch aufgrund des vorhandenen Designs sehr viel schwieriger ist.

Sie möchten nicht, dass sie sich mit der spezifischen Anfrage befassen, aber stellen Sie sicher, dass Sie ihnen mitteilen, dass JEDE Änderungsanforderung so sein wird. Niemand möchte mit einer Bewerbung in eine Ecke gestrichen werden. Entwickler glauben an YAGNI, aber das Management glaubt an CYA.

Die Vorschläge für Lasttests könnten ein guter Ansatz sein, sie sind jedoch möglicherweise nicht davon überzeugt, dass die zunehmenden Bedenken hinsichtlich der Nutzung einem realen Wachstumspotenzial entsprechen (das Unternehmen wird sich in einem Jahr nicht verdoppeln).

Alles ist relativ. Möglicherweise möchten sie die Ressourcen nicht in dieses Projekt stecken, wenn sie Pläne für wichtigere Projekte haben, für die Sie Ihre Zeit aufwenden können. Lass dich nicht beschriften, wenn du das große Ganze nicht siehst.


1
Zeigen Sie nach der Änderung die Diff-Datei an, die in einer fehlerhaften Codebasis viele verschiedene Quelldateien berührt. Haben Sie ein "Was hat das damit zu tun?" Element usw. Erklären Sie dem Management, wie viel von dieser Arbeit, dh Zeit == $$, mit der schlechten Codebasis zusammenhängt, und dass alle zukünftigen Änderungen diese Eigenschaft haben werden.
Larry OBrien

3

Wenn Sie davon sprechen, etwas zu beweisen, kommt all dieses wissenschaftliche Methodenmaterial ins Spiel. Wenn Sie objektive Maßstäbe für die Entscheidung über die Richtigkeit akzeptieren wollen, müssen Sie die Möglichkeit akzeptieren, dass diese lästigen Tatsachen bei der Untersuchung berücksichtigt werden Es stellt sich heraus, dass Sie nicht auf Ihrer Seite sind.

In Ihrem Fall sind meines Erachtens zwei Dinge zu beweisen.

Erstens, dass die aktuelle Codebasis "schlecht" ist. Was Sie wahrscheinlich beweisen können, ist, dass "die professionelle Meinung fast aller Entwickler, die diesen Code untersuchen, ist, dass es schlecht ist".

Zweitens, dass das Unternehmen besser dran ist, die Codebasis neu zu schreiben. Dies ist ein Problem, denn selbst wenn der erste Punkt wahr ist, ist der zweite möglicherweise nicht wahr. Sie wissen auch nicht genug, um diese Entscheidung zu treffen. Dies ist die Aufgabe des Managements, und wenn Sie möchten, dass sie Ihr professionelles Urteil über den ersten Punkt respektieren, sollten Sie ihr Urteil über den zweiten Punkt respektieren.

Sie können jedoch nicht über den zweiten Punkt entscheiden, ohne die von Ihnen angegebenen Informationen einzuholen. Sie müssen mitteilen, was Sie darüber wissen, wie sich die Probleme im Code auf das Geschäft auswirken, und was Sie darüber wissen, wie sich ein Umschreiben auf das Geschäft auswirken würde. Dies ist schwierig, da beide eine Zukunft voraussagen müssen, die eine Menge Unsicherheit birgt.

Sie können jedoch versuchen, das Problem in geschäftlicher Hinsicht darzulegen. Wie viel zusätzliche Zeit wird für Änderungen und Regressionen aufgewendet? Was würde ein Umschreiben kosten? Wie schnell werden die Kosten des aktuellen Systems mit der Zeit steigen, wenn sie nicht umgeschrieben werden? Was ist, wenn die Nutzung zunimmt? Wie groß ist die Wahrscheinlichkeit einer Katastrophe, wenn der aktuelle Code beibehalten wird? Sie können nichts davon wissen, aber Sie können besser raten als jeder andere. Geben Sie einen Bereich an oder etwas, um zu kommunizieren, wie genau Sie diese Dinge vorhersagen können.

Die meisten Entwickler mögen es nicht, lausigen Code zu pflegen. Aus diesem Grund kann es bedauerlich sein, dass Code, der aus Entwicklersicht ohne weiteres umgeschrieben werden muss, aus geschäftlicher Sicht möglicherweise nicht umgeschrieben werden kann.

Selbst wenn das Umschreiben rentabel ist, kann es beispielsweise weniger wert sein als die Opportunitätskosten für das Ausgeben des Geldes an einer anderen Stelle im Unternehmen. Oder es kann länger dauern, bis sich die fehlerhafte Codebasis ändert und mehr Regressionen vorliegen, aber nicht genug, um ein Umschreiben rentabel zu machen. Möglicherweise versuchen sie, in den nächsten Monaten aufgekauft zu werden, und das Ausgeben von Geld für ein Umschreiben wird in den Büchern erscheinen, Buggy-Software jedoch nicht.

Versuchen Sie, aus geschäftlicher Sicht darüber nachzudenken, und kochen Sie nicht die Zahlen, um das zu bekommen, was Sie wollen. Eine umfassende Neufassung ist aus geschäftlicher Sicht fast nie ein Kinderspiel. Wenn Sie etwas beweisen möchten, das nicht direkt beweisbar ist, versuchen Sie nach besten Kräften, es zu widerlegen. Wenn Sie Ihr Bestes immer wieder versuchen , einen Weg zu kommen nicht von Grund auf neu zu schreiben , aber nichts kommen Sie mit macht Sinn, vielleicht dann ist es wirklich Zeit von Grund auf neu zu schreiben. Und wenn Sie diese Anstrengungen unternehmen, zeigt dies Ihrem Management, dass Sie es ernst meinen, die Interessen des Unternehmens zu vertreten, nicht Ihre eigenen (Sie vertreten die Interessen des Unternehmens, nicht Ihre eigenen, oder?).


2

Ich denke, es hängt davon ab, was an der Codebasis schlecht ist. "Nicht so, wie ich Dinge tun würde" bedeutet nicht, dass es eine schlechte Codebasis ist.

Dinge, die eine schlechte Codebasis ausmachen:

  • Sicherheitslücken

    Probleme, die den Server, die Anwendung und / oder die Daten anfällig machen. Insbesondere alles, was sensible Unternehmens-, Kunden- oder Kundendaten gefährdet. Diese sollten leicht zu dokumentieren sein.

  • Arbeitet kaputt

    Es funktioniert nur, weil Sie die Daten massieren und die Anwendung fast ununterbrochen warten, damit sie weiterhin funktioniert. Wenn du gehen würdest und niemand das Spiel aufnimmt, würde es nicht mehr funktionieren. - Dokumentieren Sie, wie viel Zeit Sie damit verbringen. Und beachten Sie, wie viel Sie sparen könnten. Nicht selten sind diese Prozesse auch für Benutzer ineffizient, und Sie können dies möglicherweise auch dokumentieren.

  • Funktioniert eigentlich nicht

    Es scheint zu funktionieren, aber die Ergebnisse sind falsch. Dies führt im Allgemeinen zu Problemen auf der ganzen Linie, wie nicht übereinstimmende Zahlen, hohe Fehlerrate usw.

Was ist keine schlechte Codebasis (nur nicht gut):

  • Geschrieben am veralteten nicht unterstützten Tech. (VB6, COBOL, .net1.1 usw.)

Beachten Sie die Vorteile der Migration auf eine neue Technologie. Versuchen Sie, einen Migrationspfad zu finden, der Teile gleichzeitig verschiebt, um das Risiko zu minimieren und das Vertrauen der Benutzer und des Managements zu stärken. Stellen Sie sicher, dass die Logik im Grunde die gleiche ist wie das Original.

  • Undokumentierter / schlecht formatierter Code

Dies ist für Sie am einfachsten zu beheben, da Sie im Allgemeinen Kommentare hinzufügen und die Formatierung korrigieren können, ohne dass sich dies tatsächlich auf den Code auswirkt. Es ist jedoch kein Umschreiben erforderlich. Wenn Sie der Meinung sind, dass dies mit anderen Problemen verbunden ist, müssen Sie dies zunächst beheben, damit Sie die Funktionsfähigkeit des Codes besser einschätzen können.


1

Sie haben Ihre eigene Frage in gewisser Weise beantwortet.

Sie können sie davon überzeugen, Geld für das System auszugeben, indem Sie warten, bis es für den Benutzer nicht mehr richtig funktioniert. Wenn Sie der Meinung sind, dass es sich nicht skalieren lässt, warten Sie, bis dies eintritt, oder führen Sie einen Belastungstest durch, um dies zu beweisen.

Es ist dann ein einfacher Vorschlag, diese maßstabsgetreu zu reinigen, der X Stunden kostet.


8
Das einzige Problem ist, dass er, wenn er die Hauptverantwortung für das System trägt, dafür verantwortlich gemacht wird, wenn es nicht mehr funktioniert. "Aber es hat funktioniert, bevor du angefangen hast !", Werden sie sagen. Aus diesem Grund habe ich einen proaktiven Ansatz empfohlen. Warnen Sie sie im Voraus, dokumentieren Sie die Probleme, und dann ist sein Arsch bedeckt, wenn es bricht. Er kann nicht nur sagen, dass ich es seinem Chef gesagt habe, sondern auch, dass ich es ihm gesagt habe .
Jason Lewis

3
@Jason - Ich verstehe Ihren Standpunkt, aber meiner Erfahrung nach wirkt die Ablehnung nach unten und "sagte ihm, dass" die Kette hochgeht, wird sehr schnell mit "Nicht-Team-Spieler" auf dem Weg nach unten erreicht.
Jonno

2
Es hängt sehr stark vom jeweiligen Arbeitsplatz ab, aber ich stimme Ihnen zu ... Ich hätte es besser formulieren können ... Mein Hauptpunkt war es, die Gründe für das Scheitern im Voraus zu dokumentieren, den Punkt zu argumentieren und die Dokumentation verfügbar zu halten Wenn dies der Fall ist, können Sie das Problem beheben. Durchschnittlich sind Sie nicht geschraubt, wenn es fehlschlägt. Am schlimmsten ist es, wenn Sie das System und seine Schwächen gründlich erforschen und ausreichend beheben, um Ihrem potenziellen Arbeitgeber eindrucksvoll zu erklären, wie und warum Sie Ihre letzte Position verlassen haben, wenn Sie nach einem Fehlschlag auf Jobsuche sind ;-)
Jason Lewis

1
@JasonLewis Wenn Spieler in der Firma solche Ausdrücke verwenden I told you so, ist das eine giftige Schuldkultur und kein Ort, an dem die OP lange arbeiten möchte. Ein guter Manager gibt keinen Vorwurf, ein guter Manager erkennt Probleme an und stellt einen Plan auf.
maple_shaft

@maple_shaft Ich stimme zu. Ich meinte diese Worte nicht wörtlich, ich bezog mich eher darauf, alle Grundlagen abzudecken. Im Idealfall hätten wir alle gute, unterstützende Manager, die die gesamte Befehlskette hinaufgehen. Oft lassen wir uns jedoch mit Fairness abfinden, damit wir den Job, den wir haben, als Sprungbrett für den Job nutzen können, den wir uns wünschen.
Jason Lewis

1

Dies ist eine schwierige Situation, da sich aus Sicht des Benutzers jetzt alles in einem akzeptablen und stabilen Zustand befindet. Vor allem bei nicht-technischen Managern gibt es im Moment nichts, worüber man sich Sorgen machen müsste, aber das Umschreiben der Codebasis ist eine enorme Entscheidung, die nicht leichtfertig getroffen werden sollte, insbesondere nicht in Bezug auf die Meinung und die Bemühungen eines einzelnen Mannes (Sie selbst). .

Sie sind also in einer schwierigen Situation, weil Sie eine überwältigende technische Verschuldung haben (Ihrer Meinung nach haben wir keine Beispiele und müssen Ihr Wort dafür nehmen) und sich in einer schwierigen Situation befinden die Schwierigkeit zu haben, Funktionen in diesem System zu pflegen und hinzuzufügen.

Ihre Schätzungen für neue Funktionen werden hoch sein, rechtfertigen Sie diese hohen Zahlen mit Fakten und beweisen Sie, dass diese Dinge tatsächlich viel Zeit in Anspruch nehmen werden. Wenn Sie dies nicht richtig vermitteln, geht Ihr Vorgesetzter möglicherweise davon aus, dass Sie inkompetent sind, und das möchten Sie auf keinen Fall. Wenn er die hohen Schätzungen in Frage stellt, erklären Sie, warum Sie der Ansicht sind, dass die angesammelte technische Verschuldung die Möglichkeit behindert, der aktuellen Software schnell und kostengünstig Funktionen hinzuzufügen. Wenn Ihr Manager zwei Gehirnzellen hat, die aneinander reiben können, beginnt er sehr schnell zu verstehen.

Der Punkt ist, dass Sie nicht versuchen sollten, Ihren Manager zu überzeugen, sondern Ihren Manager mit geeigneten (und sorgfältig ausgewählten) Informationen steuern, damit er sich selbst davon überzeugen kann , dass ein Umschreiben ein akzeptabler Kurs ist. Sie müssen den Manager die ganze Zeit denken lassen, dass es seine / ihre Idee war.


1

Bestimmen Sie zunächst die akkumulierten technischen Schulden in Ihrer Codebasis. Dann werfen Sie einen Blick auf diese Frage und die Antworten , in denen erläutert wird, wie Sie das Management davon überzeugen können, die technischen Schulden zu begleichen, bevor Sie fortfahren.


0

Es gibt Grund , warum alle Software sieht aus wie Chaos reifen:

  1. Das ganze Durcheinander verschlüsselt die kritische Logik, auf die sich das Unternehmen stützt. Ohne geht nichts. Alles war nötig, um das Benutzerproblem zu lösen.
  2. Es benutzt etwas veraltete Technologie. Aktuelle Programmierer scheinen zu glauben, dass es nur ein Chaos ist, wenn keine Schablonenmagie verwendet wird. Das ist kaputte Sicht. Jeder, der zu spät zu einem größeren Projekt kommt, hat diese Phase, während er alle Details lernt.
  3. Die Anforderungen, die vor einiger Zeit kritisch waren, sind nicht mehr so ​​kritisch. Dies liegt daran, dass die Software diese Probleme bereits behoben hat. Wenn das Projekt zu spät kommt, scheint es, als sei die Software nicht ohne Grund komplex - das Problem besteht nicht mehr, aber die Komplexität des Codes ist immer noch vorhanden.

Diese Art von Einstellung führt Programmierer dazu, die massive technische Verschuldung zu entschuldigen, die sich aus Unwissenheit oder Faulheit ergibt. Die Aufgabe eines Programmierers besteht darin, Geschäftslogik mithilfe von Abstraktionen zu codieren. Mutable Angaben sollten in Metadaten und nicht in fest codierten magischen Zahlen gespeichert sein. Zweitens kann "etwas veraltet" subjektiv sein. Meiner Meinung nach bedeutet "etwas veraltet", dass das Framework / die Plattform noch aktiv entwickelt wird, und ich habe einen Upgrade-Pfad. Die Alternative ist "veraltet". Nummer 3 ist unentschuldbar. Sie haben gerade Cruft beschrieben. Niemand hat die Codebasis überarbeitet oder aufgeräumt, und das ist akzeptabel?
Jason Lewis

Sicher, aber was ist das Ergebnis, nachdem Sie die Geschäftslogik mithilfe von Abstraktionen codiert haben? Der Code wird kompliziert aussehen. Das ist die Definition von "Chaos". die (3) ist nicht cruft, da die Komplexität noch erforderlich ist; Das Bedürfnis, es zu haben, verschwand nicht, selbst nachdem das Problem gelöst war.
tp1
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.