Che cosa è il codice bello in C ++ e perché la maggior parte dei programmatori si preoccupa così tanto? [chiuso]

8

Poiché la maggior parte dei progetti utilizza un'API C ++, si occupano dei vincoli dell'API e dei vincoli del progetto stesso.

Sono un principiante in programmazione, non mi piace affatto usare OOP perché nessuno è riuscito a spiegarmi chiaramente PERCHÉ è così importante limitarsi a un ambito privato per impedire ad altri programmatori di rompere la coerenza dell'organizzazione dei dati qualche tipo.

Posso ancora andare bene con OOP, dato che permette ancora di fare cose grandiose come Qt e Ogre3D, ma quelle sono solo API, non applicazioni, e quei codici devono essere perfetti in modo che nessuno possa criticare il lavoro.

Non capisco perché la maggior parte dei programmatori, dal momento che fanno app e non API, vogliono fare codice perfetto come progettano un pezzo geniale di codice e perdono tempo su questo.

    
posta jokoon 08.07.2011 - 14:19
fonte

8 risposte

12

Hai mai sentito il detto "Nessun uomo è un'isola" ?

Per la maggior parte dei programmatori questo è vero. Quasi nessuno scrive codice che è "solo un'app". Su molte app non banali un programmatore scrive l'interfaccia utente che deve essere facilmente modificata da un designer. Inoltre, deve consentire l'associazione di dati chiari alla logica aziendale (Controller, ViewModel o qualsiasi altra cosa si voglia chiamare). Un altro programmatore scrive quel controller, che può essere spesso estremamente complesso, ma deve essere abbastanza semplice da essere facilmente utilizzato dal programmatore front-end. Quel codificatore di business logic sta consumando codice da chiunque abbia scritto il livello dati (Modello, Deposito, ecc.). Non è necessario utilizzare OOP, tuttavia, ciò che OOP è piuttosto bravo a ti permette di incapsulare la logica dietro un'interfaccia in modo che altre persone con cui lavori possano usare il tuo codice senza romperlo (presumendo che tu abbia testato quell'interfaccia!). L'astrazione non è il proiettile d'argento, ma sicuramente ti diverte quando usi librerie come Ogre3d, che ti permettono di fare cose che difficilmente riusciresti a realizzare interamente da solo.

Quindi potresti dire ora "Seriamente, sono un'eccezione e nessuno vedrà il mio codice o non lavorerà affatto". Abbastanza corretto, ma quando hai bisogno di correggere un bug in quell'app tra qualche mese, o vuoi aggiungere un paio di funzionalità, probabilmente vedrai che la persona che ha scritto quel codice e la persona che lo sta modificando ora sono due persone totalmente diverse. Spesso pensiamo che ricorderemo le cose, che è il motivo principale per cui scriviamo codice sciatto, ma la verità è che da te tra sei mesi non ricorderà gli hack che hai inserito nella tua applicazione ora. Il tuo io futuro avrà abbastanza cose da affrontare, quindi perché non concedergli una pausa?

    
risposta data 08.07.2011 - 15:17
fonte
43

Any fool can write code that a computer can understand. Good programmers write code that humans can understand. ~Martin Fowler

Questo, in poche parole, è il motivo per cui ti interessa il bel codice.

Non scrivi codice per il computer. Il computer capisce comunque il codice binario (che è prodotto dal codice sorgente tramite compilatori e interpreti). Non importa della bellezza o della chiarezza o anche se il tuo codice fa quello che dovrebbe fare.

Scrivi il codice per i tuoi colleghi programmatori. E fanno lo stesso per te. Se non riesci a capire un pezzo di codice scritto da qualcun altro, allora cosa pensi che le tue possibilità siano di trovare e correggere un bug o aggiungere nuove funzionalità?

    
risposta data 08.07.2011 - 14:56
fonte
3

Ciò che altri hanno detto come se non sapessi mai se potresti aver bisogno del tuo codice di nuovo in futuro è giusto, naturalmente.

Ma per me c'è un punto importante, perché cerco sempre di scrivere codice bello:

È l'allenamento per migliorare.

Se imparo qualcosa di nuovo su una lingua che uso o su alcuni concetti di programmazione generale, cerco immediatamente di farne uso, provo a renderlo parte del mio flusso di lavoro quotidiano e della nostra toolchain mentale.

Se leggi solo qualcosa come OOP, ne dimenticherai la maggior parte nel giro di poche settimane. E non otterrai mai l'allenamento come applicarlo correttamente a grossi problemi finché non ti insegni applicandolo a piccoli problemi.

Esempio:

Perché è importante limitarsi a un ambito privato?

Nei piccoli progetti non lo è. Alcune lingue (ad esempio Ruby) addirittura scoraggiano questo tipo di incapsulamento in una certa misura. Ma ci sono usi per questo. Molti.

