【设计模式】策略模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

简介: 【设计模式】策略模式 ( 简介 | 适用场景 | 优缺点 | 代码示例 )

文章目录

一、策略模式简介

二、策略模式适用场景

三、策略模式优缺点

四、策略模式与其它设计模式

五、策略模式代码示例

1、促销策略接口

2、满减促销策略

3、返现促销策略

4、空促销策略

5、促销策略工厂

6、促销活动

7、测试类





一、策略模式简介


策略模式 : 定义了 算法家族 , 分别 封装起来 , 让它们之间 , 可以 相互替换 , 此模式 让 算法的变化 不会影响到 使用算法的用户 ;


将 不同的算法 , 封装到 不同的类 中 , 让它们之间可以 相互替换 ,

使用算法的用户 即 应用层 , 感知不到 算法已经被替换了 ;



实际的业务场景 :


不同业务逻辑 : 商品促销 , 促销策略 , 不同的促销策略算法 , 封装到不同的类中 ;

代码优化 : 如果代码中 , 有大量的 if … else … 代码 , 可以通过策略模式 , 替换相关逻辑 ;


策略模式类型 : 行为型 ;






二、策略模式适用场景


策略模式适用场景 :


行为切换 : 系统有 很多类 , 这些类的区别仅仅在于它们的 行为不同 ; 使用策略模式 , 可以 动态地 让 用户对象 在这些行为中, 选择一个行为 ;

将对象的 不同的行为 , 封装到 不同的类 中 , 每个行为对应一种策略 ;


算法选择 : 系统中需要 动态地 在 几种算法 中 选择一种 ;

算法 就是 策略 , 其中封装了一系列的业务逻辑及计算方式 ;

如 : 计算方式 , 给定两个数字 ; 使用加法策略 , 将两个数相加 ; 使用乘法策略 , 将两个数相乘 ;






三、策略模式优缺点


策略模式优点 :


开闭原则 : 策略模式 提供了 对 开闭原则 的支持 , 可以在不修改原有系统的基础上 , 选择不同的行为 , 也可以 额外扩展其它行为 ;

避免代码冗余 : 可以 避免使用多重条件判定语句 ; 可以避免出现大量的 if … else … 语句 , switch 语句等 ;

安全保密 : 策略模式可以 提高算法的 保密性 和 安全性 ; 在终端使用策略时 , 只需要知道策略的作用即可 , 不需要知道策略时如何实现的 ;


策略模式缺点 :


策略类选择 : 客户端 必须 知道所有的 策略类 , 并且自行决定 使用哪个策略类 ;


增加复杂性 : 如果系统很复杂 , 会 产生很多策略类 ;






四、策略模式与其它设计模式


策略模式与工厂模式 :


工厂模式 : 接受指令 , 创建出符合要求的具体对象 ;

工厂模式 分为 工厂方法模式 和 抽象工厂模式 , 工厂模式 是 创建型的设计模式 , 策略模式 是 行为型的设计模式 ;


策略模式 : 接受创建好的实例对象 , 从而实现不同的行为 ;



策略模式与状态模式 :


策略模式 : 使用策略模式时 , 客户端 需要知道使用哪个策略 ;

状态模式 : 使用状态模式时 , 客户端 不需要知道具体的状态 , 这些状态之间会自动转换 ;


设计模式选择 :


状态模式 : 如果系统中 , 某个对象存在多种状态 , 在不同状态下 , 行为有差异的话 , 使用状态模式 ;


策略模式 : 如果系统中 , 某个类的某个行为 , 有多种实现方式 , 使用策略模式 ;



策略模式 一般不是独立使用的 , 可能需要结合单例 , 工厂模式 , 享元模式 等多个设计模式 , 一起实现业务逻辑 ;


如果遇到大量的 if … else … 可以考虑是否可以抽象 对象 以及 行为 , 将其封装成策略模式 ;


如果一个对象的行为经常变化 , 扩展性要求比较高 , 也可以考虑使用策略模式 ;






五、策略模式代码示例


业务场景 :


商场促销活动 : 促销是商品的一个行为 , 促销行为 , 设置多个促销行为 , 将其封装到类中 ;



1、促销策略接口


package strategy;
/**
 * 促销策略接口
 *      所有的促销策略 , 都要实现该接口
 */
public interface PromotionStrategy {
    /**
     * 促销活动
     */
    void doPromotion();
}



2、满减促销策略


package strategy;
/**
 * 满减促销策略
 *      满 100 减 20
 */
public class ManJianPromotionStrategy implements PromotionStrategy {
    @Override
    public void doPromotion() {
        System.out.println("满减促销 , 满 100 减 20");
    }
}



