Représentant vos états sous forme de masque binaire comme vous écrivez, vous pouvez simplement traduire vos descriptions des contraintes en code:
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...
Vous pouvez envelopper cela dans un makeStateConsistent()
que vous pouvez appeler avant de tester les bits d'état pour vous assurer que l'état a du sens.
Cependant, une limitation de cette approche est qu'elle ne peut pas rendre compte de l'ordre des changements d'état. Par exemple, si vous voulez avoir un résultat différent pour les éléments chauds qui deviennent humides que pour les éléments humides qui deviennent chauds, vous ne pouvez pas le faire comme ceci: tout ce que la makeStateConsistent()
méthode voit est un objet chaud et humide, sans aucune information sur la façon dont ça doit être comme ça.
Au lieu de cela, ce que vous pouvez faire est de faire l'état de l' élément privé (au moins conceptuellement) et de le manipuler à travers un ensemble de méthodes comme coolItem()
, heatItem()
, wetItem()
, dryItem()
et ainsi de suite. De cette façon, les méthodes de changement d'état elles-mêmes peuvent prendre en charge tout changement supplémentaire. Par exemple, la heatItem()
méthode pourrait ressembler à ceci:
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
}
Bien sûr, vous souhaiterez peut-être également avoir une makeStateConsistent()
méthode en tant que sauvegarde, juste au cas où vous auriez un bogue dans vos méthodes de changement d'état.
De plus, dans certains cas, vous pouvez simplifier votre code en éliminant les états inutiles. Par exemple, avez-vous vraiment besoin d'un FROZEN
état séparé , ou suffirait-il simplement de traiter les articles froids et humides comme congelés?