Ich wohne in einer Umgebung, in der die Leute glauben:
- Java-Generika sind die Funktion, die ausschließlich für das Schreiben von Bibliotheken und nicht für die eigentliche Codierung verwendet wird.
- C ++ ist eine OO-Programmiersprache.
template
ist eine optionale und vermeidbare Funktion
Diese Menschen sind jedoch sehr auf die Bibliotheken angewiesen, die mit generischer Programmierung (z. B. STL, Java-Container) geschrieben wurden. Wenn ich einen Code mit template
s oder schreibe generics
, lehnt der Code-Prüfer ihn höchstwahrscheinlich ab und kommentiert ihn, um ihn "korrekt / verständlich / elegant" zu schreiben .
Eine solche Mentalität gilt vom normalen Programmierer bis zum leitenden Manager. Es gibt keinen Ausweg, weil diese Leute in 90% der Fälle Lobbyarbeit betreiben.
Was ist der beste Weg , sie zu erklären ( ohne sich die Kehle durchzuschneiden ), der praktische Ansatz, Code zu schreiben, der OO und generische Programmierung zugleich ausmacht?
Antworten:
Es gibt immer noch Menschen in der Welt , die nicht Gebrauch jave Generika in „normaler Codierung.“ Ich kann es mit C ++ - Vorlagen glauben, aber mit Generika? Sie sind nicht einmal schwer zu erlernen / zu benutzen. Im Ernst, die besten Features von Java und C ++ sind Generics und Templates.
Der beste Weg, Menschen von Dingen zu überzeugen, besteht darin, ein überzeugendes Argument vorzulegen, nicht bedrohlich zu sein und Recht zu haben.
Solange Sie keine Vorlagen als Programmiersprache verwenden, ist der parametrische Polymorphismus (Generika / Vorlagen) mit ziemlicher Sicherheit gut.
1. Vermeidet das Kopieren von Code.
Dies ist offensichtlich, aber polymorpher Code ist allgemeiner Code. Deshalb nennt man es Generika.
2. Unterstützt eine bessere statische Überprüfung.
Ohne parametrischen Polymorphismus schreiben Sie Dinge wie
public Object clone()
oderpublic boolean equals(object b)
die nicht nur Greuel sind, sondern Typen, die keine Informationen darüber liefern, was sie tun, und die unweigerlich überall Ausnahmen auslösen. Die Alternative zum parametrischen Polymorphismus ist überall zu finden3. Nicht-parametrischer Polymorphismus OOP-Code ist grundsätzlich nicht in der Lage, "binäre Methoden" korrekt zu behandeln.
Sie verwenden diese oft.
4. Es ist eine bewährte Methode
In Java wird die Verwendung von Generika als Best Practice angesehen (siehe Effective Java von Josh Bloch). Große C ++ - Denker wie Sutter und Alexandrescu empfehlen auch die Verwendung von Vorlagen, um eine Vielzahl von Problemen zu lösen.
5. Es passt zum OO-Paradigma.
Die Leute bemerken dies oft nicht, aber die Kombination von Untertypisierung und Generika ergibt ein System, das VIEL aussagekräftiger und objektorientierter ist als jedes System mit nur einem von ihnen.
Betrachten Sie die Mixins von Scala. Dies ist eine nette Funktion, mit der Sie Ihre Objekte aus Bauteilen zusammenziehen können. Generika und Vorlagen können einige dieser Vorteile simulieren. Angenommen, eines Ihrer Objekte verwendet eine Datenbank. Gutes Design würde Sie den Datenbankzugriff in eine separate Klasse abstrahieren lassen. Wenn dies richtig gemacht wird, können Sie nicht nur Ihren Datenspeicher (Schlüssel zur Testbarkeit) verspotten, sondern auch alternative Implementierungen wie die neue No-SQL-Datenbank hinzufügen. Hier kann es jedoch zu Problemen kommen. Unabhängig davon, welche Implementierung Sie verwenden, erhalten Sie unterschiedliche Funktionen Ihres Geschäftsobjekts.
Generika zur Rettung!
Jetzt können Sie Ihre
Business
Objekte statisch unterscheiden , basierend auf der Fähigkeit, datenbankspezifische Funktionen zu verwenden. Sie brauchen noch einige Laufzeitprüfungen und Casting, aber Sie können damit beginnen, VIEL besseren Code zu erstellen.und
6. Normaler Code existiert nicht.
Es gibt nur drei Dinge im Programmieruniversum:
Wenn Sie nicht über Ihren Code nachdenken, als wäre es eine Bibliothek, haben Sie ernsthafte Probleme, wenn sich die Anforderungen an Ihr Projekt ändern. Architektur ist (wohl) die Kunst, gute APIs zu entwerfen.
Ich finde diese Einstellung atemberaubend. Wenn Sie sich an das Programmieren mit parametrisierten Typen gewöhnt haben, macht es Ihnen einfach zu schaffen, sie nicht zu verwenden. Java und C ++ haben eine Reihe von rauen Stellen, die sie beseitigen können.
quelle
normal code
nicht existiert und dass es nur drei Arten:libraries
,configurations
undbad code
. Es ist eine idealistische Argumentation, obwohl Sie es Ihren Kollegen erklären müssen, die vielleicht nicht so idealistisch sind wie Sie. Ich stimme jedoch zu, dass die Verwendung parametrisierter Typen einfach fantastisch ist, sobald Sie den Dreh raus haben.Dies ist eine spezielle Form der allgemeineren Frage: "Wie überzeugen Sie Ihre Vorgesetzten, eine neuere und bessere Technologie / Herstellungsmethode einzusetzen?"
Leider glaube ich nicht, dass Sie können, und ich bin nicht sicher, ob Sie sollten. Es ist per definitionem ihre Wahl, da sie dich dafür bezahlen, Dinge auf eine bestimmte Weise zu tun, die sie gewählt haben, und nicht auf irgendeine Weise, die du magst. Das Beste, was Sie tun können, ist, darauf hinzuweisen, dass diese Technologie da draußen ist, viele Menschen sie verwenden und sie der Weg der Zukunft zu sein scheint. Vielleicht möchten Sie sogar die Tatsache erwähnen, die sie natürlich schon wissen sollten: Es ist am besten, wenn die Leute nicht zulassen, dass ihre Fähigkeiten stagnieren. Aber das war's auch schon: Wenn sie es nicht kaufen, können Sie nichts tun.
Sie können andere Überlegungen haben, die Sie nicht haben, weil Sie nicht auf ihrer Ebene denken. Sie denken als Ingenieur, vielleicht denken sie mehr in betriebswirtschaftlicher oder sogar in personeller Hinsicht.
Verbessern Generika (oder was auch immer) den Wert ihres Produkts? Wahrscheinlich nicht.
Werden Generika (oder was auch immer) es den Leuten schwerer machen, die sie bereits angeheuert haben, um ihre Arbeit zu erledigen? Ja.
Werden Generika die Time-to-Market verbessern? Wenn der einzige Ingenieur Sie war, vielleicht. Aber wenn eine ganze Reihe von Ingenieuren über Generika unterrichtet werden müssen, bevor eine andere Codezeile im Haus geschrieben wird, Nein.
Vielleicht möchten Sie nur einen Jobwechsel in Betracht ziehen. In meinem letzten Job war ich der erste, der Generika mit Java verwendete, und zum Glück hatten sie kein Problem damit. Sie äußerten die Besorgnis, dass Generika das Lesen von Code „erschweren“, aber sie ließen mich meinen Weg. Finde so einen Job.
quelle
Ich würde dem Code-Reviewer und anderen Kollegen die Vorzüge von Generika im Vorfeld einer Überprüfung mitteilen:
1) Indem Sie Typen angeben können, auf die eine generische Klasse oder Methode einwirkt, verlagert die generische Funktion die Last der Typensicherheit von Ihnen auf den Compiler. Es ist nicht erforderlich, Code zu schreiben, um den korrekten Datentyp zu testen, da dieser zur Kompilierungszeit erzwungen wird. Das Erfordernis des Typgießens und die Möglichkeit von Laufzeitfehlern werden verringert.
2) Generika bieten Typensicherheit ohne den Aufwand mehrerer Implementierungen.
Daher verringern [1] und [2] das Fehlerrisiko im Code. Das spart dem Entwickler Zeit und damit dem Unternehmen Geld.
Wenn die Lesbarkeit ein Problem darstellt, kann die Unbeholfenheit bei der Verwendung generischer Typen beeinträchtigt werden. Dies ist ein Grund, warum Sie möglicherweise die Codierungsrichtlinien erweitern möchten. Dies kann im Kontext eines Arbeitstages und nicht nur zum Erweitern von Bibliotheken durchgeführt werden (es empfiehlt sich jedoch, bei Bedarf eine Umgestaltung vorzunehmen und mögliche Methoden für Bibliotheken im Code zu markieren, um sie später leichter erkennen zu können). Daher gibt es keinen Grund, sie nicht in einem Arbeitsalltagskontext zu verwenden.
Ich möchte ein paar Aussagen hinzufügen, wie andere Programmierer keine Probleme mit Generika haben: Generika sind in Java und vielen anderen Sprachen wie C # weit verbreitet. Jeder ernsthafte Programmierer würde es schwer haben, ein Leben ohne solche sicheren Bausteine zu führen.
Sie sollten jedoch berücksichtigen, dass einige der Entwickler möglicherweise nicht auf dem neuesten Stand sind. Das Management hätte sich bewusst dafür entscheiden können, Projekte in der Vergangenheit zu schützen, um diese Kerle von gefährlichen Bereichen fernzuhalten. Hier werden in der Regel sowohl die Unschuldigen als auch die Schuldigen dafür verantwortlich gemacht, da nur selten eine ausreichende Analyse oder ein Mikromanagement durchgeführt wird.
Wenn Sie eine gute Argumentation vorbringen und im Gegenzug keine begründete Antwort erhalten, suchen Sie heimlich nach einem anderen Unternehmen, das die Programmierung ernst nimmt.
quelle
Wenn Sie nicht der Architekt / Techniker sind, wird es schwierig sein, die Verwendung von Generika / Vorlagen zu fordern. Sie sollten die generische / Template-Lösung wirklich lange vor der Codeüberprüfung vorschlagen, vorzugsweise bevor Sie mit der Implementierung beginnen.
Was Sie tun können, ist zu demonstrieren, warum Sie in einigen Fällen ein Generikum verwenden sollten. Wenn Sie die Vorteile nachweisen können, stimmen Ihre Kollegen möglicherweise zu. Die möglichen Gründe, warum Sie Generika / Vorlagen verwenden sollten, sollten folgende sein:
In einem kürzlich durchgeführten Java-Projekt habe ich einige allgemeine abstrakte Klassen erfolgreich hinzugefügt, weil sie einige grundlegende Dinge erfüllten: Sie erleichterten die Arbeit der anderen im Team, erzwangen das vom Architekten bereits vorgeschlagene Muster und verfügten über einen gemeinsamen Code, den Programmierer nicht benötigten Kopieren und Einfügen. Es war ein einfaches Muster, das der Architekt darüber schrieb, dass einigermaßen kompetente Leute immer noch Unrecht hatten (wegen der Komplexität des tatsächlichen Systems im Spiel), aber die Generika markieren, welche Klasse wohin führt.
Natürlich kann ich das wirkliche Beispiel nicht vorführen, ohne die Geheimhaltungsvereinbarung zu verletzen. Als Beispiel für das, was ich getan habe, wäre es, das Strategiemuster zu machen und es mit Generika durchzusetzen. Das ist also das Strategiemuster:
Damit die Programmierer dieses Muster erzwingen können, können Sie den generischen Typ hinzufügen, für den
Context
einStrategy
Typ verwendet werden soll. Codemäßig würde es in Java ungefähr so aussehen:Soweit ich weiß, kannst du das mit jedem Muster machen. Stellen Sie sicher, dass Sie Ihr generisches / Template-Design mit Unit-Tests testen können, um sicherzustellen, dass es funktioniert, um Vertrauen in das Code-Design zu haben.
Wenn Ihre Kollegen die Idee nicht mögen, nehmen Sie sie nicht persönlich, es wäre vielleicht nicht so einfach für sie, sie zu handhaben, wie Sie dachten. Aus diesem Grund sollten Sie eine generische Lösung / Vorlagenlösung vorschlagen, bevor Sie mit der Implementierung beginnen. Sie müssen noch mit Ihren Kollegen zusammenarbeiten, um das eigentliche Problem auf eine andere Weise zu lösen.
quelle
Es gibt immer mehrere Möglichkeiten, dasselbe zu tun. Wenn Ihre Verwendung von Vorlagen ein Missbrauch von Vorlagen ist, sollte die Codeüberprüfung fehlschlagen.
Wenn Ihr Code die Überprüfung jedoch nicht besteht, weil er keine Vorlagen versteht, liegt ein anderes Problem vor. In diesem Fall empfehlen Sie ihnen (auf nette Weise), Vorlagen zu lernen.
quelle
Sie haben es hier mit einer Sammlung von Vorurteilen zu tun. Die Menschen bevorzugen den Status quo, es hat sich ein Groupthink herausgebildet, und das Argument wurde einige Male geführt, damit sich die Menschen in ihren Überzeugungen festsetzen.
Eine der effektivsten Strategien ist es, sich auf einen winzigen Sieg zu konzentrieren. Ich habe das folgende Beispiel in einem Buch gelesen : Der Autor war ein überzeugter Nicht-Apple-Benutzer. Sie mochte sie nicht und wollte nichts mit ihnen zu tun haben. Sie hatte viele Gespräche mit Leuten, die für Apple waren, und jeder drückte ihre Fersen tiefer in den Boden. Dann kaufte ihr jemand einen iPod shuffle und so verschwanden ihre Vorurteile. Es brachte sie nicht dazu, nur Apple-Produkte zu kaufen, aber die harte, fest verwurzelte Anti-Apple-Haltung war durch eine ausgewogenere Sichtweise ersetzt worden. Es gab Raum für Kompromisse, und sie stellte sich langsam ganz auf Apple um.
Versuchen Sie also nicht, alle auf einmal zu überzeugen: Es wird den gegenteiligen Effekt haben. Konzentrieren Sie sich auf eine Kleinigkeit, und der Rest wird von selbst passieren. Beseitigen Sie einfach die zweiseitige Natur des Arguments, damit die Leute nach und nach überqueren können, anstatt alles auf einmal.
Der spezifische Punkt, auf den Sie sich konzentrieren müssen, hängt von Ihrer Situation ab. Hier ist jedoch eine Idee: Die von Ihnen skizzierte Trennung zwischen Bibliotheken und 'echtem Code' erscheint sehr unnatürlich. Meiner Ansicht nach sollte ein Programmierer, der eine Anwendung erstellt, 80% seiner Zeit in einer Bibliothek für die Art der Anwendung verbringen, die er erstellt, und 20% in dieser Bibliothek, um die Anwendung zu erstellen. Jeder Code, der es wert ist, aufbewahrt zu werden, sollte als Bibliothek betrachtet werden. Ich würde Ihren Vorgesetzten vorschlagen, einen Teil Ihres Codes in einer internen Bibliothek zu verallgemeinern (falls Sie dies noch nicht getan haben). Nach eigener Logik sollten sie hierfür Generika verwenden, und nach der obigen Schätzung können 80% Ihres Codes in der Bibliothek landen. Sobald Sie alle dazu bringen, Generika von der anderen Seite zu verwenden, sollten sie sich daran gewöhnen, und die Vorurteile sollten verblassen.
quelle
Beachten Sie "verständlich". Wenn der Code-
<<<>>>
Prüfer den Nutzen von Generika nicht sieht, ist alles, was er benötigt, nur unverständliches Rauschen.Ich würde vorschlagen, einen Blick darauf zu werfen, wie viele aktuelle (offene oder kürzlich behobene) Fehler in Ihrer Bug-Datenbank vorhanden sind, die durch die Verwendung von Generika vermieden werden könnten. Suchen Sie nach ClassCastExceptions.
Beachten Sie auch, dass wenn Sie keine Fehler haben, die durch die Verwendung von Generika hätten vermieden werden können, Ihre Kollegen den Punkt haben, dass Sie sie nicht benötigen.
quelle
Ich würde das einfach angehen. Ich bin vor ein paar Jahren von Java 1.4 auf 1.6 umgestiegen, und Generika waren ein echter Ruck. Es ist einfach und sehr hilfreich, wenn Sie versuchen, ein paar Sammlungen, Karten und andere Strukturen unter einen Hut zu bringen. Das Schreiben von Klassen, die generische Daten als Parameter verwenden, bearbeiten und an andere Klassen weitergeben, wird jedoch schnell zu einer enormen Verwirrung. Ich bin sehr zufrieden damit, dass alles funktioniert, frage mich aber, ob sich die zusätzliche Zeit und Mühe gelohnt hat. Ich befürchte auch, dass eine gute Anzahl von Java-Programmierern nie wirklich den Dreh rausbekommt.
Noch ein paar zufällige Gedanken von meiner bisherigen Reise:
@SuppressWarnings(value="unchecked")
gelegentlich verwendet werden müssen. Woher weißt du, ob du dich jenseits der Grenzen von Generika befindest oder ob du nur dumm bist und härter nachdenken musst?@SuppressWarnings(value="unchecked")
, nur auf eine Zeile zuzutreffen.Generics hat meinen Code bereinigt und mich zu oft vor Problemen gewarnt, als dass ich ihn ablehnen könnte, aber ich sehe auch eine längere Entwicklungszeit, zusätzliche Schulungszeit und Java-Programmierer, die gezwungen sind, in C #, C und Visual Basic zu arbeiten. ..oder Java 1.4. Ich würde mich darauf konzentrieren, Code zu schreiben, den Ihre Mitarbeiter verstehen können. Wenn Sie sich verständliche Generika zulegen können, großartig. Ich sehe Java-Generika als Chance / Problem, das noch nicht herausgefunden wurde.
quelle