文章目录
策略模式:灵活切换算法的导航系统
当你使用导航软件规划路线时,可以根据自己的需求选择不同的策略:最短路径、最快路径、避开高速公路等。这个看似简单的功能选择,实际上完美诠释了策略模式的精髓。
在软件开发中,我们经常遇到需要在运行时选择算法的情况。策略模式就像这个导航系统,它定义了一系列算法,将每个算法封装起来,并使它们可以相互替换。这种模式让算法可以独立于使用它的客户而变化!
策略模式的奥秘
策略模式就像一个"算法超市",它将一组相关的算法家族封装成一系列策略类,使得它们可以相互替换。通过这种方式,你可以在不影响客户端的情况下,随时增加、删除或修改算法,使得系统更加灵活和可扩展。
策略模式有什么利与弊?
策略模式的优点是它定义了一系列可复用的算法和行为,消除了一些条件语句,可以提供相同行为的不同实现。它遵循了开闭原则,使得算法可以独立于客户端而变化。缺点是客户端必须知道所有的策略类,且可能会创建多余的策略类。
如何使用策略模式来优化你的系统
策略模式涉及角色
- 上下文(Context): 维护一个对策略对象的引用,可以定义一个接口来让策略访问它的数据
- 策略(Strategy): 定义所有支持的算法的公共接口
- 具体策略(ConcreteStrategy): 实现了 Strategy 接口的具体算法
策略模式步骤
- 创建一个策略接口,定义所有支持的算法的公共方法
- 创建具体策略类,实现策略接口,定义具体的算法
- 创建上下文类,包含策略对象的引用
- 在上下文类中实现客户端接口,将具体行为委托给当前策略对象
- 客户端通过上下文类来选择和使用不同的策略
选择合适的策略模式,你就能轻松地管理和切换不同的算法,让系统变得更加灵活和可维护!
代码实现案例
typescript
// 策略接口
interface RouteStrategy {
calculateRoute(start: string, end: string): string;
}
// 具体策略类 - 最短路径
class ShortestPathStrategy implements RouteStrategy {
calculateRoute(start: string, end: string): string {
return `计算从 ${start} 到 ${end} 的最短路径`;
}
}
// 具体策略类 - 最快路径
class FastestPathStrategy implements RouteStrategy {
calculateRoute(start: string, end: string): string {
return `计算从 ${start} 到 ${end} 的最快路径`;
}
}
// 具体策略类 - 避开高速公路
class AvoidHighwaysStrategy implements RouteStrategy {
calculateRoute(start: string, end: string): string {
return `计算从 ${start} 到 ${end} 的路径,避开高速公路`;
}
}
// 上下文类 - 导航系统
class NavigationSystem {
private strategy: RouteStrategy;
constructor(strategy: RouteStrategy) {
this.strategy = strategy;
}
setStrategy(strategy: RouteStrategy): void {
this.strategy = strategy;
}
route(start: string, end: string): string {
return this.strategy.calculateRoute(start, end);
}
}
// 客户端代码
const nav = new NavigationSystem(new ShortestPathStrategy());
console.log(nav.route("北京", "上海"));
nav.setStrategy(new FastestPathStrategy());
console.log(nav.route("广州", "深圳"));
nav.setStrategy(new AvoidHighwaysStrategy());
console.log(nav.route("成都", "重庆"));
// 输出
// 计算从 北京 到 上海 的最短路径
// 计算从 广州 到 深圳 的最快路径
// 计算从 成都 到 重庆 的路径,避开高速公路
策略模式的主要优点
- 算法可以自由切换: 策略模式提供了管理相关的算法族的办法
- 避免使用多重条件转移语句: 如果不使用策略模式,在选择具体算法时就可能会使用多重条件转移语句
- 扩展性良好: 在不修改原有系统的基础上可以更换算法或增加新的算法
- 策略类之间可以自由切换: 由于策略类都实现同一个接口,使它们之间可以自由切换
策略模式的主要缺点
- 客户端必须知道所有的策略类: 客户端需要理解所有策略算法的区别,以便适时选择恰当的算法类
- 将造成产生很多策略类: 可能会增加系统的复杂度
- 会增加系统中类的数目: 每一个策略都是一个类,复用性较低
策略模式的适用场景
- 许多相关的类仅仅是行为有异: 这些行为可以提取出来作为独立的策略类
- 需要使用一个算法的不同变体: 例如,定义一些反映不同的空间/时间权衡的算法
- 算法使用客户端不应该知道的数据: 可以使用策略模式以避免暴露复杂的、与算法相关的数据结构
- 一个类定义了多种行为,这些行为在这个类的操作中以多个条件语句的形式出现
总结
策略模式是一种行为型设计模式,它定义了算法家族,分别封装起来,让它们之间可以互相替换。策略模式让算法的变化独立于使用算法的客户。这种模式提高了系统的灵活性和可扩展性,同时也提高了代码的可读性和可维护性。合理使用策略模式,可以让你的代码结构更加清晰,更易于理解和维护。
喜欢的话就点个赞 ❤️,关注一下吧,有问题也欢迎讨论指教。感谢大家!!!
下期预告: TypeScript 设计模式之【模板方法模式】