E l'uso di questo viene fornito con determinati problemi e molti dettagli che devi imparare. Usarlo in piccoli progetti ti insegnerà questo. Vedrai alcuni messaggi di errore del tuo compilatore che sono nuovi per te e in un piccolo progetto sarai in grado di trovare la fonte del problema più facilmente.

Scopri i domini in C ++. Non c'è tanto bisogno per loro in piccoli progetti. Lo stesso vale per la struttura generale dei file di intestazione e include. Puoi imparare tutto questo subito nella protezione di una piccola base di codice.

    
risposta data 01.08.2011 - 12:28
fonte
1

Si tratta di dover mantenere il codice legacy. E in pochi mesi il codice che stai scrivendo diventerà un codice legacy che dovrai anche conservare.

Coding for Violent Psychos

    
risposta data 08.07.2011 - 15:01
fonte
1
  1. Ciò che R0MANARMY ha detto nel suo commento. Pulisci e amp; Il codice "bello" semplifica la lettura, la comprensione, la manutenzione, la modifica e la correzione in futuro, non solo per te stesso, ma per gli altri che ti seguono.

  2. Alcune persone, quando fanno qualcosa, cercano di fare il meglio che possono, nel miglior modo possibile, quindi è "perfetto", o in questo caso, "bello". Ho scoperto che esiste una grande sovrapposizione tra questo gruppo di persone e sviluppatori (incluso me stesso!).

Ricorda però che "bello", "pulito" o "elegante" sono termini altamente soggettivi che significano cose diverse per persone diverse. Da quello che ho visto, codice che è ampiamente considerato bello, pulito e / o elegante,

  • È facile da leggere e capire
  • Nessun codice, o poco, inutile che gira intorno a
  • È facilmente estensibile e / o modulare
  • È ben documentato
  • Segue tutti gli standard per linguaggi / tecnologie correlate
  • E non fa nulla di inaspettato (ad esempio effetti collaterali in un metodo accessor)
risposta data 08.07.2011 - 15:35
fonte
1

Sono d'accordo sulla cosa della manutenibilità. Prova a creare un progetto relativamente grande per te stesso e vedrai tutto il caos che ti lega alle correzioni dei bug, aggiungendo nuove funzionalità, ecc. Ma per parlare di bellezza:

Beautiful code is the desired product quality because (at least, C++) programming is an ART.

    
risposta data 08.07.2011 - 16:26
fonte
1

[...] nobody clearly managed to explain to me WHY it's is so important to restricting yourself with private scope to prevent others programmers to break data organisation consistency of some kind.

In una squadra abbastanza piccola con una base di codice abbastanza piccola, che è davvero ben coordinata con buoni standard (potrebbe essere una sola persona), spesso è possibile trovare software affidabile che lascia tutti i dati alla luce per chiunque sia in contatto con tutti i campi di dati di struct esposti a tutto campo e con la definizione di struct a cielo aperto per chiunque abbia accesso a tale intestazione. La legge di Murphy non si applica sempre in questi casi.

Ma ho lavorato nello scenario opposto di un'enorme base di codice con molti milioni di LOC risalenti agli anni '80 con un grande team di sviluppatori di tutto il mondo in cui ci siamo incontrati faccia a faccia ogni pochi mesi, liberamente - coordinato, a volte a malapena la stessa lingua, senza standard di codifica tranne SDK che la gente spesso non seguiva comunque, nessun test di unità / integrazione, usando SVN senza diramazioni e a volte andando a 6 settimane senza verificare il codice, solo per bombardarci con bug, e non è stato fino ad allora che ho veramente capito il valore di nascondere le informazioni e mantenere gli invarianti .

