Представляя ваши состояния в виде битовой маски, как вы пишете, вы можете просто перевести ваши описания ограничений в код:
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...
Вы можете заключить это в объект, makeStateConsistent()
который вы можете вызвать перед проверкой битов состояния, чтобы убедиться, что состояние имеет смысл.
Однако одним из ограничений этого подхода является то, что он не может учитывать порядок изменений состояния. Например, если вы хотите получить другой результат для горячих предметов, которые становятся мокрыми, чем для мокрых предметов, которые становятся горячими, вы не можете сделать это следующим образом: все, что makeStateConsistent()
видит метод - это горячий и мокрый объект, без информации о том, как так и должно быть.
Вместо того , что вы могли бы сделать , это государство пункт частным (по крайней мере , концептуально) и управлять ею с помощью набора методов , таких как coolItem()
, heatItem()
, wetItem()
, dryItem()
и так далее. Таким образом, сами методы изменения состояния могут позаботиться о любых дополнительных изменениях. Например, heatItem()
метод может выглядеть примерно так:
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
}
Конечно, вы все еще можете иметь makeStateConsistent()
метод в качестве резервной копии, на случай, если у вас есть ошибка в ваших методах изменения состояния.
Кроме того, в некоторых случаях вы можете упростить код за счет устранения ненужных состояний. Например, вам действительно нужно отдельное FROZEN
состояние, или этого будет достаточно, чтобы относиться к холодным и влажным предметам как к замороженным?