您的当前位置:首页正文

Java经典案例 策略模式 替换大量 if else 辅以工厂 单例模式使结构更优雅 易于维护和扩展...

2024-11-11 来源:个人技术集锦

员工年假年终奖案例

  • 传统实现方案

难以修改维护,不利于扩展

if(普通员工){
    if(0~3年){
        if(男){
            // ...
        }else{
            // ...
        }    
    }else if(3~5年){            
        if(男){
            // ...
        }else{
            // ...
        }           
    }else{
        if(男){
            // ...
        }else{
            // ...
        }           
    }
}else if(主管){    
    
}else if(经理){    
    
}
  • 策略模式实现

把奖金、奖品、年假以策略的方式实现

策略结构:接口 < 抽象类 < 具体策略类

策略抽象类中存放相同的部分,具体策略类只实现不同的部分

具体策略类以工厂方法来实现,采用单例模式(静态内部类)

所有福利包装在枚举类中

福利枚举类 WelfareEnum

package strategy.employee.strategy;

/**
 * @author 土味儿
 * Date 2021/7/31
 * @version 1.0
 * 福利(枚举)
 */
public enum WelfareEnum {
    // MONEY5000 用于程序调用
    // 奖金
    MONEY_5000(1,"5000元"),
    MONEY_10000(2,"10000元"),
    MONEY_50000(3,"50000元"),

    // 奖品:手机
    BLACK_HUAWEI_PHONE(21,"黑色华为手机"),
    RED_HUAWEI_PHONE(22,"红色华为手机"),

    // 奖品:笔记本
    BLACK_HUAWEI_COMPUTER(41,"黑色华为笔记本"),
    RED_HUAWEI_COMPUTER(42,"红色华为笔记本"),

    // 年假
    LEAVE_5(61,"5天"),
    LEAVE_10(62,"10天"),
    LEAVE_15(63,"15天");

    // 福利代码(方便向数据库存储)
    private int code;
    // 福利描述(方便向用户展示)
    private String desc;

    WelfareEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }

    public int getCode() {
        return code;
    }

    public String getDesc() {
        return desc;
    }
}

年终奖金策略接口 BonusStrategy

package strategy.employee.strategy.bonus;

/**
 * @author 土味儿
 * Date 2021/8/1
 * @version 1.0
 * 年终奖金策略接口
 */
public interface BonusStrategy {
    /**
     * 获取奖金福利
     */
    void getAnnualBonus();
}

年终奖金策略抽象类 AbstractBonusStrategy

实现公共的部分:welfareList、getAnnualBonus()

public abstract class AbstractBonusStrategy implements BonusStrategy {
    // 奖金集合
    protected List<String> welfareList;

    /**
     * 获取奖金福利
     */
    @Override
    public void getAnnualBonus() {
        if(welfareList != null){
            for (String s : welfareList) {
                System.out.print(s + " ");
            }
            System.out.println();
        }else{
            System.out.println("无奖金!");
        }
    }
}

年终奖金具体策略类

只实现有差别的部分:构造器

无奖金

public class BonusStrategy0 extends AbstractBonusStrategy {
    /**
     * 构造器
     */
    public BonusStrategy0() {
        welfareList = new ArrayList<>();
    }
}

一级奖金

public class BonusStrategy1 extends AbstractBonusStrategy {
    /**
     * 构造器
     */
    public BonusStrategy1() {
        welfareList = new ArrayList<>();
        welfareList.add(WelfareEnum.MONEY_50000.getDesc());
    }
}

二级奖金

public class BonusStrategy2 extends AbstractBonusStrategy {
    /**
     * 构造器
     */
    public BonusStrategy2() {
        welfareList = new ArrayList<>();
        welfareList.add(WelfareEnum.MONEY_10000.getDesc());
    }
}

三级奖金

public class BonusStrategy3 extends AbstractBonusStrategy {
    /**
     * 构造器
     */
    public BonusStrategy3() {
        welfareList = new ArrayList<>();
        welfareList.add(WelfareEnum.MONEY_5000.getDesc());
    }
}

年终奖品策略接口 PrizeStrategy

package strategy.employee.strategy.prize;

/**
 * @author 土味儿
 * Date 2021/8/1
 * @version 1.0
 * 年终奖品策略接口
 */
