Come diffondere la consapevolezza per la programmazione generica tra i membri del team?


20

Sto in un ambiente in cui le persone credono:

  1. I generici Java sono la funzione utilizzata esclusivamente per la scrittura di librerie e non per la vera codifica.
  2. C ++ è un linguaggio di programmazione OO; templateè una funzione opzionale ed evitabile

Tuttavia, queste persone fanno molto affidamento sulle librerie scritte usando una programmazione generica (ad es. Contenitori STL, Java). Se scrivo un codice usando templates o generics, è molto probabile che il revisore del codice lo rifiuti e commenterà per scriverlo in modo "corretto / comprensibile / elegante" .

Tale mentalità è applicabile dal normale programmatore al senior manager. Non c'è via d'uscita, perché il 90% delle volte queste persone hanno le loro pressioni.

Qual è il modo migliore ( non essere tagliato alla gola ) di spiegarli, l'approccio pratico di scrivere codice che costituisce OO e programmazione generica allo stesso tempo?


11
Ti auguro buona fortuna, ma probabilmente dovrai andartene se vuoi la tua strada ..
The Muffin Man

3
@TheMuffinMan, hai ragione. Ho lasciato quel posto di lavoro e ora ho la mia compagnia. Qui ho il controllo completo sulla codifica!
iammilind,

Risposte:


14

Ci sono ancora persone al mondo che non lo fanno usano i generici di jave nel "codice ordinario". Posso crederci con i modelli C ++, ma generici? Non sono nemmeno difficili da imparare / usare. Seriamente le migliori caratteristiche di Java e C ++ sono rispettivamente generici e template.

Il modo migliore per convincere la gente delle cose è di fare un argomento convincente, di non essere minaccioso e di avere ragione.

Finché non stai facendo qualcosa come usare i template come linguaggio di programmazione, il polimorfismo parametrico (generici / template) è quasi certamente buono.

1. Evita la duplicazione del codice.

Questo è ovvio, ma il codice polimorfico è un codice generale. Ecco perché si chiama generici.

2. Supporta un migliore controllo statico.

Senza polimorfismo parametrico finisci per scrivere cose come public Object clone()o public boolean equals(object b)che non sono solo abominazioni, hanno tipi che non forniscono informazioni su ciò che fanno e finiscono invariabilmente con l'eccezione. L'alternativa al polimorfismo parametrico è il cast dappertutto

3. Il polimorfismo non parametrico Il codice OOP non è sostanzialmente in grado di gestire i "metodi binari" in modo corretto.

Li usi spesso.

4. È la migliore pratica

In Java, l'uso dei generici è considerato la migliore pratica (vedi Effective Java di Josh Bloch). I maggiori pensatori del C ++ come Sutter e Alexandrescu incoraggiano anche l'uso di modelli per risolvere una varietà di problemi.

5. Si adatta al paradigma OO.

La gente spesso non se ne accorge, ma la combinazione di sotto-tipizzazione e generici produce un sistema MOLTO più potente espressivo e orientato agli oggetti di qualsiasi sistema con solo uno di essi.

Considera i mixin di Scala. Questa è una bella funzionalità che ti consente di riunire i tuoi oggetti dalle parti componenti. I generici e i modelli possono simulare alcuni di questi vantaggi. Ad esempio, supponiamo che uno dei tuoi oggetti utilizzi un database. Un buon design ti farebbe astrarre l'accesso al database in una classe separata. Se fatto bene, questo non solo ti consente di deridere il tuo archivio di dati (chiave per la testabilità), ma significa anche che puoi aggiungere implementazioni alternative come quel nuovo database no-sql. Qui, tuttavia, potresti avere un problema, indipendentemente dall'implementazione che utilizzerai, otterrai diverse funzionalità dell'oggetto aziendale.

Generici in soccorso!

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

Ora puoi iniziare a differenziare staticamente i tuoi Businessoggetti in base alla capacità di utilizzare funzionalità specifiche del database. Hai ancora bisogno di alcuni controlli di runtime e casting, ma puoi iniziare a costruire codice MOLTO migliore.

e

6. Il codice normale non esiste.

Ci sono solo tre cose nell'universo di programmazione:

  1. biblioteche,
  2. configurazioni e
  3. codice errato.

Se non pensi al tuo codice come se fosse una libreria, sei nei guai seri quando cambiano i requisiti per il tuo progetto. L'architettura è (probabilmente) l'arte di progettare buone API.

Trovo questo atteggiamento sbalorditivo. Dopo esserti abituato alla programmazione con tipi parametrizzati, non usarli rende tutto un problema. E, Java e C ++ hanno un sacco di punti difficili che aiutano a porre rimedio.


