Idealmente, non dovresti aver bisogno di memorizzare queste informazioni in modo esplicito. Dovrebbe seguire implicitamente dal flusso di controllo del tuo programma.
;; Very easy to read
ROUTINE ProcessItem(item)
BEGIN
IF IsValidItem(item) THEN
ProcessValidItem(item)
ELSE
ProcessInvalidItem(item)
FI
END
ROUTINE ProcessValidItem(item)
BEGIN
DoSomething(item)
DoAnotherThing(item)
DoThisThing(item)
END
ROUTINE ProcessInvalidItem(item)
BEGIN
DoSomethingElse(item)
DoAnotherThing(item)
END
All'interno delle subroutine ProcessValidItem
e ProcessInvalidItem
, non ho bisogno di un flag che mi dice se un elemento è valido. Se la struttura del tuo programma implica la validità di un oggetto, non puoi dimenticare di controllarlo. La validità dovrebbe essere verificata esattamente a un punto, se possibile. Invece di combinare il trattamento di articoli validi e non validi nella stessa funzione e decidere ripetutamente cosa fare in base a un flag "valido", separare il flusso di controllo in due percorsi di codice distinti e diretti e calcolare le parti comuni al trattamento di entrambi, articoli validi e non validi, in subroutine. Trovo il codice mostrato sopra molto più pulito rispetto al seguente esempio.
;; Not so easy to read
ROUTINE ProcessItem(item)
BEGIN
valid ← IsValidItem(item)
IF valid THEN
DoSomething(item)
ELSE
DoSomethingElse(item)
FI
DoAnotherThing(item)
IF valid THEN
DoThisThing(item)
FI
END
Se devi memorizzare la validità su una base per articolo, questo flag deve essere di proprietà di chiunque ne stabilisca la validità.
Se un oggetto può validarsi, dovrebbe avere un metodo che indichi se è valido. Che si convalidi da solo ogni volta che questo metodo viene chiamato o lo memorizza nella cache in un campo privato è un dettaglio di implementazione. Si interrompe chiaramente l'incapsulamento per lasciare che il codice al di fuori del pasticcio di classe con il valore di quel campo.
D'altra parte, se l'oggetto è validato da qualcun altro, allora questo qualcuno è responsabile della conservazione delle informazioni - al di fuori dell'oggetto. Dare l'accesso all'oggetto al suo stato di convalida determinato esternamente sarebbe altrettanto sbagliato che dare a qualcun altro l'accesso allo stato interno dell'oggetto. Una semplice struttura a coppie potrebbe essere utilizzata per allegare tali informazioni a un oggetto e rimuoverlo quando non è più necessario. In una configurazione orientata agli oggetti, il flag potrebbe essere sostituito dal polimorfismo per salvare una parola di archiviazione per il costo di una chiamata al metodo virtuale.
+-------------------------+
| ValidatedItem<T> |
+-------------------------+
| - item : T |
+-------------------------+
| + getItem() : T |
| + isValid() : Boolean |
+-------------------------+
^
|
+-------------------+-------------------+
| |
+-------------------------+ +-------------------------+
| ValidItem<T> | | InvalidItem<T> |
+-------------------------+ +-------------------------+
| + isValid() : Boolean | | + isValid() : Boolean |
+-------------------------+ +-------------------------+