public interface PrizeStrategy {
    /**
     * 得到奖品福利
     */
    void getAnnualPrize();
}

年终奖品策略抽象类 AbstractPrizeStrategy

public abstract class AbstractPrizeStrategy implements PrizeStrategy {
    // 奖品集合
    protected List<String> welfareList;

    /**
     * 得到奖品福利
     */
     @Override
     public void getAnnualPrize() {
        if (welfareList != null) {
            for (String s : welfareList) {
                System.out.print(s + " ");
            }
            System.out.println();
        } else {
            System.out.println("无奖品!");
        }
    }
}

年终奖品具体策略类

无奖品

public class PrizeStrategy0 extends AbstractPrizeStrategy {
    /**
     * 构造器
     */
    public PrizeStrategy0() {
        welfareList = new ArrayList<>();
    }
}

一级奖品

黑色

public class PrizeStrategy1 extends AbstractPrizeStrategy {
    /**
     * 构造器
     * 黑色
     */
    public PrizeStrategy1() {
        welfareList = new ArrayList<>();
        welfareList.add(WelfareEnum.BLACK_HUAWEI_PHONE.getDesc());
        welfareList.add(WelfareEnum.BLACK_HUAWEI_COMPUTER.getDesc());
    }
}

一级奖品

红色

public class PrizeStrategy21 extends AbstractPrizeStrategy {
    /**
     * 构造器
     * 红色
     */
    public PrizeStrategy21() {
        welfareList = new ArrayList<>();
        welfareList.add(WelfareEnum.RED_HUAWEI_PHONE.getDesc());
        welfareList.add(WelfareEnum.RED_HUAWEI_COMPUTER.getDesc());
    }
}

二级奖品

黑色

public class PrizeStrategy2 extends AbstractPrizeStrategy {
    /**
     * 构造器
     * 黑色
     */
    public PrizeStrategy2() {
        welfareList = new ArrayList<>();
        welfareList.add(WelfareEnum.BLACK_HUAWEI_COMPUTER.getDesc());
    }
}

二级奖品

红色

public class PrizeStrategy22 extends AbstractPrizeStrategy {
    /**
     * 构造器
     * 红色
     */
    public PrizeStrategy22() {
        welfareList = new ArrayList<>();
        welfareList.add(WelfareEnum.RED_HUAWEI_COMPUTER.getDesc());
    }
}

三级奖品

黑色

public class PrizeStrategy3 extends AbstractPrizeStrategy {
    /**
     * 构造器
     * 黑色
     */
    public PrizeStrategy3() {
        welfareList = new ArrayList<>();
        welfareList.add(WelfareEnum.BLACK_HUAWEI_PHONE.getDesc());
    }
}

三级奖品

红色

public class PrizeStrategy23 extends AbstractPrizeStrategy {
    /**
     * 构造器
     * 红色
     */
    public PrizeStrategy23() {
        welfareList = new ArrayList<>();
        welfareList.add(WelfareEnum.RED_HUAWEI_PHONE.getDesc());
    }
}

年假策略接口 LeaveStrategy

package strategy.employee.strategy.leave;

/**
 * @author 土味儿
 * Date 2021/8/1
 * @version 1.0
 * 年假策略接口
 */
public interface LeaveStrategy {
    /**
     * 获取年假福利
     */
    void getAnnualLeave();
}

年假策略抽象类 AnnualLeaveStrategy

public abstract class AbstractLeaveStrategy implements LeaveStrategy {
    // 年假福利
    protected List<String> welfareList;

    /**
     * 获取年假福利
     */
    @Override
    public void getAnnualLeave() {
        if(welfareList != null){
            for (String s : welfareList) {
                System.out.print(s + " ");
            }
            System.out.println();
        }else{
            System.out.println("无年假!");
        }
    }
}

年假具体策略类

无年假

public class LeaveStrategy0 extends AbstractLeaveStrategy {
    /**
     * 构造器
     */
    public LeaveStrategy0() {
        welfareList = new ArrayList<>();
    }
}

一级年假

public class LeaveStrategy1 extends AbstractLeaveStrategy {
    /**
     * 构造器
     */
    public LeaveStrategy1() {
        welfareList = new ArrayList<>();
        welfareList.add(WelfareEnum.LEAVE_15.getDesc());
    }
}

二级年假