7
Mi piace l'idea che normal codenon esiste e che ci sono solo tre tipi: libraries, configurationse bad code. È un ragionamento idealista, sebbene tu debba ancora spiegarlo ai tuoi colleghi, che potrebbero non essere idealisti come te. Sono d'accordo però che l'uso di tipi parametrizzati sia semplicemente fantastico una volta capito.
Spoike,

3
Diamine, anche i modelli C ++ non sono così difficili da usare se non li usi per scopi di metaprogrammazione dei modelli. :-)
In silico,

-1 per aver suggerito che chiunque decida di non usare generici lo fa solo perché non sa come funziona la funzione.
tp1,

dato il potenziale di uso improprio, direi che limitare / non usare generici / modelli può essere una decisione molto migliore che gli dai credito.
Ryathal,

Le persone che rifiutano di usare generici / modelli per l'ingegneria del software su larga scala costruiranno accidentalmente e inevitabilmente una "seconda lingua" - un interprete che gira su Java, che implementa qualunque "linguaggio aziendale" abbiano in mente. en.wikipedia.org/wiki/Inner-platform_effect
rwong

16

Questa è una forma specializzata della domanda più generale "come convinci i tuoi superiori a iniziare a utilizzare una tecnologia / un modo nuovo e migliore di fare le cose?"

Sfortunatamente, non penso che tu possa, e non sono sicuro che dovresti. È per definizione la loro scelta, poiché ti stanno pagando per fare le cose in un certo modo che hanno scelto, non nel modo che preferisci. Il meglio che puoi fare è suggerire che questa tecnologia è là fuori, molte persone la stanno usando e sembra essere la via del futuro. Potresti anche voler menzionare il fatto che ovviamente dovrebbero già sapere: è meglio che le persone non lascino stagnare le loro abilità. Ma è tutto: se non lo acquistano, non c'è niente che tu possa fare.

Potrebbero avere altre considerazioni che non hai, perché non stai pensando al loro livello. Stai pensando come un ingegnere, potrebbero pensare di più in termini commerciali o anche in termini di risorse umane.

  • I generici (o qualsiasi altra cosa) miglioreranno il valore del loro prodotto? Probabilmente no.

  • I generici (o qualsiasi altra cosa) renderanno più difficile per le persone che hanno già assunto per fare il loro lavoro? Sì.

  • I generici miglioreranno il time-to-market? Se tu fossi l'unico ingegnere, forse. Ma se un intero gruppo di ingegneri deve essere istruito sui generici prima che un'altra riga di codice sia scritta in casa, No.

Quindi, potresti prendere in considerazione l'idea di cambiare lavoro. Nel mio ultimo lavoro sono stato il primo a usare i generici con Java, e fortunatamente non hanno avuto problemi; hanno espresso la preoccupazione che i generici rendano il codice "più difficile da leggere", ma mi hanno lasciato fare a modo mio. Trova un lavoro simile.


9

Trasmetterei i meriti dei generici al revisore del codice e ad altri colleghi prima di qualsiasi recensione:

1) Consentendo all'utente di specificare i tipi su cui agisce una classe o un metodo generico, la funzione generics sposta il carico della sicurezza dei tipi da te al compilatore. Non è necessario scrivere il codice per verificare il tipo di dati corretto poiché viene applicato al momento della compilazione. La necessità di eseguire il cast del tipo e la possibilità di errori di runtime sono ridotti.

2) I generici forniscono la sicurezza del tipo senza il sovraccarico di molteplici implementazioni.

Pertanto, [1] e [2] riducono il rischio di errore nel codice. Ciò consente di risparmiare tempo per gli sviluppatori e quindi i soldi dell'azienda.

Se la leggibilità è un problema, l'imbarazzo dell'utilizzo di tipi generici potrebbe essere compromesso. Questo è uno dei motivi per cui potresti voler estendere le linee guida per la codifica. Questo può essere fatto in un contesto di giorni lavorativi e non solo per l'estensione delle librerie (tuttavia, è un'idea di refactoring mentre si procede e contrassegnare possibili metodi candidati per le librerie nel codice per un facile riconoscimento in seguito). Pertanto, non vi sarebbe motivo di non utilizzarli in un contesto quotidiano.

Vorrei aggiungere alcune affermazioni su come gli altri programmatori non abbiano problemi con i generici: i generici sono ampiamente usati in Java e in molti altri linguaggi come C #. Qualsiasi programmatore serio troverebbe la vita difficile senza blocchi di questo tipo sicuri.

