【设计模式_02】使用策略模式实现主键算法的切换

本文主要有以下内容:

  • 策略模式

策略模式:策略模式是一种行为型模式,通常用来定义同一行为或逻辑的不同实现,如主键生成策略的不同算法,

实现方式:

  • 抽取出不同方式完成同特定任务的类,将其共有的逻辑抽取出来定义在被称为策略的独立类或者接口。
  • 在一个称之为上下文的类中保留其策略类的引用,用于替换不同类型的实现。上下文并不执行,而是将其委托给其具体实现类执行。

类图如下:

一个简单的代码示例,策略接口和策略具体实现代码如下:

java 复制代码
public interface Strategy {
    void execute();
}
public class ConcreteStrategyA implements Strategy {
    @Override
    public void execute() {
        log.info("ConcreteStrategy execute: 策略设计模式:具体实现类A");
    }
}
public class ConcreteStrategyB implements Strategy {
    @Override
    public void execute() {
        log.info("ConcreteStrategyB execute:策略设计模式具体实现B");
    }
}

在上下文类中保持对策略的引用。代码如下:

java 复制代码
public class Context {
    private Strategy strategy;
​
    public Context() {
    }
    public void execute() {
        strategy.execute();
    }
}

客户端使用:

java 复制代码
public static void main(String[] args) {
    Context context = new Context();
​
    ConcreteStrategyA strategyA = new ConcreteStrategyA();
    context.setStrategy(strategyA);
​
    context.execute();
    ConcreteStrategyB concreteStrategyB = new ConcreteStrategyB();
    context.setStrategy(concreteStrategyB);
​
    context.execute();
}

在实际的项目开发中。如项目中完成某一个事情有多种方式,就可以采用此设计模式。在Springboot中使用,以主键生成策略为例:主键策略的不同实现:如雪花主键、随机生成主键、短主键。

java 复制代码
public interface IIdGenerator {
    /**
     * 功能: 生成主键
     * @return long
     */
    long nextId();
}

代码的具体实现如下:

java 复制代码
// 随机主键
@Component
public class RandomNumeric implements IIdGenerator {
    @Override
    public long nextId() {
        return Long.parseLong(RandomStringUtils.randomNumeric(11));
    }
}
// 短码主键
@Component
public class ShortCode implements IIdGenerator {
    @Override
    public long nextId() {
        Calendar calendar = Calendar.getInstance();
        int year = calendar.get(Calendar.YEAR);
        int week = calendar.get(Calendar.WEEK_OF_YEAR);
        int day = calendar.get(Calendar.DAY_OF_WEEK);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
​
        // 打乱排序:2024年为准
        StringBuilder idStr = new StringBuilder();
        idStr.append(year - 2024);
        idStr.append(day);
        idStr.append(String.format("%02d", week));
        idStr.append(hour);
        return Long.parseLong(idStr.toString());
    }
}
// 雪花主键
@Component
public class SnowFlake implements IIdGenerator {
    private Snowflake snowflake;
​
    @PostConstruct
    public void init() {
        // 0 ~ 31 位,可以采用配置的方式使用
        long workerId;
        try {
            workerId = NetUtil.ipv4ToLong(NetUtil.getLocalhostStr());
        } catch (Exception e) {
            workerId = NetUtil.getLocalhostStr().hashCode();
        }
        workerId = workerId >> 16 & 31;
        long dataCenterId = 1L;
        snowflake = IdUtil.createSnowflake(workerId, dataCenterId);
    }
​
    @Override
    public synchronized long nextId() {
        return snowflake.nextId();
    }
}

建立上下文引用:并通过自动注入的方式注入。

Java 复制代码
// 枚举类
  public enum Ids {
      SnowFlake,
      ShortCode,
      RandomNumeric;
  }
@Configuration
public class IdContext {
    @Bean
    public Map<Constants.Ids, IIdGenerator> idGenerator(SnowFlake snowFlake,
                                                        ShortCode shortCode,
                                                        RandomNumeric randomNumeric) {
        Map<Constants.Ids, IIdGenerator> idGeneratorMap = new HashMap<>(8);
        idGeneratorMap.put(Constants.Ids.SnowFlake, snowFlake);
        idGeneratorMap.put(Constants.Ids.ShortCode, shortCode);
        idGeneratorMap.put(Constants.Ids.RandomNumeric, randomNumeric);
        return idGeneratorMap;
    }
}

接下来就可以在需要使用的地方注入此map,这样就可以在项目中随心所欲的使用了。

ps:最近的事情太多了,导致断更太久了。先试着写写复健复健。努力保持、每天学习一点点。

相关推荐
昵称小白6 分钟前
复杂度分析方法
算法
科研前沿19 分钟前
2026 数字孪生前沿科技:全景迭代报告 —— 镜像视界生成式孪生(Generative DT)技术白皮书
大数据·人工智能·科技·算法·音视频·空间计算
古城小栈2 小时前
从 cargo-whero 库中,找到提升 rust 的契机
开发语言·后端·rust
keep one's resolveY2 小时前
SpringBoot实现重试机制的四种方案
java·spring boot·后端
学涯乐码堂主2 小时前
有趣的“打擂台算法”
c++·算法·青少年编程·gesp
Tutankaaa3 小时前
知识竞赛题库设计全攻略
人工智能·算法
WolfGang0073213 小时前
代码随想录算法训练营 Day50 | 图论 part08
数据结构·算法·图论
阿丰资源4 小时前
基于Spring Boot的电影城管理系统(直接运行)
java·spring boot·后端
IT_陈寒4 小时前
SpringBoot自动配置的坑差点让我加班到天亮
前端·人工智能·后端
aini_lovee5 小时前
多目标粒子群优化(MOPSO)双适应度函数MATLAB实现
人工智能·算法·matlab