本文主要有以下内容:
- 策略模式
策略模式:策略模式是一种行为型模式,通常用来定义同一行为或逻辑的不同实现,如主键生成策略的不同算法,
实现方式:
- 抽取出不同方式完成同特定任务的类,将其共有的逻辑抽取出来定义在被称为策略的独立类或者接口。
- 在一个称之为上下文的类中保留其策略类的引用,用于替换不同类型的实现。上下文并不执行,而是将其委托给其具体实现类执行。
类图如下:
一个简单的代码示例,策略接口和策略具体实现代码如下:
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:最近的事情太多了,导致断更太久了。先试着写写复健复健。努力保持、每天学习一点点。