Java设计模式超详解--策略设计模式(含uml图)

一,初步说明

策略设计模式就是在遇到一个问题时,可以自行采用不同策略进行解决

举个例子:现在我有2种计算工资的策略,针对不同情况,我选择不同策略

那我需要以下模块帮助我管理这些策略

interface Strategy

整合所有策略,告诉所有策略基本要完成什么任务

ConcreteStrategy

具体策略的实现方式

Context

管理策略所需要的数据等内容,相当于策略要实施前的准备与管理工作

二,题目理解

SalaryManager类管理计时工资,workHourList是历次工作的时长,hourlyRate是小时费率,计算计时工资有两种策略:

SaryComputerStrategyOne策略,累计工作时长*小时费率,若累计工作时长大于160,再乘以1.2

SaryComputerStrategyTwo策略,若单项工作时长大于40,则乘以1.2 ,累计后*小时费率

现在我们来把题目与通用类图一一对应

显然,我们这里要实现的策略分别是SaryComputerStrategyOne和SaryComputerStrategyTwo 那它们就属于ConcreteStrategy

SalaryManager则属于Context:对策略所需要的数据(这里是工资)进行管理

最后我们还需要一个interface Strategy来统一策略行为,这里命名为SaryComputerStrategy

画出类图如下:

代码

java 复制代码
import java.util.ArrayList;
import java.util.List;

/**
 * 薪资管理类(策略模式中的上下文Context)
 * 职责:管理员工的工作时长、时薪,维护当前使用的薪资计算策略,
 * 并提供对外的薪资计算入口
 */
class SalaryManager {

    // 存储员工每日/每月的工作时长列表
    private List<Double> workHourList = new ArrayList<Double>();

    // 薪资计算策略(核心:面向接口编程,解耦具体计算逻辑)
    private SaryComputerStrategy strage;

    // 每小时的基础薪资(时薪)
    private double hourlyRate;

    /**
     * 设置时薪
     * @param hourlyRate 每小时薪资金额
     */
    public void setHourlyRate(double hourlyRate) {
        this.hourlyRate = hourlyRate;
    }

    /**
     * 设置薪资计算策略(策略模式核心:动态切换计算规则)
     * @param strage 具体的薪资计算策略实现类
     */
    public void setStrage(SaryComputerStrategy strage) {
        this.strage = strage;
    }

    /**
     * 添加单次工作时长(如单日工作时长)
     * @param h 工作时长,单位:小时
     */
    public void addWorkHour(double h) {
        workHourList.add(h);
    }

    /**
     * 计算总薪资(委托给具体的策略类执行)
     * @return 计算后的总薪资金额
     */
    public double computerSalary() {
        // 调用策略接口的计算方法,将工作时长列表和时薪传递进去
        return strage.computerSalary(workHourList, hourlyRate);
    }
}

/**
 * 薪资计算策略接口(策略模式的Strategy接口)
 * 定义所有薪资计算策略必须实现的核心方法
 */
interface SaryComputerStrategy {

    /**
     * 计算总薪资的核心方法
     * @param list 工作时长列表(多个时段的工作时长)
     * @param rate 时薪(每小时薪资)
     * @return 计算后的总薪资
     */
    double computerSalary(List<Double> list, double rate);

}

/**
 * 薪资计算策略实现类1(示例:按总工时直接计算,无加班系数)
 */
class SaryComputerStrategyOne implements SaryComputerStrategy {

    @Override
    public double computerSalary(List<Double> workHourList, double hourlyRate) {
        // 1. 计算总工作时长
        double totalHours = 0.0;
        for (double hour : workHourList) {
            totalHours += hour;
        }
        // 2. 总薪资 = 总工时 * 时薪
        return totalHours * hourlyRate;
    }
}

/**
 * 薪资计算策略实现类2(示例:加班工时(超过40小时/天)按1.5倍计算)
 */
class SaryComputerStrategyTwo implements SaryComputerStrategy {

    @Override
    public double computerSalary(List<Double> workHourList, double hourlyRate) {
        double totalSalary = 0.0;
        // 遍历每个时段的工作时长,区分正常工时和加班工时
        for (double hour : workHourList) {
            if (hour <= 40) {
                // 正常工时:按原时薪计算
                totalSalary += hour * hourlyRate;
            } else {
                // 加班工时:40小时按正常算,超出部分按1.5倍算
                totalSalary += 40 * hourlyRate + (hour - 40) * hourlyRate * 1.5;
            }
        }
        return totalSalary;
    }
}

/**
 * 主测试类
 * 演示策略模式的使用:动态切换不同的薪资计算策略
 */
public class Main {

