Rappresentando i tuoi stati come maschera di bit come scrivi, puoi semplicemente tradurre in codice le descrizioni dei vincoli:
if ( (state & HOT) && (state & COLD) ) {
state &= ~HOT;
state &= ~COLD; // reset both HOT and COLD flags if both are set
}
if ( (state & COLD) && (state & WET) ) {
state &= ~WET; // cold items can't be wet
state |= FROZEN; // instead, they're frozen
}
if ( (state & HOT) && (state & WET) ) {
state &= ~WET; // hot and wet items dry up...
state &= ~HOT; // ...and cool down
}
// add other constraints here...
Potresti includerlo in un nome makeStateConsistent()
che puoi chiamare prima di testare i bit di stato per assicurarti che lo stato abbia un senso.
Tuttavia, una limitazione di questo approccio è che non può tenere conto dell'ordine dei cambiamenti di stato. Ad esempio, se si desidera ottenere un risultato diverso per gli articoli caldi che si bagnano rispetto agli articoli bagnati che diventano caldi, non è possibile farlo in questo modo: tutto il makeStateConsistent()
metodo vede è un oggetto caldo e bagnato, senza informazioni su come deve essere così.
Invece, quello che si potrebbe fare è rendere lo stato oggetto privato (almeno concettualmente) e manipolare attraverso una serie di metodi come coolItem()
, heatItem()
, wetItem()
, dryItem()
e così via. In questo modo, i metodi stessi di cambiamento di stato possono occuparsi di eventuali cambiamenti aggiuntivi. Ad esempio, il heatItem()
metodo potrebbe assomigliare a questo:
if ( state & COLD ) {
state &= ~COLD; // cold items become normal temp when heated
if ( state & FROZEN ) {
state &= ~FROZEN; // ...and melt if they were frozen
state |= WET;
}
} else if ( state & WET ) {
state &= ~WET; // wet items dry up when heated, stay normal temp
} else {
state |= HOT; // dry normal temp items become hot
}
Naturalmente, potresti comunque voler avere anche un makeStateConsistent()
metodo come backup, nel caso in cui tu abbia un bug nei tuoi metodi di cambio di stato.
Inoltre, in alcuni casi potresti essere in grado di semplificare il codice eliminando gli stati non necessari. Ad esempio, hai davvero bisogno di uno FROZEN
stato separato , o sarebbe sufficiente trattare solo oggetti freddi e bagnati come congelati?