Mi sono occupato di bug in cui non riuscivo nemmeno a riprodurre il problema in modo coerente sulla mia macchina, ea volte nessuno di noi poteva tra l'intero team. E quando finalmente potevo fortunatamente riprodurre il problema segnalato dall'utente o qualcosa che lo somigliava dopo tutti i tipi di tentativi ed errori (e le prove e gli errori spesso richiedevano ore perché l'inefficienza del nostro software si combinava con l'esecuzione nel debug contro la produzione dell'utente finale i dati richiedevano spesso più di 15 minuti solo per caricare i dati), lo tracciavo a qualcosa come struct per un tipo di stringa che aveva un len impostato su un numero negativo negativo, come una lunghezza di stringa di -921141282 .

Questo non dovrebbe mai accadere, ma chi lo ha fatto? Quindi ho dovuto impostare i punti di interruzione della memoria e scoprirlo, e quando finalmente l'ho fatto, era come un'interazione a cascata di variabili non inizializzate utilizzate aritmeticamente che alla fine si aggiungevano a un campo len di stringhe impostato su un numero di garbage negativo e che il codice non era stato modificato negli anni. Ha volato sotto il radar.

E tutto quel tempo dopo aver incontrato molti bug come questo, ho pensato a me stesso, quanto sarebbe più affidabile il nostro software se usasse solo getters e setters ? Getter e setter sono generalmente indicativi dei peggiori tipi di design di interfacce possibili, ma un setter potrebbe almeno innescare un errore di asserzione se qualcuno tentasse di impostare la lunghezza di una stringa su un valore negativo. Avremmo potuto intercettare quell'errore anni prima nel momento preciso in cui era stato introdotto in secondi, non il culmine di ore di sforzi investigativi. E questo è solo pensare egoisticamente come sviluppatore; non copre tutte le ore di dolore che avrebbe potuto salvare anche gli utenti e il team di QA. Sai che il tuo sistema si trova in un brutto posto quando stai sognando quanto potrebbe essere migliore se usasse setter e getter di fronte agli ultimi 35 bug che hai passato a risolvere tutti i nottambuli.

Abbiamo persino avuto casi in cui structs è stato documentato in un modo che afferma che nessun altro dovrebbe accedere a quei campi di dati, solo per trovare punti nel sistema che accede a quei campi di dati.

Quindi questi sono i tipi di cose che puoi davvero apprezzare al massimo affrontando quello scenario peggiore, ma spesso lo farai a meno che tu non abbia la fortuna di passare il resto della tua vita a lavorare su basi di codice più piccole con team coordinati e forti standard di codifica.

What is beautiful code in C++ [...]?

È difficile. Sto ancora cercando di capirlo. La maggior parte del codice che considero bello che ho scritto nel corso degli anni, o almeno affidabile e relativamente atemporale e stabile (non ho bisogno di / volere cambiamenti) è stata scritta in C e recentemente Lua. Faccio ancora fatica a scrivere codice C ++ che sembra passare la prova del tempo al punto in cui non rifletterò su di esso qualche anno dopo e almeno desidero potrei cambiarlo. Mi sembra che sia diventato più facile dal C ++ 11, ma ho bisogno di alcuni anni per scoprire quanto il mio codice riesce a sopravvivere senza bisogno di modifiche per dirlo con certezza. Per me l'ultima "bellezza" è la "stabilità", come nel codice che non ha bisogno e non tenta nemmeno ulteriori cambiamenti, ma rimane pertinente e utile per gli anni a venire, poiché questo è un codice che comporta costi di manutenzione zero. / p>     

risposta data 19.12.2017 - 09:38
fonte
0

Bene, definire interfacce pulite e utili ("bello" è un qualificatore scadente) significa assicurarsi che:

  1. L'utente comprende con il minimo dolore come utilizzare il tuo oggetto (o sistema di oggetti) semplicemente leggendo la sua interfaccia.
  2. L'utente avrà difficoltà a utilizzare l'oggetto / sistema in modo errato - l'interfaccia rende difficile fare qualcosa di sbagliato o segnalare problemi in anticipo.
  3. L'interfaccia descrive un'astrazione utile.

I punti 1. e 2. richiedono di pensare molto al contratto che stai facendo con il tuo utente. Quel contratto, o protocollo, è il modo per comunicare all'utente come può usare il tuo sistema. Ad esempio, le funzioni membro di sola lettura (funzioni membro const) indicano molto su quali situazioni dovresti essere in grado di chiamare tale funzione. Allo stesso modo, gli attributi di ciascuna funzione divengono l'utente che raccoglie e fornisce le informazioni minime necessarie affinché il sistema funzioni.

Tutti i punti suggeriscono che le tue interfacce dovrebbero mostrare solo servizi utili all'utente. Innanzitutto limitare l'uso del sistema da parte dell'utente solo a ciò per cui è stato realizzato il sistema. Secondo, evitando che manipoli lo stato interno in modo sbagliato. Quindi, il modo più semplice in C ++ per raggiungere questo obiettivo è quello di mettere tutti i membri privati e indicare esplicitamente quali servizi il tuo sistema fornisce, usando funzioni membro o globali (in namespace). Un altro modo è usare l'idioma PImpl.

Terzo, e il più importante: la tua interfaccia dovrebbe fornire un'astrazione utile, il che significa che l'utente non deve comprendere l'implementazione. Quando guido una macchina o una lavatrice, non voglio sapere come è costruita all'interno (anche se sono un fanatico della tecnologia ...). Ho solo bisogno di usarlo e non devo preoccuparmi di cosa c'è dentro.

È difficile.

Qualsiasi definizione di protocollo, come la progettazione di un linguaggio di programmazione o la progettazione di una classe, non è così ovvia come potresti aver pensato prima. È necessaria molta esperienza per apprezzare i subtelties delle interfacce desiging.

Tutto ciò che non è revelant quando si definiscono strutture o classi che rappresentano concetti di livello molto basso. Più alto è il tuo hardware, più devi avere pulito, chiaro e amp; interfacce utili.

    
risposta data 08.07.2011 - 14:39
fonte

Leggi altre domande sui tag