Javascript - изменить много операторов if с помощью класса (ES6) - PullRequest
0 голосов
/ 26 ноября 2018

Сейчас я использую множество операторов if в своем коде, поэтому я хочу изменить с помощью класса (ES6)

Однако я не очень хорош в Javascript ... так что PLZ HELP ME ..!

Предыдущий код:

//example code
function first(){
  console.log('first scenario called');
}

function second(){
  console.log('second scenario called');
}

function third(){
  console.log('third scenario called');
}

state = 1;
if(state === 1){
  first();
}else if(state === 2){
  second();
}else if(state === 3){
  third();
}
//first scenario called

Измененный код:

class Strategy {
    constructor(state) {
        this.state = state;

        if(this.state === 1){
          return first();
        }else if (val === 2){
          return second();
        }else if (val === 3){
          return third();
        }
    }

}

function first(){
  console.log('first scenario called');
}

function second(){
  console.log('second scenario called');
}

function third(){
  console.log('third scenario called');
}

let firstClass = new Strategy(1);
//first scenario called

Это мой пример кода ..

На самом деле у меня почти 50+ если отметился.Это правильный способ изменить много утверждений if ???

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

Быстро и грязно - Не предпочтительный способ

Просто создайте карту, где ключ дает вам правильную функцию:

this.strategies = {
    1: this.first,
    2: this.second,
    3: this.third
}

, а затем найдите функцию и выполните ее:

execute(value) {
    this.strategies[value] == null
        ? console.log("this strategy does not exist")
        : this.strategies[value]()
}

Полный рабочий пример

class Strategy {

    constructor(value) {
        this.strategies = {
            1: this.first,
            2: this.second,
            3: this.third
        }

        this.execute(value)

    }

    execute(value) {
        this.strategies[value] == null
            ? console.log("this strategy does not exist")
            : this.strategies[value]()
    }

    first() {
        console.log('first scenario called');
    }

    second() {
        console.log('second scenario called');
    }

    third() {
        console.log('third scenario called');
    }
}

new Strategy(0);
new Strategy(1);
new Strategy(2);
new Strategy(3);

Фабрика-Скороговорка - Предпочтительный способ

Класс Strategy делает две мысли:

  • it ищет правильный метод
  • it выполняет правильный метод

it ищет правильный метод.Думаю, что поиск должен быть в классе StrategyFacotry, а выполнение должно обрабатывать кого-то, но не небольшой подсказка StrategyFacotry.

: для поиска правильной стратегии используется быстрый и грязный способ сверху:)

Я поместил разные стратегии в отдельные классы.Важно то, что эти функции должны использовать один и тот же интерфейс.В моем примере все они должны реализовать функцию execute.Если у вас мало функций, вы можете сделать это и с лямдой.

class StrategyFactory {

    constructor() {
        this.strategies = {
            1: new PowerfullStrategy(),
            2: new WeakStrategy(),
        }
    }

    get(value) {
        return this.strategies[value] == null
            ? new DefaultStrategy()
            : this.strategies[value]
    }
}

class DefaultStrategy {
    excecute() {
        console.log("this strategy does not exist")
    }
}

class PowerfullStrategy {
    excecute() {
        // do some
        // calculaion here ..
        console.log("I AM THE POWERFULL STRATEGY")
    }
}


class WeakStrategy {
    excecute() {
        // do some
        // calculaion here ..
        console.log("i am the waek strategy")
    }
}

const factory = new StrategyFactory()
const strategy = factory.get(1)
const otherStrategy = factory.get(1000)

strategy.excecute()
otherStrategy.excecute()
0 голосов
/ 26 ноября 2018

Не используйте состояние в качестве целого числа и не используйте его в операторе 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...