public class LeaveStrategy2 extends AbstractLeaveStrategy {
    /**
     * 构造器
     */
    public LeaveStrategy2() {
        welfareList = new ArrayList<>();
        welfareList.add(WelfareEnum.LEAVE_10.getDesc());
    }
}

三级年假

public class LeaveStrategy3 extends AbstractLeaveStrategy {
    /**
     * 构造器
     */
    public LeaveStrategy3() {
        welfareList = new ArrayList<>();
        welfareList.add(WelfareEnum.LEAVE_5.getDesc());
    }
}

策略工厂类 StrategyFactory

生产所有策略类实例(单例模式:静态内部类)

package strategy.employee.strategy;

import strategy.employee.strategy.bonus.*;
import strategy.employee.strategy.leave.*;
import strategy.employee.strategy.prize.*;

/**
 * @author 土味儿
 * Date 2021/7/31
 * @version 1.0
 * 策略工厂类
 * 生产各个具体的策略类
 */
public class StrategyFactory {
    // =========== 奖金 =============
    /**
     * 静态内部类
     * 无奖金
     */
    private static class Bonus0{
        private static final BonusStrategy BONUS_0 = new BonusStrategy0();
    }
    /**
     * 静态内部类
     * 一级奖金
     */
    private static class Bonus1{
        private static final BonusStrategy BONUS_1 = new BonusStrategy1();
    }
    /**
     * 静态内部类
     * 二级奖金
     */
    private static class Bonus2{
        private static final BonusStrategy BONUS_2 = new BonusStrategy2();
    }
    /**
     * 静态内部类
     * 三级奖金
     */
    private static class Bonus3{
        private static final BonusStrategy BONUS_3 = new BonusStrategy3();
    }

    /**
     * 得到无奖金策略实例
     * @return
     */
    public static BonusStrategy getBonusInstance0(){
        return Bonus0.BONUS_0;
    }

    /**
     * 得到一级奖金策略实例
     * @return
     */
    public static BonusStrategy getBonusInstance1(){
        return Bonus1.BONUS_1;
    }

    /**
     * 得到二级奖金策略实例
     * @return
     */
    public static BonusStrategy getBonusInstance2(){
        return Bonus2.BONUS_2;
    }

    /**
     * 得到三级奖金策略实例
     * @return
     */
    public static BonusStrategy getBonusInstance3(){
        return Bonus3.BONUS_3;
    }

    // =========== 年假 =============
    /**
     * 静态内部类
     * 无年假
     */
    private static class Leave0{
        private static final LeaveStrategy LEAVE_0 = new LeaveStrategy0();
    }
    /**
     * 静态内部类
     * 一级年假
     */
    private static class Leave1{
        private static final LeaveStrategy LEAVE_1 = new LeaveStrategy1();
    }
    /**
     * 静态内部类
     * 二级年假
     */
    private static class Leave2{
        private static final LeaveStrategy LEAVE_2 = new LeaveStrategy2();
    }
    /**
     * 静态内部类
     * 三级年假
     */
    private static class Leave3{
        private static final LeaveStrategy LEAVE_3 = new LeaveStrategy3();
    }

    /**
     * 得到无年假策略实例
     * @return
     */
    public static LeaveStrategy getLeaveInstance0(){
        return Leave0.LEAVE_0;
    }
    /**
     * 得到一级年假策略实例
     * @return
     */
    public static LeaveStrategy getLeaveInstance1(){
        return Leave1.LEAVE_1;
    }
    /**
     * 得到二级年假策略实例
     * @return
     */
    public static LeaveStrategy getLeaveInstance2(){
        return Leave2.LEAVE_2;
    }
    /**
     * 得到三级年假策略实例
     * @return
     */
    public static LeaveStrategy getLeaveInstance3(){
        return Leave3.LEAVE_3;
    }

