Wie kann das Bewusstsein für generisches Programmieren unter den Teammitgliedern verbreitet werden?

20

Ich wohne in einer Umgebung, in der die Leute glauben:

  1. Java-Generika sind die Funktion, die ausschließlich für das Schreiben von Bibliotheken und nicht für die eigentliche Codierung verwendet wird.
  2. C ++ ist eine OO-Programmiersprache. templateist 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 templates 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?

iammilind
quelle
11
Ich wünsche Ihnen viel Glück, aber Sie werden wahrscheinlich gehen müssen, wenn Sie Ihren Weg wollen ..
The Muffin Man
3
@TheMuffinMan, Sie haben recht. Ich habe diesen Arbeitsplatz verlassen und habe jetzt meine eigene Firma. Hier habe ich die volle Kontrolle über die Codierung!
iammilind

Antworten:

14

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()oder public 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 finden

3. 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!

   public class Business<S extends Datastore>{
      private S store; ...
   }

Jetzt können Sie Ihre BusinessObjekte 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:

  1. Bibliotheken,
  2. Konfigurationen und
  3. schlechter Code.

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.

Philip JF
quelle
7
Ich mag die Vorstellung , dass normal codenicht existiert und dass es nur drei Arten: libraries, configurationsund bad 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.
Spoike
3
Selbst C ++ - Vorlagen sind nicht so schwer zu verwenden, wenn Sie sie nicht für die Metaprogrammierung von Vorlagen verwenden. :-)
In silico
-1 für den Hinweis, dass jeder, der sich gegen die Verwendung von Generika entscheidet, dies nur deshalb tut, weil er nicht weiß, wie die Funktion funktioniert.
tp1
Angesichts des Missbrauchspotenzials würde ich sagen, dass das Einschränken / Nichtverwenden von Generika / Vorlagen eine viel bessere Entscheidung sein kann, als Sie es zu schätzen wissen.
Ryathal
Menschen, die sich weigern, Generika / Vorlagen für das umfangreiche Software-Engineering zu verwenden, werden versehentlich und unweigerlich eine "zweite Sprache" erstellen - einen Interpreter, der auf Java läuft und die von ihnen gewünschte "Geschäftssprache" implementiert. en.wikipedia.org/wiki/Inner-platform_effect
rwong
16

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.

Mike Nakis
quelle
9

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.

CarneyCode
quelle
7

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:

  • Sie sollten weniger Code für sich wiederholende Aufgaben schreiben können
  • Das erleichtert dem Programmierer die Arbeit
  • Es erzwingt ein vom Lösungsarchitekten festgelegtes Muster
  • Es kapselt gemeinsame Funktionen, die die Programmierer zwingen würden, Code nicht zu kopieren und einzufügen (dh das Problem der doppelten Wartung zu vermeiden).
  • Es ist ein vernünftiger Zukunftsbeweis für Ihren Code (obwohl es schwierig ist, über diesen Weg nachzudenken).

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:

Bildbeschreibung hier eingeben

Damit die Programmierer dieses Muster erzwingen können, können Sie den generischen Typ hinzufügen, für den Contextein StrategyTyp verwendet werden soll. Codemäßig würde es in Java ungefähr so ​​aussehen:

// declare the generic Context class that has a type "S" 
// that is an upper bound class of Strategy
public class Context <S extends Strategy> {
    S strategy;

    // Constructor with an initial strategy
    public Context(S initialStrategy) {
        this.strategy = initialStrategy;
    }

    public void doSomething() {
      strategy.execute(); // assumes that Strategy has an execute() method.
    }

    public void setStrategy(S strategy) {
        this.strategy = strategy;
    }
}

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.

Spoike
quelle
Lieben Sie das Diagramm! Welches Tool hast du benutzt?
Yannis
@YannisRizos Ich habe die yuml.me verwendet , die Diagramme aus Texteingaben erstellt. Der Beta-Service ist im Moment allerdings etwas fehlerhaft (Sie können das generierte Bild jedoch über den generierten Link in Ihren Beitrag hochladen).
Spoike
mit Lesezeichen versehen, danke fürs Teilen. Obwohl ich nicht wirklich eine andere Syntax lernen möchte, so simpel sie auch sein mag, sie sieht cool aus und ich werde sie irgendwann ausprobieren.
Yannis
@YannisRizos Oh, ich vergesse ständig die Syntax selbst. Deshalb gibt es eine praktische Musterseite . Ich fand es schneller, einfache Klassendiagramme in yuml zu schreiben, als Visio zu verwenden.
Spoike
@YannisRizos yUml ist ein cooles Tool. Hier sind einige andere Beispiele, wie Sie damit umgehen
CarneyCode
4

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.

BЈовић
quelle
4

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.

Peter
quelle
Danke Peter, es war eine sehr aufschlussreiche Antwort. Ihre Gedanken gelten nicht nur für meine Frage, sondern auch für die allgemeine Philosophie unseres Alltags.
iammilind
2

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
2

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:

  • ClassCastExceptions treten zur Laufzeit auf, werden jedoch normalerweise bei den ersten Durchläufen angezeigt und sind einfach zu beheben.
  • In jedem Artikel, den ich über Generika gelesen habe, heißt es, dass sie manchmal einfach nicht funktionieren und @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?
  • Es kann schwierig sein @SuppressWarnings(value="unchecked"), nur auf eine Zeile zuzutreffen.
  • Ich habe einer meiner Klassen ein paar ausgefallene Generika hinzugefügt. Ich habe mehrere Programmierer gekannt, die die Klasse hätten verbessern können, bevor ich sie generierte, die sie niemals hätten anfassen können, und danach eine saubere Kompilierung bekommen.

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.

RalphChapin
quelle