【设计模式实战】策略+工厂模式 解决多角色身份/多重if-else判断

116 阅读2分钟

需求:线上/线下 的 用户/商家 的 会员/非会员 三种身份组合关系,为每一个身份进行业务逻辑。 不用设计模式:if-else或者switch,硬编码,不利于后期维护和功能拓展 使用设计模式:优雅地添加配置类,完成每个类的功能解耦合,实现单一职责。

策略+工厂模式

策略:对于状态的选择

工厂:传入策略参数,生成具体策略

两者搭配可以解决多分支 ifelse 设计难题

1、 准备:

// 定义维度枚举
public enum Channel {
    ONLINE, OFFLINE
}
// 定义会员状态枚举类
public enum MemberStatus {
    MEMBER, NON_MEMBER
}
// 定义角色状态
public enum UserType {
    BUSINESS, CUSTOMER
}

2、策略类

/**
 * ---Do First---
 *
 * @author:wellseasun
 * @date:2025/6/26 上午 10:18
 * @desc: 策略接口
 */
public interface DiscountStrategy {
    void execute();
}

public class DefaultStrategy implements DiscountStrategy {
    @Override
    public void execute() {
        System.out.println("使用默认策略");
    }
}
/**
 * ---Do First---
 *
 * @author:wellseasun
 * @date:2025/6/26 上午 10:18
 * @desc: 线上商家会员策略
 */
public class OnlineBusinessMemberStrategy implements DiscountStrategy {
    @Override
    public void execute() {
        System.out.println("线上商户会员策略");
    }
}
/**
 * ---Do First---
 *
 * @author:wellseasun
 * @date:2025/6/26 上午 10:19
 * @desc: 线下消费者非会员策略
 */
public class OnlineCustomerNonMemberStrategy implements DiscountStrategy {
    @Override
    public void execute() {
        System.out.println("线上普通非会员:基础折扣");
    }
}
/**
 *  ……
 */

3、工厂类(根据策略参数返回具体的策略)

public class StrategyFactory {
    private static final Map<String, DiscountStrategy> strategies = new HashMap<>();

    // 通过静态代码块提前把策略放入map中
    static{
        strategies.put(buildKey(Channel.ONLINE,UserType.BUSINESS,MemberStatus.MEMBER),
                new OnlineBusinessMemberStrategy());
        strategies.put(buildKey(Channel.ONLINE,UserType.CUSTOMER,MemberStatus.NON_MEMBER),
                new OnlineCustomerNonMemberStrategy());
    }

    // 根据Channle、UserType、MemberStatus获取对应的策略
    public static DiscountStrategy getStrategy(Channel c,
                                               UserType u,
                                               MemberStatus m){
        String key = buildKey(c,u,m);
        return strategies.get(key);
    }

    // 构建策略的key
    private static String buildKey(Channel c, UserType u, MemberStatus m){
        return c.name() + u.name() + m.name();
    }
}

4、客户端

public class Client {
    public static void main(String[] args) {
        // 模拟获取业务参数
        Channel online = Channel.ONLINE;
        UserType business = UserType.BUSINESS;
        MemberStatus member = MemberStatus.MEMBER;

        //从工厂中建造一个策略
        DiscountStrategy strategy = StrategyFactory.getStrategy(online, business, member);

        // 执行策略
        strategy.execute();
    }
}