这是我参与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();
})()
复制代码
主要优点:
- 多重条件不易维护,而使用策略模式可以避免使用多重条件语句
- 策略模式提供一些列的可供重用的算法族,
- 策略模式提供相同行为不同实现
- 策略模式提供对开闭原则的支持,不修改源代码灵活扩展
- 策略模式将算法的实现和使用算法的代码隔离开
存在缺点:
- 客户端需知晓所有算法,然后选择合适的算法
- 策略模式造成很多的策略类,增加维护难度