    // =========== 奖品 =============
    /**
     * 静态内部类
     * 无奖品
     */
    private static class Prize0{
        private static final PrizeStrategy PRIZE_0 = new PrizeStrategy0();
    }
    /**
     * 静态内部类
     * 一级奖品
     */
    private static class Prize1{
        private static final PrizeStrategy PRIZE_1 = new PrizeStrategy1();
    }
    /**
     * 静态内部类
     * 二级奖品
     */
    private static class Prize2{
        private static final PrizeStrategy PRIZE_2 = new PrizeStrategy2();
    }
    /**
     * 静态内部类
     * 三级奖品
     */
    private static class Prize3{
        private static final PrizeStrategy PRIZE_3 = new PrizeStrategy3();
    }
    /**
     * 静态内部类
     * 一级奖品
     */
    private static class Prize21{
        private static final PrizeStrategy PRIZE_21 = new PrizeStrategy21();
    }
    /**
     * 静态内部类
     * 二级奖品
     */
    private static class Prize22{
        private static final PrizeStrategy PRIZE_22 = new PrizeStrategy22();
    }
    /**
     * 静态内部类
     * 三级奖品
     */
    private static class Prize23{
        private static final PrizeStrategy PRIZE_23 = new PrizeStrategy23();
    }

    /**
     * 得到无奖品策略实例
     * @return
     */
    public static PrizeStrategy getPrizeInstance0(){
        return Prize0.PRIZE_0;
    }
    /**
     * 得到一级奖品策略实例
     * @return
     */
    public static PrizeStrategy getPrizeInstance1(){
        return Prize1.PRIZE_1;
    }
    /**
     * 得到二级奖品策略实例
     * @return
     */
    public static PrizeStrategy getPrizeInstance2(){
        return Prize2.PRIZE_2;
    }
    /**
     * 得到三级奖品策略实例
     * @return
     */
    public static PrizeStrategy getPrizeInstance3(){
        return Prize3.PRIZE_3;
    }
    /**
     * 得到一级奖品策略实例
     * @return
     */
    public static PrizeStrategy getPrizeInstance21(){
        return Prize21.PRIZE_21;
    }
    /**
     * 得到二级奖品策略实例
     * @return
     */
    public static PrizeStrategy getPrizeInstance22(){
        return Prize22.PRIZE_22;
    }
    /**
     * 得到三级奖品策略实例
     * @return
     */
    public static PrizeStrategy getPrizeInstance23(){
        return Prize23.PRIZE_23;
    }
}

员工抽象类 Employee

package strategy.employee.employee;

import strategy.employee.strategy.bonus.BonusStrategy;
import strategy.employee.strategy.leave.LeaveStrategy;
import strategy.employee.strategy.prize.PrizeStrategy;

/**
 * @author 土味儿
 * Date 2021/7/31
 * @version 1.0
 * 员工抽象类
 */
public abstract class Employee {
    // 年终奖金(聚合)
    protected BonusStrategy bonusStrategy;
    // 年终奖品(聚合)
    protected PrizeStrategy prizeStrategy;
    // 年假(聚合)
    protected LeaveStrategy leaveStrategy;

    // 员工属性:姓名、性别、入职年限
    protected String name;
    protected int sex;
    protected int years;

    /**
     * 得到年终奖金
     */
    public void getAnnualBonus() {
        if (bonusStrategy != null) {
            System.out.print("年终奖金:");
            bonusStrategy.getAnnualBonus();
        }
    }

    /**
     * 得到年终奖品
     */
    public void getAnnualPrize() {
        if (prizeStrategy != null) {
            System.out.print("年终奖品:");
            prizeStrategy.getAnnualPrize();
        }
    }

    /**
     * 得到年假
     */
    public void getAnnualLeave() {
        if (leaveStrategy != null) {
            System.out.print("年假:");
            leaveStrategy.getAnnualLeave();
        }
    }

    /**
     * 得到员工信息
     */
    public abstract void display();
}

普通员工 GeneralEmployee

public class GeneralEmployee extends Employee{
    /**
     * 构造器
     * @param name
     * @param sex
     * @param years
     */
    public GeneralEmployee(String name,int sex,int years) {
        this.name = name;
        this.sex = sex;
        this.years = years;

        // 三级年终奖
        bonusStrategy = StrategyFactory.getBonusInstance3();
        // 三级年假
        leaveStrategy = StrategyFactory.getLeaveInstance3();

        // 三年以上工龄三级年终奖品
        if(years >= 3){
            // 女生红色,男生黑色
            prizeStrategy = sex > 0 ? StrategyFactory.getPrizeInstance23():StrategyFactory.getPrizeInstance3();
        }
    }

    @Override
    public void display() {
        System.out.println("\n====== 普通员工 ======");
        System.out.println(name + "," + (sex > 0 ? "女,入职 " : "男,入职 ") + years + " 年");
        System.out.println("--------------------");
    }
}

