Representando seus estados como máscara de bits como você escreve, você pode apenas traduzir suas descrições das restrições em código:
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...
Você pode agrupar isso em um makeStateConsistent()
que você pode chamar antes de testar os bits de estado para garantir que o estado faça sentido.
No entanto, uma limitação dessa abordagem é que ela não pode explicar a ordem das mudanças de estado. Por exemplo, se você deseja obter um resultado diferente para itens quentes que ficam úmidos do que para itens quentes que ficam quentes, não é possível fazer o seguinte: tudo o makeStateConsistent()
que o método vê é um objeto quente e úmido, sem informações sobre como tem que ser assim.
Em vez disso, o que você poderia fazer é tornar o estado do item privado (pelo menos conceitualmente) e manipulá-lo através de um conjunto de métodos como coolItem()
, heatItem()
, wetItem()
, dryItem()
e assim por diante. Dessa forma, os próprios métodos de mudança de estado podem cuidar de quaisquer alterações adicionais. Por exemplo, o heatItem()
método pode ser algo como isto:
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
}
Obviamente, você ainda pode querer ter um makeStateConsistent()
método como backup, caso tenha algum erro nos métodos de alteração de estado.
Além disso, em alguns casos, você pode simplificar seu código eliminando estados desnecessários. Por exemplo, você realmente precisa de um FROZEN
estado separado ou seria suficiente apenas tratar itens frios e molhados como congelados?