Tuttavia, potresti voler considerare che alcuni sviluppatori potrebbero non essere all'altezza. Il management avrebbe potuto prendere una decisione consapevole per proteggere i progetti in passato, mantenendo così questi tipi fuori dalle aree pericolose. Qui, sia gli innocenti che i colpevoli di solito ricevono la colpa in quanto raramente vengono condotte analisi sufficienti o micro-gestione.

Se metti avanti un buon caso e non ti viene data una risposta motivata in cambio, allora segretamente inizi a cercare un'altra società che prende sul serio la programmazione.


7

A meno che tu non sia il capo architetto / tecnico, sarà difficile imporre che dovresti usare generici / modelli. Dovresti davvero proporre la soluzione generica / modello molto prima della revisione del codice, preferibilmente prima di iniziare a implementarla.

Quello che puoi fare è dimostrare perché in alcuni casi dovresti usare un generico. Se puoi dimostrare i vantaggi, i tuoi colleghi potrebbero essere d'accordo. I possibili motivi per cui dovresti usare generici / template dovrebbero essere i seguenti:

  • Dovrebbe consentire di scrivere meno codice per le attività ripetitive
  • Semplifica il lavoro dei programmatori
  • Applica un modello impostato dall'architetto della soluzione
  • Incapsula funzionalità comuni, che costringerebbero i programmatori a non copiare e incollare il codice (evitando il doppio problema di manutenzione)
  • È ragionevolmente a prova di futuro il tuo codice (anche se questa strada è difficile da ragionare)

In un recente progetto Java ho aggiunto con successo alcune classi astratte generiche perché soddisfacevano alcune cose di base: rendeva le cose più facili per gli altri nel team, applicava il modello che l'architetto aveva già proposto e aveva un codice comune che i programmatori non avevano bisogno copia e incolla. Era un modello semplice che l'architetto scrisse sul fatto che le persone ragionevolmente competenti si sbagliavano (a causa della complessità del sistema reale in gioco), ma i generici segnano quale classe va dove.

Ovviamente non posso mostrare il vero esempio senza violare l'accordo di non divulgazione. Ma come esempio di ciò che ho fatto sarebbe stato fare il modello di strategia e applicarlo con i generici. Quindi questo è il modello di strategia:

inserisci qui la descrizione dell'immagine

E affinché i programmatori possano applicare questo modello, è possibile aggiungere il tipo generico in modo Contextche dovrebbe utilizzare qualcosa che ha un Strategytipo. Per quanto riguarda il codice sarebbe simile a questo in Java:

// 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;
    }
}

Puoi farlo praticamente con qualsiasi modello, per quanto ne so. Assicurati di poter testare il tuo design generico / modello con unit test per vedere che funziona, al fine di avere fiducia nella progettazione del codice.

Se ai tuoi colleghi non piace l'idea, non prenderla sul personale, potrebbe non essere stata resa una soluzione così facile da gestire come pensavi. Ecco perché dovresti proporre una soluzione generica / modello prima di iniziare a implementarla. Devi ancora collaborare con i tuoi colleghi per risolvere il problema in modo diverso.


Adoro il diagramma! Quale strumento hai usato?
yannis,

