Javascript-使用类(ES6)更改许多if语句

时间:2018-11-26 08:40:38

标签: javascript node.js oop if-statement design-patterns

我现在在我的代码中使用了很多if语句, 所以我想通过使用类(ES6)进行更改

但是,我的Java语言不是很好...所以请PLZ帮助我..!

先前的代码:

//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 :(得分:3)

请勿将状态用作整数,而应在if或switch语句中使用该状态。在自己的班级中定义策略。这样一来,您始终可以扩展,而不必修改将成长为庞然大物的类。

为什么要使用单独的类来提供额外的功能,您可能想知道何时只执行一两行? 现在您可能只有一两行,但是将来您可能需要在此处添加一行,在此处添加一行,在此处添加一个for循环,以及在此各处添加更多if语句,并且您将需要一些变量来记录状态,而您的20行程序最终成为200-2000行的庞然大物,它包含许多ifs,else和else,并且由于在类似命名的变量中出现错字而可能会出现一些冲突的状态。这些东西趋于增长。

通过将关注点分开(google that),您可以仅在各个类中添加功能,而不必担心功能会与其他功能重叠,并且可以通过让一个全局策略师类来管理其他功能来随时添加其他内容。策略。这些策略具有自己的状态,一次运行,间隔运行,xhr处理程序等,而不会影响主要策略家的状态。它可以使您的代码清晰明了,并且您将能够看到什么代码导致了什么。当您在6个月内拥有200行巨兽时,它将变得更加困难,因为一个事物属于一种状态需要链接到正确的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>

答案 1 :(得分:0)

快速而肮脏–不是首选方式

只需创建一个地图,其中的键会为您提供正确的功能:

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

工厂模式-首选方式

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()。如果您只有很少的功能,也可以使用lamda。

google()