venerdì 30 dicembre 2011

Programmazione: Ecco perché dovresti usare i private accessors

Ah, gli accessors. Per molti programmatori in erba sono quasi degli sconosciuti. Per i più navigati (e pigri) poco più che delle seccature. Per alcuni IDE, un modo come un altro per generare warnings e riempirvi il codice di fastidiose sottolineature.

E' tuttavia pratica comune ammettere che gli accessors pubblici hanno un loro perché, tirando fuori il principio di Incapsulamento dell'OOP. Ma cosa si può dire di un accessor privato?

Prendiamo ad esempio il seguente frammento di codice C++:

class Player
{
   public:
   
   void hurt(int damage){
      this->hp -= damage;
   }

   void heal(int amount){
      this->hp += amount;
   }

   private:

   int hp;
}

Il membro hp è privato e la classe Player vi accede in modo diretto all'interno dei suoi metodi. Che c'è di male? Beh, niente. Tutto lecito. Il compilatore va avanti e il programma funzia. Ma vediamo come apparirebbe con l'utilizzo di accessors privati:

class Player
{
   public:
   
   void hurt(int damage){
      setHp(getHp()-damage);
   }

   void heal(int amount){
      setHp(getHp()+amount);
   }

   private:

   int hp;

   private:

   void setHp(int value){
      this->hp = value;
   }

   int getHp(){
      return this->hp;
   }

}

E' vero, c'è del codice in più. E' vero, codice in più == bug in più. Ma ci sono anche ottimi motivi per operare in questo modo. Elenchiamoli:

  • Tutte le modifiche in un punto solo
    Sappiamo che questo vale per gli accessors pubblici, perché non dovrebbe valere per quelli privati? Ogni modifica al membro hp verrà fatta dentro setHp(), riducendo la complessità di debug e manutenzione del codice (un solo breakpoint).
  • Validazione
    E' possibile operare logiche aggiuntive in un unico punto. Ad esempio si potrebbe controllare che gli hp non scendano sotto lo zero, o che non salgano sopra una certa soglia, mettendo tutti i controlli nella setHp() anziché spargerli nelle varie hurt(), heal() e così via.
  • Unit test?
    Con qualche accorgimento (tipo un metodo wrapper pubblico sugli accessor privati, magari da commentare dopo la fase di test) possiamo scrivere dei test più sicuri ed efficienti, perché andranno a spremere con tutte le logiche possibili un unico metodo. (I moderni tool di unit testing solitamente hanno poi escamotage per raggiungere anche i metodi privati, senza chiederci di sporcare il codice con wrapper vari.)
  • Incapsulamento
    Ancora una volta, l'essere privato non elimina i vantaggi del pubblico. E' vero, stiamo "nascondendo" dettagli implementativi alla stessa classe che li implementa, il che può apparire sciocco. Ma non è mai sciocco racchiudere funzionalità operanti su un membro in un unico punto.
  • Ridefinizione nelle classi derivate
    Ok, qui bariamo un attimo e rendiamo i nostri accessors virtual e protected. Le classi derivate possono ridefinire l'accesso al membro. Se questa esigenza fosse sorta dopo un po' e non avessimo avuto gli accessors privati saremmo stati costretti quantomeno ad un pericoloso refactoring.
  • Undo e Redo
    Altro figlio dell'avere le modifiche in un solo punto è la possibilità di aggiungere con facilità funzionalità di undo e redo.

I vantaggi qui elencati sono solo esempi. Scommetto che lavorandoci se ne potrebbero trovare altri.

Buon coding...e Buon Anno!

L'articolo originale da cui ho tratto lo spunto per questa riflessione è pubblicato sul blog Joel on Software

mercoledì 28 dicembre 2011

Dwarf Fortress: come ti sopravvivo al primo anno (parte 1)

Questo post poteva anche appartenere alla serie "Il gioco indie che forse non conoscete...", ma chi non ha mai sentito parlare di Dwarf Fortress? Chi non ha mai provato a giocarci e, dopo solo tre minuti, l'ha cestinato per via della sua inconcepibile complessità? E chi, tra questi, ha mantenuto quell'amaro in bocca dovuto alla sensazione di aver appena rinunciato ad una esperienza di gioco potenzialmente molto valida?


Ebbene, se siete tra i tanti frustrati che ci hanno provato ma ne sono stati sconfitti, questo post tenterà di farvi tornare la voglia per un nuovo tentativo. Sì, perché qui si parla della base di partenza per creare una fortezza e mantenerla in vita per il primo anno di gioco.

E' vero, ci sono tanti tutorial su Dwarf Fortress, quindi perché anche questo?

