Pioritree e Silex

post_it_treeCirca due anni fa stavo (finalmente) studiando i design pattern su Head First Design Patterns, un libro semplice, pieno di figure, sicuramente più accessibile (ai programmatori un po’ meno svegli) del ben più noto Design Patterns: Elementi per il riuso di software ad oggetti, il quale è più un catalogo da consultare che un testo di apprendimento.

Beh, avevo letto del Composite Pattern e mi era venuta in mente un’idea per metter in pratica quanto appreso.
Cercavo un modo per dedicare il giusto tempo alle mille attività che dovevo/volevo svolgere senza trascurare nulla, ma soprattutto senza trascurare le cose più importanti:

Quanto tempo devo dedicare alla pulizia della casa? Quanto ne posso dedicare alle attività della mia associazione? Ma della pulizia della casa, quanto tempo dedico alla cucina e quanto alla camera da letto?

Insomma volevo costruire una gerarchia (un albero) di attività da svolgere, in cui ogni attività potesse essere suddivisa in sottoattività e così via. Ad ogni attività avrei quindi assegnato un livello di priorità (da 1 a 10 per esempio). Avrei infine scelto un monte ore di riferimento (ad esempio 100 ore) da distribuire automaticamente a ciascuna attività in base alle loro priorità. Il Composite Pattern era perfetto per gestire gerarchie di elementi e avrei potuto sperimentare un approccio TDD. Il nome che gli avrei dato sarebbe stato Prioritree.

Non mi ci volle molto per realizzare un prototipo. Sarebbe stato impossibile implementare le classi che gestiscono una gerarchia senza l’ausilio di test unitari.
Praticamente si doveva definire la propria gerarchia di attività con le loro priorità ed il monte ore assegnato su un file Yaml:

// mytasks.yml
Root:
  data: timeBox=100
  children:
     Casa:
        data: priority=10
        children:
           Camera da letto:
              data: priority=6
           Bagno:
              data: priority=10
           Cucina:
              data: priority=8
     Associazione:
        data: priority=6
        children:
           Sito:
              data: priority=2
           Facebook:
              data: priority=4
           Eventi:
              data: priority=10

eseguendo un semplice php index.php il file veniva arricchito con le ore assegnate a ciascuna attività.

// mytasks.yml
Root:
   data: usedTime=0; timeBox=100; progress=0%; time=0/100
   children:
      Casa:
         data: usedTime=0; priority=10; progress=0%; time=0/62.5
         children:
            Camera da letto:
               data: usedTime=0; priority=6; progress=0%; time=0/15.63
            Bagno:
               data: usedTime=0; priority=10; progress=0%; time=0/26.04
            Cucina:
               data: usedTime=0; priority=8; progress=0%; time=0/20.83
      Associazione:
         data: usedTime=0; priority=6; progress=0%; time=0/37.5
         children:
            Sito:
               data: usedTime=0; priority=2; progress=0%; time=0/4.69
            Facebook:
               data: usedTime=0; priority=4; progress=0%; time=0/9.38
            Eventi:
               data: usedTime=0; priority=10; progress=0%; time=0/23.44

Successivamente era possibile specificare il tempo utilizzato per ciascuna attività  a qualsiasi livello di dettaglio impostando usedTime; rilanciando php index.php veniva aggiornato il progresso percentuale e le ore assegnate su tutte le attività discendenti ed ascendenti.

// mytasks.yml
Root:
   data: usedTime=0; timeBox=100; progress=11%; time=11/100
   children:
      Casa:
         data: usedTime=2; priority=10; progress=17.6%; time=11/62.5
         children:
            Camera da letto:
               data: usedTime=4; priority=6; progress=29.87%; time=4.67/15.63
            Bagno:
               data: usedTime=5; priority=10; progress=21.76%; time=5.67/26.04
            Cucina:
               data: usedTime=0; priority=8; progress=3.2%; time=0.67/20.83
      Associazione:
         data: usedTime=0; priority=6; progress=0%; time=0/37.5
         children:
            Sito:
               data: usedTime=0; priority=2; progress=0%; time=0/4.69
            Facebook:
               data: usedTime=0; priority=4; progress=0%; time=0/9.38
            Eventi:
               data: usedTime=0; priority=10; progress=0%; time=0/23.44

Era possibile cambiare le priorità delle attività oppure cambiare la struttura dell’albero in qualsiasi momento: le ore assegnate cambiavano, nessun problema.

Faceva altre cose ovviamente, come resettare il monte ore portandosi dietro i debiti e i crediti del monte ore precedente, ma l’idea in soldoni era questa.

Utilizzai come contenitore un microframework che stavo realizzando per i miei progetti personali ispirato a quanto avevo letto di Symfony e dell’archiettura MVC. Solo l’anno scorso imparai ad utilizzare Git e Github e vi pubblicai il mio Prioritree.

Quest’estate, però, ho imparato ad utilizzare Silex, il fratellino minore di Symfony 2, grazie ad un lavoretto con Ideato. Quindi ho pensato di riprendere il Prioritree e sostituire il mio incompleto e rozzo microframework con Silex, al fine di costruire in un secondo momento una’interfaccia web decente per quello che ora è solo un set di classi.

Grazie ai vecchi test il porting è stato rapido e indolore e questo è il risultato.

Ho cercato di fare commit piccole e significative in modo da mettere in evidenza tutti i passaggi fatti per cambiare contenitore. I tag v1.0 e v2.0  corrispondono rispettivamente al Prioritree prima e dopo il travaso in Silex.

Ora manca il Readme in markdown e buttar su un’interfaccia web semplice semplice per poterlo pubblicare e rendere disponibile a tutti. E’ la prima volta che a distanza di anni riesco a riprendere del vecchio codice e a riutilizzarlo senza che mi faccia schifo. :)

Lascia una risposta

L'indirizzo email non verrà pubblicato. I campi obbligatori sono contrassegnati *

È possibile utilizzare questi tag ed attributi XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>