@YannisRizos Ho usato yuml.me che crea diagrammi dall'inserimento di testo. Al momento il servizio beta è un po 'difettoso (puoi comunque caricare l'immagine generata sul tuo post usando il link generato).
Spoike,

aggiunto ai segnalibri, grazie per la condivisione. anche se non voglio davvero imparare un'altra sintassi, per quanto semplicistica, sembra interessante e ci proverò a un certo punto.
yannis,

@YannisRizos Oh, dimentico costantemente la sintassi da solo. Ecco perché c'è una comoda pagina di esempi . Ho trovato più veloce scrivere semplici diagrammi di classe in yuml che usare Visio.
Spoike,

@YannisRizos yUml è uno strumento interessante. Ecco alcuni altri esempi di cosa puoi farci: carnotaurus.philipcarney.com/tagged/yUML
CarneyCode

4

Esistono sempre diversi modi per fare la stessa cosa. Se il tuo uso dei modelli è un uso improprio dei modelli, la revisione del codice non dovrebbe riuscire.

Tuttavia, se la revisione del codice non riesce, poiché non comprendono i modelli, il problema è di diverso tipo. In tal caso, consiglia loro (in modo carino) di imparare i modelli.


4

Quello di cui hai a che fare qui è una raccolta di pregiudizi. Le persone preferiscono lo status quo, si è sviluppato un pensiero di gruppo e l'argomento è stato condotto alcune volte in modo che le persone si siano trincerate nelle loro credenze.

Una delle strategie più efficaci qui è concentrarsi su una piccola vittoria. Ho letto il seguente esempio in un libro : l'autore era un fedele utente non Apple. Non le piacevano e non voleva avere niente a che fare con loro. Ha avuto molte discussioni con persone con una posizione pro-Apple, e ognuna ha appena spinto i talloni più a fondo nel terreno. Poi qualcuno le ha comprato un iPod shuffle e così, i suoi pregiudizi sono scomparsi. Non le fece venire voglia di acquistare solo prodotti Apple, ma la posizione anti-Apple, dura e radicata, era stata sostituita da un punto di vista più equilibrato. C'era spazio per un compromesso e finì lentamente per convertirsi interamente in Apple.

Quindi non cercare di convincere tutti in una volta: avrà l'effetto opposto. Concentrati su una piccola cosa e il resto accadrà da solo. Basta sbarazzarsi della natura a due facce dell'argomento in modo che le persone possano attraversare a poco a poco, invece che tutte in una volta.

Il punto specifico su cui concentrarsi dipende dalla tua situazione, ma ecco un'idea: la divisione che disegni tra le biblioteche e il "codice reale" sembra molto innaturale. Dal mio punto di vista, un programmatore che fa una domanda dovrebbe trascorrere l'80% del suo tempo in una biblioteca per il tipo di applicazione che sta facendo e il 20% usando quella biblioteca per costruire l'applicazione. Tutto il codice che vale la pena conservare dovrebbe essere considerato una libreria. Suggerirei ai tuoi superiori di generalizzare parte del tuo codice in una biblioteca interna (se non l'hai già fatto). Per loro stessa logica, dovrebbero usare i generici per questo, e secondo la stima sopra, l'80% del tuo codice può finire all'interno della libreria. Una volta che tutti usano i generici dall'altra parte, dovrebbero abituarsi e i pregiudizi dovrebbero svanire.


Grazie Peter, è stata una risposta molto perspicace. I tuoi pensieri si applicano non solo alla mia domanda, ma anche alla filosofia generale della nostra vita quotidiana.
iammilind,

2

Nota "comprensibile". Se il revisore del codice non vede il vantaggio dei generici, allora tutto il <<<>>>roba è solo un rumore incomprensibile che non è necessario.

Suggerirei di dare un'occhiata a quanti effettivamente, attuali bug (aperti o corretti di recente) che il database dei bug contiene che avrebbero potuto essere evitati usando i generici. Cerca ClassCastExceptions.

Si noti inoltre che se non si dispone di alcun bug che avrebbe potuto essere evitato utilizzando i generici, i colleghi hanno ragione nel dire che non sono necessari.


2

Andrei piano con questo. Sono passato da Java 1.4 a 1.6 un paio di anni fa e i generici sono stati una vera scossa. È semplice e molto utile se stai cercando di destreggiarti tra alcune raccolte, mappe e altre strutture. Tuttavia, la scrittura di classi che accettano dati generici come parametri, li manipola e li passa ad altre classi rapidamente diventa monumentalmente confusa. Ho una grande soddisfazione nel far funzionare tutto, ma mi chiedo se ne sia valsa la pena. Temo anche che un buon numero di programmatori Java non riesca mai a capirlo.

Alcuni pensieri casuali dal mio viaggio generico finora:

  • ClassCastExceptions si verificano in fase di esecuzione, ma in genere vengono visualizzate nelle prime esecuzioni e sono facili da correggere.
  • Ogni articolo che ho letto sui farmaci generici afferma che a volte non funzionano e che è necessario utilizzarlo di @SuppressWarnings(value="unchecked")tanto in tanto. Come fai a sapere se sei oltre i limiti dei generici o se sei solo stupido e hai bisogno di pensare di più?
  • Può essere difficile applicare @SuppressWarnings(value="unchecked")a una sola riga.
  • Ho aggiunto alcuni generici fantasiosi a una delle mie lezioni. Ho conosciuto diversi programmatori che avrebbero potuto migliorare la classe prima di generarla, che non avrebbero mai potuto toccarla e ottenere una compilazione pulita in seguito.

Generics ha ripulito il mio codice e mi ha avvertito di troppi problemi perché potessi rifiutarlo, ma vedo anche un tempo di sviluppo maggiore, tempo extra dedicato alla formazione e programmatori Java costretti a lavorare in C #, C e Visual Basic. ..o Java 1.4. Mi concentrerei sulla scrittura di codice che i tuoi colleghi possano capire. Se riesci a scivolare in alcuni generici comprensibili, fantastico. Vedo i generici Java come un'opportunità / problema che non è stato ancora capito.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.