主管 GroupLeaderEmployee

public class GroupLeaderEmployee extends Employee{
    /**
     * 构造器
     * @param name
     * @param sex
     * @param years
     */
    public GroupLeaderEmployee(String name,int sex,int years) {
        this.name = name;
        this.sex = sex;
        this.years = years;

        // 二级年终奖
        bonusStrategy = StrategyFactory.getBonusInstance2();
        // 二级年假
        leaveStrategy = StrategyFactory.getLeaveInstance2();

        // 三年以上工龄二级年终奖品
        if(years < 3){
            // 女生红色,男生黑色
            prizeStrategy = sex > 0 ? StrategyFactory.getPrizeInstance23():StrategyFactory.getPrizeInstance3();
        }else if(years < 5){
            // 女生红色,男生黑色
            prizeStrategy = sex > 0 ? StrategyFactory.getPrizeInstance22():StrategyFactory.getPrizeInstance2();
        }else{
            // 女生红色,男生黑色
            prizeStrategy = sex > 0 ? StrategyFactory.getPrizeInstance21():StrategyFactory.getPrizeInstance1();
        }
    }

    @Override
    public void display() {
        System.out.println("\n====== 主管 ======");
        System.out.println(name + "," + (sex > 0 ? "女,入职 " : "男,入职 ") + years + " 年");
        System.out.println("--------------------");
    }
}

经理 ManagerEmployee

public class ManagerEmployee extends Employee{
    /**
     * 构造器
     * @param name
     * @param sex
     * @param years
     */
    public ManagerEmployee(String name,int sex,int years) {
        this.name = name;
        this.sex = sex;
        this.years = years;

        // 一级年终奖
        bonusStrategy = StrategyFactory.getBonusInstance1();
        // 一级年假
        leaveStrategy = StrategyFactory.getLeaveInstance1();

        // 三年以上工龄二级年终奖品
        if(years < 3){
            // 女生红色,男生黑色
            prizeStrategy = sex > 0 ? StrategyFactory.getPrizeInstance23():StrategyFactory.getPrizeInstance3();
        }else if(years < 5){
            // 女生红色,男生黑色
            prizeStrategy = sex > 0 ? StrategyFactory.getPrizeInstance22():StrategyFactory.getPrizeInstance2();
        }else{
            // 女生红色,男生黑色
            prizeStrategy = sex > 0 ? StrategyFactory.getPrizeInstance21():StrategyFactory.getPrizeInstance1();
        }
    }

    @Override
    public void display() {
        System.out.println("\n====== 经理 ======");
        System.out.println(name + "," + (sex > 0 ? "女,入职 " : "男,入职 ") + years + " 年");
        System.out.println("--------------------");
    }
}

测试客户端 Client

package strategy.employee;

import strategy.employee.employee.*;

/**
 * @author 土味儿
 * Date 2021/7/31
 * @version 1.0
 * 测试客户端
 */
public class Client {
    public static void main(String[] args) {
        // 普通员工
        Employee generalEmployee = new GeneralEmployee("小红", 1, 3);
        generalEmployee.display();
        generalEmployee.getAnnualBonus();
        generalEmployee.getAnnualPrize();
        generalEmployee.getAnnualLeave();
        // 主管
        Employee groupLeaderEmployee = new GroupLeaderEmployee("张三", 0, 4);
        groupLeaderEmployee.display();
        groupLeaderEmployee.getAnnualBonus();
        groupLeaderEmployee.getAnnualPrize();
        groupLeaderEmployee.getAnnualLeave();

        // 经理
        Employee managerEmployee = new ManagerEmployee("李四", 0, 5);
        managerEmployee.display();
        managerEmployee.getAnnualBonus();
        managerEmployee.getAnnualPrize();
        managerEmployee.getAnnualLeave();
    }
}

运行结果

====== 普通员工 ======
小红,女,入职 3 年
--------------------
年终奖金:5000元 
年终奖品:红色华为手机 
年假:5天 

====== 主管 ======
张三,男,入职 4 年
--------------------
年终奖金:10000元 
年终奖品:黑色华为笔记本 
年假:10天 

====== 经理 ======
李四,男,入职 5 年
--------------------
年终奖金:50000元 
年终奖品:黑色华为手机 黑色华为笔记本 
年假:15天
Top