quali sono le regole da rispettare durante il refactoring? | le modifiche al codice non devono modificare le funzionalità: il refactoring DEVE essere invisibile al cliente;
non possono essere aggiunti test aggiuntivi rispetto alla fase verde appena raggiunta. |
quali possono essere i motivi che spingono al refactoring? | - design complesso e poco leggibile
- design che non si integra bene con feature successive. In questo caso, se il refactoring non è banale è bene fermarsi, tornare indietro e evolvere il codice (design for change).
- presenza di debolezze e “scorciatoie” che ostacolano notevolmente evoluzioni future: “ogni debito tecnico lo si ripaga con gli interessi”.
- migliorare l'efficienza del codice |
sotto che forme si puo' presentare il design knolwledge di un progetto? | - Memoria: memoria individuale del programmatore, soggetta a variazioni e dimenticanze...
- Documenti di design (linguaggio naturale o diagrammi): se non viene aggiornato di pari passo con il codice rimane obsoleto, risultando più dannoso che d’aiuto.
- Piattaforme di discussione (version control, issue management): le informazioni sono sparse in luoghi diversi e difficili da reperire ,
le informazioni necessitano di manutenzione.
- gli UML: tramite diagrammi UML si è cercato di sfruttare l’approccio generative programming, ovvero la generazione automatica del codice a partire da specificazioni di diagrammi. (non funziona)
- nel Codice : tramite la lettura del codice è possibile capire il design ma è difficile rappresentare le ragioni della scelta. |
in quali modi puo' essere condiviso il know how? | - metodi: con pratiche (come Agile) o addirittura l’object orientation stessa, che può essere un metodo astratto per condividere scelte di design.
- design pattern: fondamentali per condividere scelte di design, sono utili anche per generare un vocabolario comune (sfruttiamo dei nomi riconosciuti da tutti per descrivere i ruoli dei componenti) e aiutano l’implementazione (i pattern hanno delle metodologie note per essere implementati). I pattern non si concentrano sulle prestazioni di un particolare sistema ma sulla generalità e la riusabilità di soluzioni a problemi comuni;
- principi: per esempio i principi SOLID. |
quali sono le proprieta' dell'object orientation? | - ereditarietà: ovvero la possibilità di poter definire una classe ereditando proprietà e comportamenti di un’altra classe.
- polimorfismo: quando una classe può assumere diverse forme in base alle interfacce che implementa.
- collegamento dinamico: in Java il tipo concreto degli oggetti e quindi il problema di stabilire quale metodo chiamare viene risolto durante l’esecuzione. es:
Forma quadrato = new Quadrato(5);
quadrato.calcolaArea();
non chiama il metodo in forma ma il metodo in quadrato! |
quali sono i principi SOLID? | SINGLE RESPONSIBILITY: una classe, un solo scopo. Così facendo, le classi rimangono semplici e si agevola la riusabilità.
OPEN-CLOSE PRINCIPLE: le classi devono essere aperte ai cambiamenti (opened) ma senza modificare le parti già consegnate e in produzione (closed). Il refactoring è comunque possibile, ma deve essere preferibile estendere la classe attuale.
LISKOV SUBSTITUTION PRINCIPLE: c’è la garanzia che le caratteristiche eredidate dalla classe padre continuinino ad esistere nelle classi figlie. Questo concetto si collega all’aspetto contract-based del metodo Agile: le precondizioni di un metodo di una classe figlia devono essere ugualmente o meno restrittive del metodo della classe padre. Al contrario, le postcondizioni di un metodo della classe figlia non possono garantire più di quello che garantiva il metodo nella classe padre. Fare casting bypassa queste regole.
INTERFACE SEGREGATION: più le capacità e competenze di una classe sono frammentate in tante interfacce più è facile utilizzarla in contesti differenti. In questo modo un client non dipende da metodi che non usa. Meglio quindi avere tante interfacce specifiche e piccole (composte da pochi metodi), piuttosto che poche, grandi e generali.
DEPENDENCY INVERSION: il codice dal quale una classe dipende non deve essere più concreto di tale classe. Per esempio, se il telaio della FIAT 500 dipende da uno specifico motore, è possibile utilizzarlo solo per quel specifico motore. Se invece il telaio dipende da un concetto di motore, non c’è questa limitazione. In conlusione, le classi concrete devono tendenzialmente dipendere da classi astratte e non da altre classi concrete. |
Che cosa afferma la Legge di Parnas? | Solo ciò che è nascosto può essere cambiato liberamente e senza pericoli. |
quali principi deve rispettare una classe per essere immutabile? | una classe si dice immutabile quando il suo stato non puo' essere modificato dopo la sua creazione :
- non fornire metodi di modifica allo stato;
- avere tutti gli attributi privati per i tipi potenzialmente mutabili (come List<T>);
- avere tutti gli attributi final se non già privati;
- assicurare l’accesso esclusivo a tutte le parti non mutabili, ovvero non avere reference escaping. |
cosa sono i code smell? qualche esempio | I code smell sono dei segnali che suggeriscono problemi nella progettazione del codice. Di seguito ne sono elencati alcuni:
codice duplicato: si può fare per arrivare velocemente al verde ma è da togliere con il refactoring. Le parti di codice in comune possono quindi essere fattorizzate.
metodi troppo lunghi: sono poco leggibili e poco riusabili;
troppi livelli di indentazione: scarsa leggibilità e riusabilità, è bene fattorizzare il codice;
troppi attributi: suggerisce che la classe non rispetta la single responsability, ovvero fa troppe cose;
lunghe sequenze di if-else o switch;
classe troppo grande;
lista parametri troppo lunga;
numeri magici: è importante assegnare alle costanti numeriche all’interno del codice un nome per comprendere meglio il loro scopo;
commenti che spiegano cosa fa il codice: indicazione che il codice non è abbastanza chiaro;
nomi oscuri o inconsistenti;
codice morto: nel programma non deve essere presente del codice irraggiungibile o commentato. Utilizzando strumenti di versioning è possibile riaccedere a codice precedentemente scritto con facilità.
getter e setter: vedi principio di tell don’t ask. |
che cosa afferma il principio Tell Don't Ask | afferma che qualora sia possibile, e' meglio delegare una funzionalita' ad una classe utilizzata piuttosto che reperirne delle informazioni dalla classe medesima per poi elaborarle |
quali sono i principali approcci per la creazione di interfacce? | - up front: scrivere direttamente l’interfaccia;
- down front: scrivere il codice e quindi tentare di estrarne un’interfaccia. (migliore per l'approccio TDD) |
che cosa prevede l'interface segregation? | e' uno dei principi SOLID e suggerisce che le interfacce di una classe dovrebbero essere specifiche per i clienti che le utilizzano, piuttosto che avere un'unica interfaccia ingombrante e generica che costringerebbe i clienti a implementare metodi che non hanno bisogno. Questo principio promuove la suddivisione delle interfacce in più parti più piccole e specifiche, in modo che i clienti possano implementare solo le parti di cui hanno bisogno. |
che cosa prevede il concetto di loose coupling? | e' il concetto secondo cui in un progetto i moduli devono essere implementati in modo che siano il mendo dipendenti tra di loro possibile. questo principio promuove:
- minore dipendenza fra i moduli
- riutilizzabilita' del codice
- migliore manutenibilita' del codice
- migliore testabilita' |
quale e' la differenza fra il contract based design e la programmazione difensiva? | Contract-Based Design si concentra sulla specifica formale delle aspettative tra le componenti, mentre la programmazione difensiva si concentra sulla prevenzione degli errori e sulla gestione delle situazioni di errore |