使用策略模式选择同一个接口的不同适配实现,基于SpringBoot工程进行:
1. 定义动物的统一行为接口AdaptAnimalService
package com.example.jvm.demo.service;
/**
* 动物行为接口
*
* @author fangxc
* @version V1.0.0
* @date 2022/2/10 13:51
*/
public interface AdaptAnimalService {
String CAT_SERVICE = "CAT";
String DOG_SERVICE = "DOG";
default String eat() throws Exception {
throw new RuntimeException();
}
default String cry() throws Exception {
throw new RuntimeException();
}
}
2.新增2个具体实现Cat和Dog
package com.example.jvm.demo.service.impl;
import com.example.jvm.demo.service.AdaptAnimalService;
import org.springframework.stereotype.Service;
/**
* Cat实现
*
* @author fangxc
* @version V1.0.0
* @date 2022/2/10 13:54
*/
@Service(AdaptAnimalService.CAT_SERVICE)
public class Cat implements AdaptAnimalService {
@Override
public String eat() throws Exception {
return "猫吃鱼!";
}
@Override
public String cry() throws Exception {
return "猫喵喵叫!";
}
}
package com.example.jvm.demo.service.impl;
import com.example.jvm.demo.service.AdaptAnimalService;
import org.springframework.stereotype.Service;
/**
* Dog实现
*
* @author fangxc
* @version V1.0.0
* @date 2022/2/10 13:56
*/
@Service(AdaptAnimalService.DOG_SERVICE)
public class Dog implements AdaptAnimalService {
@Override
public String eat() throws Exception {
return "狗吃骨头!";
}
@Override
public String cry() throws Exception {
return "狗汪汪叫!";
}
}
3. 新增动物类型枚举AdaptAnimalEnum(可以不需要,只是为了代码的可阅读性以及后续可维护性)
package com.example.jvm.demo.enums;
import com.example.jvm.demo.service.AdaptAnimalService;
/**
* 动物类型枚举
*
* @author fangxc
* @version V1.0.0
* @date 2022/2/10 13:58
*/
public enum AdaptAnimalEnum {
CAT_SERVICE(AdaptAnimalService.CAT_SERVICE, 1, "猫服务"),
DOG_SERVICE(AdaptAnimalService.DOG_SERVICE, 2, "狗服务"),;
private String animalServiceName;
private int animalType;
private String animalDesc;
AdaptAnimalEnum(String animalServiceName, int animalType, String animalDesc) {
this.animalServiceName = animalServiceName;
this.animalType = animalType;
this.animalDesc = animalDesc;
}
public String getAnimalServiceName() {
return animalServiceName;
}
public int getAnimalType() {
return animalType;
}
public String getAnimalDesc() {
return animalDesc;
}
public static String getAnimalServiceNameByType(int animalType) {
for (AdaptAnimalEnum value : AdaptAnimalEnum.values()) {
if (value.getAnimalType() == animalType) {
return value.getAnimalServiceName();
}
}
return null;
}
}
4. 添加动物具体实现适配器AdaptAnimalContext
package com.example.jvm.demo.context;
import cn.hutool.core.util.StrUtil;
import com.example.jvm.demo.enums.AdaptAnimalEnum;
import com.example.jvm.demo.service.AdaptAnimalService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 动物具体实现适配器
*
* @author fangxc
* @version V1.0.0
* @date 2022/2/10 14:06
*/
@Component
public class AdaptAnimalContext {
@Autowired
public Map<String, AdaptAnimalService> adaptAnimalServiceMap = new ConcurrentHashMap<>();
/**
* 根据动物类型编码获取具体动物实现类
*
* @param animalType
* @return
*/
public AdaptAnimalService getAdaptAnimalServiceByType(int animalType) {
String animalServiceName = AdaptAnimalEnum.getAnimalServiceNameByType(animalType);
if (StrUtil.hasBlank(animalServiceName)) {
throw new RuntimeException("animalType:'" + animalType + "' does not exists!");
}
AdaptAnimalService strategy = adaptAnimalServiceMap.get(animalServiceName);
if (strategy == null) {
throw new RuntimeException("No AnimalService Matched, AnimalServiceName : " + animalServiceName);
}
return strategy;
}
}
5. 单元测试下,看下实际运行效果
@Autowired
private AdaptAnimalContext adaptAnimalContext;
@Test
public void animalAdaptTest1() throws Exception {
System.out.println(adaptAnimalContext.getAdaptAnimalServiceByType(1).eat());
System.out.println(adaptAnimalContext.getAdaptAnimalServiceByType(1).cry());
System.out.println(adaptAnimalContext.getAdaptAnimalServiceByType(2).eat());
System.out.println(adaptAnimalContext.getAdaptAnimalServiceByType(2).cry());
System.out.println(adaptAnimalContext.getAdaptAnimalServiceByType(3).eat());
}
6. 此种方式,在例如支付收银台场景中,支付是一个通用的行为,它的具体实现可以是支付宝、微信、云闪付、银联等,可以让代码更加优雅,后续的可阅读性和可维护性相对友好(当然你要是觉得if-else就是天,那你说得对)