Не используйте состояние в качестве целого числа и не используйте его в операторе if или switch.Определите стратегии в своих классах.Таким образом, вы всегда можете расширить, не изменяя один класс, который превратится в гигантского.
Зачем использовать отдельные классы для дополнительной функциональности, вы можете задаться вопросом, когда нужно выполнить одну или две строки?Теперь у вас может быть одна или две строки, но в будущем вам может понадобиться добавить строку здесь, строку туда, добавить цикл for здесь с некоторыми другими операторами if здесь и там, и вам понадобится несколько переменных для регистрацииstate и ваша 20-строчная программа заканчивается как 200-2000-строчный бегемот с большим количеством ifs и elses и, возможно, с некоторыми конфликтующими состояниями из-за опечатки в переменных с одинаковыми именами.Эти вещи имеют тенденцию к росту.
Имея разделение проблем (google that), вы можете просто добавить функциональность в отдельные классы, не беспокоясь о том, что эта функциональность перекрывает любую другую, и вы можете добавлять другие вещи в любое время, когда захотите.имея один глобальный класс стратегов, который управляет стратегиями.Стратегии имеют свои собственные состояния, одноразовые бегуны, интервальные бегуны, обработчики xhr и т. Д., Но не влияют на состояние главного стратега.Это сохраняет ваш код в чистоте, и вы сможете увидеть, какой код вызывает, что.Если у вас есть бегемот в 200 строк за 6 месяцев, это становится сложнее, потому что одна вещь принадлежит одному состоянию и должна быть связана с правильным оператором if, и вы можете обновить его в другом операторе if.
Кроме того, имея отдельные классы, вы можете автоматизировать тестирование того, что они делают, что упрощает проверку того, что весь код все еще работает, как ожидалось.
class Strategist {
constructor() {
this.strategies = {};
this.activeStrategy = -1;
this.strategy = null;
}
registerStrategy(strategy) {
this.strategies[strategy.getId()] = strategy;
}
setStrategy(id) {
if(this.activeStrategy != -1) {
if(this.strategies.hasOwnProperty(id)) {
this.activeStrategy = id;
}
else {
throw new Error("No such strategy was registered!");
}
}
else {
throw new Error("Another strategy is already active!");
}
}
run() {
this.strategies[ activeStrategy ].run();
}
public function stop() {
this.strategies[ this.activeStrategy ].stop();
this.strategies[ activeStrategy ].reset();
this.activeStrategy = -1;
}
}
Затем определите стратегии.сначала глобальный родительский класс.
class Strategy {
constructor(external_id) {
this.id = external_id;
}
get getId() {
return this.id;
}
run(){};
stop(){};
reset(){};
}
Затем фактические стратегии.что должно произойти, вы определяете здесь.
class StrategyFirst extends Strategy {
run() {
// do something
}
stop() {
// stop doing stuff
}
reset() {
// reset state
}
}
class StrategySecond extends Strategy {
run() {
// do something
}
stop() {
// stop doing stuff
}
reset() {
// reset state
}
}
Затем зарегистрируйте их в стратегии.
strategist = new Strategist();
strategist.registerStrategy(new StrategyFirst("destroy all humans"));
strategist.registerStrategy(new StrategySecond("pluck a flower"));
Затем, когда что-то произошло, и вам нужно запустить его, вы можете обратиться к своему стратегу с просьбой:решить.
strategist.setStrategy("pluck a flower");
Ниже во фрагменте приведен небольшой пример реализации того, как это будет работать в реальном мире, иш.
class Strategist {
constructor() {
this.strategies = {};
this.activeStrategy = -1;
this.strategy = null;
}
registerStrategy(strategy) {
this.strategies[strategy.getId()] = strategy;
}
setStrategy(id) {
if(this.activeStrategy === -1) {
if(this.strategies.hasOwnProperty(id)) {
this.activeStrategy = id;
}
else {
throw new Error("No such strategy was registered!");
}
}
else {
throw new Error("Another strategy is already active!");
}
}
run() {
this.strategies[ this.activeStrategy ].run();
}
stop() {
this.strategies[ this.activeStrategy ].stop();
this.strategies[ this.activeStrategy ].reset();
this.activeStrategy = -1;
}
}
class Strategy {
constructor(external_id) {
this.id = external_id;
}
getId() {
return this.id;
}
run(){};
stop(){};
reset(){};
}
class StrategyFirst extends Strategy {
run() {
if(!this.isRunning) {
this.interval = window.setInterval(function() {
window.alert("BOOOOM! Another one bites the dust, dum dum dum");
}, 3000);
this.isRunning = true;
}
}
stop() {
window.clearInterval(this.interval);
}
reset() {
this.interval = null;
this.isRunning = false;
}
}
class StrategySecond extends Strategy {
run() {
if(!this.isRunning) {
this.interval = window.setInterval(function() {
window.alert("Oooh, look a pretty flower *pluck*");
}, 3000);
this.isRunning = true;
}
}
stop() {
window.clearInterval(this.interval);
}
reset() {
this.interval = null;
this.isRunning = false;
}
}
strategist = new Strategist();
strategist.registerStrategy(new StrategyFirst("destroy all humans"));
strategist.registerStrategy(new StrategySecond("pluck a flower"));
document.getElementById("execute").addEventListener('click',function() {
var select = document.getElementById('fate');
strategist.setStrategy(select.options[select.selectedIndex].value);
strategist.run();
});
document.getElementById("halt").addEventListener('click',function() {
strategist.stop();
});
<select id="fate">
<option value="destroy all humans">Destroy humans</option>
<option value="pluck a flower">Destroy flowers</option>
</select>
<button id="execute">Execute fate</button>
<button id="halt">Interrupt fate</button>