Beh, DF è un gioco grosso (ma rende meglio all'americana: HUGE!) e, quasi fosse fisiologico, anche i tutorial che vanno ad occuparsene finiscono per diventarlo. Inoltre sono spesso scritti da guru del gioco, persone che ormai ne padroneggiano i segreti più occulti e che hanno perso di vista quella sensazione di muro che si trova davanti il novizio.

Io no. Ho perso le mie prime fortezze in molti modi: per fame, per sete, per rabbia dei nani, per fantasmi (!), per cause ignote ma che mi lasciavano nani morti ammazzati in giro per le sale e per altri divertimenti assortiti.

Dopo diversi tentativi ho però trovato la formula per l'equilibrio, quel tanto che basta a far vivere e prosperare la fortezza fino all'arrivo della prima carovana di mercanti, e anche un po' più in la. Tutto si riassume in due parole: cibo e alcolici. Fate in modo di produrne in quantità regolari (ma anche abbondanti) e avrete risolto i bisogni primari dei vostri nani.

Produrre cibo e alcol sottintende avere una o più fattorie (farm plot) funzionanti. Per fare una fattoria occorrono però una serie di passi intermedi che vanno dal tagliare gli alberi allo scavare in un terreno adatto (o irrigare). Fondamentale sarà anche tenere un conto preciso delle scorte.

In questa prima parte prenderemo solo confidenza con i meccanismi di base del gioco.
Incredibilmente, per essere un gioco tanto complesso, le meccaniche sono essenzialmente tre o quattro, e si ripetono sempre uguali.

All'inizio troverete i vostri nani (sette, naturalmente) attorno al wagon, il carro con cui sono giunti al luogo della spedizione. Sul wagon ci sono un sacco di robe utili, ma per ora non ce ne preoccupiamo.

Fermi tutti!


Il gioco parte in stato di pausa, come vedete nella parte alta a sinistra della schermata. Lo stato di Pausa è fondamentale e ci passerete gran parte del tempo. Occorre quindi padroneggiarlo. Si entra in pausa in due modi: o per volontà, premendo Space dal menu principale, o in automatico, quando si entra in un sottomenu. Durante la pausa il tempo si blocca (ma dai!), i nani non fanno nulla e non accade niente di divertente, ma potete navigare tra i ricchi sottomenu in santa pace e assegnare ordini e direttive ai vostri nani, o capire cosa non va e con chi. Per ora allenatevi ad entrare ed uscire dalla pausa, acquisendo coscienza di essa.

Potete dare ordini ai nani premendo 'd' (Designations), come vedete nella parte destra dello schermo. Da qui si accede ad un sottomenu con i vari ordini, da scavare (Mine), a tagliare alberi (Chop down trees), a raccogliere erbe (Gather plants) ecc.

Sì, ma come?


Ogni voce ha un suo tasto associato, che occorre premere. Mine, ad esempio, ha la 'd'. Per selezionare l'azione scavare, quindi, occorre premere 'd' e poi ancora 'd'. A questo punto la X gialla nella schermata di mappa con i nani diventa un cursore. Dobbiamo selezionare l'area interessata dall'azione, specificandone il vertice alto a sinistra e basso a destra. Per farlo portiamo il cursore (con le frecce) nel punto desiderato (alto a sinistra) e premiamo Enter. Quindi ci portiamo nel secondo vertice (basso a destra) e premiamo Enter di nuovo. L'area viene evidenziata. Nel caso dello scavare, l'area evidenziata rappresenta la fetta di terra/roccia da eliminare. Naturalmente ha senso solo se fatta in una zona con una parete rocciosa, oppure sotto terra.

Altro menu importante è quello delle costruzioni (Buildings). Ci si accede col tasto 'b' e vengono mostrate le possibili costruzioni. Ci torneremo, nel frattempo esplorate pure i vari sottomenu, specialmente quello dei laboratori (Workshops).

Chi fa cosa?


E' importante capire che non comandate direttamente i singoli nani, ma specificate cosa deve essere fatto (è un gestionale). I nani hanno poi delle statistiche e il sistema invia i nani più skillati nel lavoro scelto. A volte capita che nessun nano sappia fare la cosa scelta. In questo caso occorre agire sul singolo nano, abilitandolo al lavoro specifico (Labor). Ma questa è un'altra storia. Se avete scelto di giocare subito (consigliato) anziché preparare il viaggio con cura avrete a disposizione sette nani capaci di svolgere i compiti basilari.

Su e giù


Altra abilità importante che dovete sviluppare come giocatori di Dwarf Fortress è il concetto di Z-Level e come muoversi tra essi. DF è un gioco in 2D, ma simula il 3D lavorando con i livelli, come un programma di fotoritocco. Premendo '>' si scende di un livello (si va in profondità), mentre con '<' si risale. Quando i vostri nani inizieranno a scavare (o a costruire verso l'alto, perché no) diventerà essenziale navigare tra i livelli. Fate esercizio già da ora e vedrete come i livelli più bassi appaiano ora quasi del tutto neri (solida roccia), magari con qualche falda acquifera qua e la, mentre quelli più alti vadano a perdere di dettaglio man mano che si sale. Se vi perdete niente paura: con F1 si torna al wagon.

Coraggio dunque, iniziate la vostra avventura nanica e prendete la mano con i comandi di base e la mentalità del gioco, che nella prossima puntata si parte con la strategia di sopravvivenza.