2015-05-09 18:45 GMT+01:00 Giovanni Porcari <giovanni.porc...@softwell.it>:
> Sono certo che molti criticheranno il fatto di partire subito definendo > una classe > ma per mia esperienza, con questo tipo di approccio un programma iniziato > per piccole esigenze può crescere bene. Se si buttano giù linee di codice > affastellate, alla fine tocca buttare tutto e ripartire :D. > Io criticherei il fatto che una classe siffatta e' inusabile e viola in modo necessario piu' o meno ogni regola di programmazione ad oggetti. Il problema piu' grosso e' che mischia concerns molto diversi: input, output e logica business. Non solo: lega l'input ad una specifica logica di input. Allora, andiamo per gradi: tipicamente vuoi che una classe abbia delle invarianti. Quanto piu' costante e' la classe, quanto piu' e' facile mantenere delle invarianti. L'ideale e' avere una classe completamente immutabile: le invarianti vanno controllate nel costruttore e poi non sono piu' un problema; inoltre hai garanzie forti sul fatto che qualunque triangolo hai nel tuo programma rispettera' *sempre* le invarianti (altrimenti il costruttore avrebbe lanciato un'eccezione). Viceversa, con un approccio a mutatori ti trovi a doverle controllare ogni volta che cambi qualcosa (e potenzialmente a dovere introdurre il concetto di transazione se hai mai due mutatori che vanno chiamati insieme per mantenere l'invariante. E non e' codice esattamente banale da scrivere correttamente (immagina proprio un triangolo: immaginatelo mantenuto con dei vertici, puoi trovarti che modificando un vertice non hai piu' un triangolo e devi appunto spostare *due* vertici). Riguardo l'input, hai legato: 1. la fonte di input 2. la strategia di input 3. il formato di input Non solo quella classe funziona esclusivamente prendendo i dati da standard input (per come hai definito l'interfaccia), ma presuppone che quello che hai su standard input sia in uno specifico formato *non* negoziabile. Devi fare *due* letture (e se ti scordi di farne una, hai rotto verosimilmente tutto). Quindi la classe non e' adattabile ne a cose come prendiamo input da file, ne a cose come invece che prendere i numeri separati da newline li prendiamo separati da tab nella stessa linea. Per piu' forte ragione, anche cose tipo prendiamo i triangoli da un database non si possono fare e nemmeno cose come prendiamo i triangoli da un file json (o da un pickle o da dove ti pare). Non solo: anche cose a livello di logica di input piu' di alto livello sono rotte (per esempio invece che prendere base e altezza -- assumendo che la base sia un segmento, quindi vuole dire succhiare due punti oppure un punto, una direzione e una lunghezza -- vuoi prendere invece 3 vertici -- che potrebbero essere in coordinate cartesiani o polari). L'output ha essenzialmente lo stesso problema (sebbene almeno non abbia necessita' di due chiamate). Quindi in altre parole il principiante che si trovasse avendo scritto una classe del genere non sarebbe nella condizione di potere estendere il suo codice facilmente per fare cose estremamente banali e legittime. Lo schema e' talmente lontano da una buona struttura che l'unica cosa che potrebbe fare sarebbe aggiungere qualche dozzina di metodi ad hoc -- che poi non sarebbe testare in modo incrociato e si troverebbe con una API fragilissima --. Personalmente, rimanendo all'esempio del triangolo, progetterei tutto con una named-tuple (ma questo e' un dettaglio implementativo) che tiene un certo set di dati minimi in memoria. Poi ci sabbero dei metodi statici per prendere diverse strutture (che so... base - altezza, 3 vertici, etc etc etc). Ovviamente tutto questo richiede di un concetto di Punto relativamente ben fatto (ancora una volta immutabile, che puoi costruire, per dire, con coordinate cartesiane oppure polari). A questo punto il triangolo avrebbe un metodo per darti l'area. Il resto rimane molto piu' semplice. -- . ..: -enrico-
_______________________________________________ Python mailing list Python@lists.python.it http://lists.python.it/mailman/listinfo/python