TypeScript | 设计模式10 -策略模式

这是我参与11月更文挑战的第15天,活动详情查看:2021最后一次更文挑战

前言

设计模式第三种模式—行为型模式,总共划分了以下几种模式:模板方法模式、命令模式、访问者模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、责任链模式

策略模式

策略模式,他能让你定义一些列算法,并将每种算法分别放入独立的类中,以使算法的对象能够互相替换。策略模式属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

场景

双十一时候有各种的电商活动,打折,送商品,送积分等方法,如果开发中遇到这种多条件的判断,如果写很多if else 判断来完成业务逻辑,不但使条件语句变得很复杂,而且增加、删除或更换算法要修改原代码,不易维护,违背开闭原则。如果采用策略模式就能很好解决该问题。

模式结构

  • 抽象策略:定义了一个公共接口或者抽象类,各种不同的算法以不同的方式实现接口,环境类使用该接口调用不同的算法
  • 具体策略:实现抽象策略定义的接口,提供具体的实现
  • 环境类:持有一个策略类的引用,最终给客户端使用
​
// 环境类,拥有策略类的引用,专门给客户端调用
 class Context {
​
    private strategy: Strategy;
​
    constructor(strategy: Strategy) {
        this.strategy = strategy;
    }
​
    public setStrategy(strategy: Strategy) {
        this.strategy = strategy;
    }
​
    public doSomeBusinessLogic(): void {
      
        console.log('Context: Sorting data using the strategy (not sure how it'll do it)');
        const result = this.strategy.doAlgorithm(['a', 'b', 'c', 'd', 'e']);
        console.log(result.join(','));
​
    }
}
​
// 策略接口/抽象类
interface Strategy {
    doAlgorithm(data: string[]): string[];
}
​
// 具体实现了策略接口/抽象 -1
class ConcreteStrategyA implements Strategy {
    public doAlgorithm(data: string[]): string[] {
        return data.sort();
    }
}
​
// 具体实现了策略接口/抽象 -2
class ConcreteStrategyB implements Strategy {
    public doAlgorithm(data: string[]): string[] {
        return data.reverse();
    }
}
​
(()=>{
    // 使用策略A类的方法
    const context = new Context(new ConcreteStrategyA());
    console.log('Client: Strategy is set to normal sorting.');
    context.doSomeBusinessLogic();
    
    console.log('');
    
     // 使用策略B类的方法
    console.log('Client: Strategy is set to reverse sorting.');
    context.setStrategy(new ConcreteStrategyB());
    context.doSomeBusinessLogic();
})()
​
复制代码

主要优点:

  • 多重条件不易维护,而使用策略模式可以避免使用多重条件语句
  • 策略模式提供一些列的可供重用的算法族,
  • 策略模式提供相同行为不同实现
  • 策略模式提供对开闭原则的支持,不修改源代码灵活扩展
  • 策略模式将算法的实现和使用算法的代码隔离开

存在缺点:

  • 客户端需知晓所有算法,然后选择合适的算法
  • 策略模式造成很多的策略类,增加维护难度

猜你喜欢

转载自juejin.im/post/7030819531979227144
今日推荐