3、返现促销策略


package strategy;
/**
 * 返现促销策略
 *      购买后返优惠券
 */
public class FanXianPromotionStrategy implements PromotionStrategy {
    @Override
    public void doPromotion() {
        System.out.println("返现促销 , 返优惠券 10 元");
    }
}



4、空促销策略


package strategy;
/**
 * 空的促销策略
 *      为了防止空指针
 */
public class EmptyPromotionStrategy implements PromotionStrategy{
    @Override
    public void doPromotion() {
        System.out.println("原价出售");
    }
}



5、促销策略工厂


package strategy;
import java.util.HashMap;
/**
 * 促销策略工厂
 */
public class PromotionStrategyFactory {
    private static HashMap<String, PromotionStrategy> PROMOTION_STRATEGY_MAP = new HashMap<>();
    static {
        PROMOTION_STRATEGY_MAP.put(PromotionKey.MANJIAN, new ManJianPromotionStrategy());
        PROMOTION_STRATEGY_MAP.put(PromotionKey.FANXIAN, new FanXianPromotionStrategy());
    }
    /**
     * 构造函数不能被外界访问
     */
    private PromotionStrategyFactory() {
    }
    /**
     * 根据传入的键值获取相应的促销策略
     * @param promotionKey
     * @return
     */
    public static PromotionStrategy getPromotionStrategy(String promotionKey) {
        PromotionStrategy promotionStrategy = PROMOTION_STRATEGY_MAP.get(promotionKey);
        return promotionStrategy != null ? promotionStrategy : new EmptyPromotionStrategy();
    }
    /**
     * 使用这种方式声明常量 , 可以起到逻辑上分组的作用
     */
    public interface PromotionKey {
        String MANJIAN = "ManJian";
        String FANXIAN = "FanXian";
    }
}



6、促销活动


package strategy;
/**
 * 促销活动
 */
public class PromotionActivity {
    /**
     * 促销策略 , 通过构造器注入
     */
    private PromotionStrategy promotionStrategy;
    public PromotionActivity(PromotionStrategy promotionStrategy) {
        this.promotionStrategy = promotionStrategy;
    }
    /**
     * 执行促销策略
     */
    public void executePromotionStrategy() {
        this.promotionStrategy.doPromotion();
    }
}



7、测试类


package strategy;
public class Main {
    public static void main(String[] args) {
        // 获取促销策略
        PromotionStrategy promotionStrategy = PromotionStrategyFactory.
                getPromotionStrategy(PromotionStrategyFactory.PromotionKey.FANXIAN);
        // 创建促销活动 , 并执行促销策略
        PromotionActivity promotionActivity = new PromotionActivity(promotionStrategy);
        // 执行促销策略
        promotionActivity.executePromotionStrategy();
    }
}


————————————————


目录
相关文章
|
2月前
|
设计模式 算法 Kotlin
Kotlin - 改良设计模式 - 策略模式
Kotlin - 改良设计模式 - 策略模式
55 4
|
27天前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
27天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
27天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
21天前
|
设计模式 存储 缓存
前端必须掌握的设计模式——策略模式
策略模式(Strategy Pattern)是一种行为型设计模式,旨在将多分支复杂逻辑解耦。每个分支类只关心自身实现,无需处理策略切换。它避免了大量if-else或switch-case代码,符合开闭原则。常见应用场景包括表单验证、风格切换和缓存调度等。通过定义接口和上下文类,策略模式实现了灵活的逻辑分离与扩展。例如,在国际化需求中,可根据语言切换不同的词条包,使代码更加简洁优雅。总结来说,策略模式简化了多条件判断,提升了代码的可维护性和扩展性。
|
2月前
|
设计模式 算法 Kotlin
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
Kotlin教程笔记(53) - 改良设计模式 - 策略模式
53 1
|
2月前
|
设计模式 前端开发 JavaScript
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
47 2
|
22天前
|
设计模式 前端开发 搜索推荐
前端必须掌握的设计模式——模板模式
模板模式(Template Pattern)是一种行为型设计模式,父类定义固定流程和步骤顺序,子类通过继承并重写特定方法实现具体步骤。适用于具有固定结构或流程的场景,如组装汽车、包装礼物等。举例来说,公司年会节目征集时,蜘蛛侠定义了歌曲的四个步骤:前奏、主歌、副歌、结尾。金刚狼和绿巨人根据此模板设计各自的表演内容。通过抽象类定义通用逻辑,子类实现个性化行为,从而减少重复代码。模板模式还支持钩子方法,允许跳过某些步骤,增加灵活性。
|
2月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
4月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。