初识设计模式——策略模式(Strategy Pattern)

策略模式(Strategy Pattern)是一种行为型设计模式,其核心思想是将算法的定义与使用分离,允许在运行时动态选择不同的算法策略。
策略模式定义了算法家族,分别封装起来,让它们之间可以相互替换,此模式使得算法的变化,不会影响到使用算法的客户。
策略模式的组成
策略接口(Strategy)
定义所有支持算法的公共接口,声明算法执行的方法
1 |
|
具体策略类(Concrete Strategy)
实现策略接口,提供具体的算法实现。
1 | // 支付宝支付策略 |
上下文类(Context)
持有一个策略对象的引用,负责在运行时动态切换策略,并委托策略执行算法(策略模式名称的来源,需要在这里定义策略)。
1 | // 订单类,作为上下文类 |
客户端使用示例
1 | // 客户端代码 |
策略模式的优缺点
策略模式的优点
- 灵活性与扩展性:新增策略时只需实现接口,无需修改原有代码(开闭原则)。例如新增微信支付策略,只需添加WeChatPayStrategy类。
- 减少条件判断:避免在客户端使用大量if-else或switch-case语句,将条件逻辑转移到策略类中。
- 运行时动态切换:可根据业务需求在运行时灵活选择不同策略。例如电商订单可根据用户选择切换支付方式。
- 提高代码复用性:不同策略可被多个上下文共享,减少重复代码。
策略模式的缺点
- 客户端需了解策略细节:客户端必须知道所有策略类并决定使用哪一个,可能增加调用复杂度。
- 类数量增加:每个策略对应一个类,当策略较多时会导致系统类膨胀。
- 性能开销:策略对象可能需要频繁创建和销毁,若策略类较重(如包含大量数据),可能影响性能。
应用场景
- 算法动态切换:如支付方式、排序算法、加密策略等。
- 行为型功能扩展:避免通过继承扩展功能时的类爆炸问题。
- 消除条件判断:将复杂的条件逻辑抽取为独立策略。
策略模式与简单工厂模式的区别
策略模式和简单工厂模式都是软件开发中常用的设计模式,但它们有着不同的侧重点和应用场景
模式定义和核心意图
- 策略模式
- 定义:定义一系列的算法,并将每个算法封装起来,使它们可以相互替换。策略模式让算法的变化独立于使用算法的客户端。
- 核心意图:强调行为的封装和可替换性,旨在解决在多种算法实现中,客户端能够根据不同情况动态选择合适的算法,而不需要修改客户端代码。
- 简单工厂模式
- 定义:定义一个创建对象的类,由这个类来封装实例化对象的行为。
- 核心意图:将对象的创建和使用分离,客户端只需要通过工厂类获取所需的对象,而不需要关心对象的具体创建过程,提高代码的可维护性和可扩展性。
结构组成
- 策略模式
- 策略接口(Strategy):定义所有支持算法的公共接口,声明算法执行的方法。
- 具体策略类(Concrete Strategy):实现策略接口,提供具体的算法实现。
- 上下文类(Context):持有一个策略对象的引用,负责在运行时动态切换策略,并委托策略执行算法。
- 简单工厂模式
- 工厂类(Factory):负责创建对象的类,根据传入的参数决定创建哪种具体的产品对象。
- 抽象产品类(Product):定义产品的公共接口或抽象类。
- 具体产品类(Concrete Product):实现抽象产品类的具体产品。
应用场景
- 策略模式
- 当一个系统需要在多种算法中动态选择一种时,例如电商系统中的不同支付方式、游戏中的不同角色技能实现等。
- 当有多个类的区别仅在于它们的行为时,可以使用策略模式将这些行为封装成不同的策略类,以减少代码的重复。
- 简单工厂模式
- 当创建对象的逻辑比较复杂,且客户端不希望了解对象的创建细节时,例如数据库连接对象的创建、文件读取器对象的创建等。
- 当一个类需要根据不同的条件创建不同类型的对象时,使用简单工厂模式可以将创建逻辑集中在工厂类中,提高代码的可维护性。
侧重点
- 策略模式
- 侧重于算法的封装和切换,强调行为的变化和可替代性,客户端可以在运行时动态改变策略。
- 关注的是如何在不同的算法实现之间进行灵活选择和切换。
- 简单工厂模式
- 侧重于对象的创建过程,将对象的创建逻辑封装在工厂类中,客户端只需要使用工厂类获取对象,而不需要关心对象的具体创建细节。
- 关注的是如何将对象的创建和使用分离,提高代码的可维护性和可扩展性。
策略模式与简单工厂模式结合使用的案例
在代码开发中,可以将策略的选择权交给简单工厂类,让它来选择创建某个对象,这样方式可以解决策略模式中客户端需了解策略细节的缺点。以下使用一个API响应格式的需求来作为案例
策略模式
1 |
|
结合简单工厂模式
1 |
|