实用设计模式实战:工厂+策略

这个模式主要可以用来替代项目中的if/else

  public static void main(String[] args){
    String type = "common";
    operateByType(type);
  }

  private static void operateByType(String type) {
    if ("common".equals(type)){
      System.out.println("先查询缓存,缓存没有在查询数据库,同时更新缓存");
    }
    if ("update".equals(type)){
      System.out.println("直接更新缓存");
    }
  }

以上初级代码使用设计模式改造

public interface AttributeNumberService {
  String getType();

  void operateByType();
}
@Slf4j
@Service
public class CommonAttributeNumberServiceImpl implements AttributeNumberService {

  @Override
  public String getType() {
    return "common";
  }

  @Override
  public void operateByType() {
     System.out.println("先查询缓存,缓存没有在查询数据库,同时更新缓存");
  }
}

@Slf4j
@Service
public class UpdateAttributeNumberServiceImpl implements AttributeNumberService {

  @Override
  public String getType() {
    return "update";
  }

  @Override
  public void operateByType() {
    System.out.println("直接更新缓存");
  }
}

在setApplicationContext 方法中获取实现了AttributeNumberService接口的所有类。添加到一个map(工厂)中


@Service
public class AttributeNumberStrategy implements ApplicationContextAware {

  private Map<String, AttributeNumberService> processServiceMap;

  public AttributeNumberService getProcessService(String type) {
    return processServiceMap.get(type);
  }

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    //获取AttributeNumberService接口的所有实现
      Map<String, AttributeNumberService> beansOfType =
        applicationContext.getBeansOfType(AttributeNumberService.class);
    processServiceMap = Maps.newHashMap();
    //put进容器  
    beansOfType.values().forEach(v -> processServiceMap.putIfAbsent(v.getType(), v));
  }
}

AttributeNumberStrategy类可以看成是一个工厂类,实现了ApplicationContextAware接口

ApplicationContextAware 接口是 Spring Framework 提供的一个接口,用于在 Spring 容器初始化时将应用程序上下文(ApplicationContext)实例传递给实现了该接口的类。通过实现这个接口,你可以在你的 Spring Bean 中获取到应用程序上下文,从而访问容器中的其他 Bean 或执行其他与容器相关的操作。
当一个类实现了 ApplicationContextAware 接口后,Spring 容器会在初始化这个 Bean 的时候调用其 setApplicationContext 方法,将当前的应用程序上下文作为参数传递进去。

使用时根据传的type不同,返回不同的实现类。调用相同的方法执行不同的逻辑。

  @Test
  public void operateByTypeTest(){
    AttributeNumberService processService = attributeNumberStrategy.getProcessService("update");
    processService.operateByType();
  }

注意,类型可以放在枚举中哦

@Getter
@AllArgsConstructor
public enum AffinityCacheEnum {

  COMMON("common", "普通"),

  UPDATE("update", "更新"),
  ;

  private final String type;

  private final String desc;
}

你可能感兴趣的:(设计模式,开发语言,java)