    public static void main(String[] args) {
        // 1. 创建薪资管理对象(上下文)
        SalaryManager salaryManager = new SalaryManager();
        
        // 2. 设置基础时薪:50元/小时
        salaryManager.setHourlyRate(50);
        
        // 3. 添加多段工作时长(模拟员工多日的工作时长)
        salaryManager.addWorkHour(52);   // 第一天52小时
        salaryManager.addWorkHour(40.5); // 第二天40.5小时
        salaryManager.addWorkHour(38.5); // 第三天38.5小时
        salaryManager.addWorkHour(60);   // 第四天60小时
        
        // 4. 使用策略1计算薪资(无加班系数)
        salaryManager.setStrage(new SaryComputerStrategyOne());
        System.out.println("策略1计算的总薪资:" + salaryManager.computerSalary());
        
        // 5. 切换为策略2计算薪资(含加班系数)
        salaryManager.setStrage(new SaryComputerStrategyTwo());
        System.out.println("策略2计算的总薪资:" + salaryManager.computerSalary());
    }
}

三,练习巩固

某软件公司欲开发一款汽车竞速类游戏,需要模拟长轮胎和短轮胎急刹车时在路面上留下的不同痕迹,并考虑后续能模拟更多种轮胎急刹车时的痕迹。现采用策略(Strategy)设计模式来实现该需求

java 复制代码
interface BrakeBehavior {

    public abstract void stop();

}

/**



此部分代码需要你编写并提交!



**/




public class Main {

    public static void main(String[] args) {

        BrakeBehavior brake1 = new ShortWheelBrake();

        BrakeBehavior brake2 = new LongWheelBrake();

        Car car = new ShortWheelCar(brake1);

        car.brake();

        car = new LongWheelCar(brake2);

        car.brake();

    }

}

uml图:

代码:

java 复制代码
class ShortWheelBrake implements BrakeBehavior{
    public void stop(){
        System.out.println("Simulate short tire brake marks!");
    }
    
}
class LongWheelBrake implements BrakeBehavior{
    public void stop(){
        System.out.println("Simulate long tire brake marks!");
    }
    
}
class Car{
    protected BrakeBehavior behavior;
    public Car(BrakeBehavior behavior){
        this.behavior=behavior;
    }
    public void brake(){
        behavior.stop();
    }
    
}

class ShortWheelCar extends Car{
    public ShortWheelCar(BrakeBehavior behavior){
        super(behavior);
    }
}

class LongWheelCar extends Car{
    public LongWheelCar(BrakeBehavior behavior){
        super(behavior);
    }
}

四,状态与策略

状态设计模式与策略设计模式可能会让人容易搞混

策略:是我要解决一个问题,可以选择不同策略,是主观的想要做什么,可以随心所欲,比如这里的我选择不同的工资计算或者选择不同类型的车
状态:是我想实现一个功能,这个功能本身必须要怎么做才能让系统完整,举个例子,我投币扭蛋,扭蛋机里的状态不是我能设计的,设计师不是我, 我只是求一个我做出行为后的结果(主播主页有状态设计模式详解哦~)

五,总结

在策略模式(Strategy Pattern)中一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

在策略模式定义了一系列算法或策略,并将每个算法封装在独立的类中,使得它们可以互相替换。通过使用策略模式,可以在运行时根据需要选择不同的算法,而不需要修改客户端代码。

在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

希望能帮到大家,设计模式持续更新,请多多关注,谢谢(ง •~•)งo(* ̄▽ ̄*)ブ

相关推荐
memgLIFE8 小时前
SQL 优化方法详解(1)
java·数据库·sql
2201_757830878 小时前
Bean原理篇
java·开发语言
小宇的天下8 小时前
Calibre 3Dstack--每日一个命令day 6 [process和export layout](3-6)
java·前端·数据库
牛奔8 小时前
docker compose up 命令,默认配置文件自动查找规则
java·spring cloud·docker·容器·eureka
工具罗某人8 小时前
docker快速部署jenkins
java·docker·jenkins
sxlishaobin8 小时前
设计模式之原型模式
设计模式·原型模式
华如锦8 小时前
四:从零搭建一个RAG
java·开发语言·人工智能·python·机器学习·spring cloud·计算机视觉
Tony_yitao8 小时前
22.华为OD机试真题:数组拼接(Java实现,100分通关)
java·算法·华为od·algorithm
JavaGuru_LiuYu8 小时前
Spring Boot 整合 SSE(Server-Sent Events)
java·spring boot·后端·sse
爬山算法8 小时前
Hibernate(26)什么是Hibernate的透明持久化?
java·后端·hibernate