public interface HandlerMapResolver<K, V, R> {
boolean support(K key, V value);
R resolve(K key, V value);
}
import java.util.Collections;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.bson.types.ObjectId;
@Slf4j
@RequiredArgsConstructor
public class HandlerKafkaMessageResolverComposite {
private final List<HandlerMapResolver> resolvers;
public List<ObjectId> resolve(String key, String value) {
for (HandlerMapResolver resolver : this.resolvers) {
if (resolver.support(key, value)) {
return (List<ObjectId>)resolver.resolve(key, value);
}
}
log.warn("No resolver can handle this kafka message, key: {}, value: {}", key ,value);
return Collections.emptyList();
}
}
import java.util.Collections;
import java.util.List;
import org.bson.types.ObjectId;
public class OverrideEventResolver
implements HandlerMapResolver<String, String, List<ObjectId>> {
@Override
public boolean support(String key, String value) {
return true;
}
@Override
public List<ObjectId> resolve(String key, String value) {
return Collections.emptyList();
}
}
策略模式
比如SpringMVC的HandlerMethodArgumentResolver接口,使用HandlerMethodArgumentResolverComposite(实现HandlerMethodArgumentResolver接口),通过遍历内部所有的HandlerMethodArgumentResolver(当然有缓存 机制),选择support返回true的实例,并把接口的调用交给该实例处理
其实,我们在写业务代码的时候,很多童鞋喜欢用Map保存策略实现类,其实这样并不好,不够灵活,应该像spring这样提供一个support方法,可以支持更加复杂的逻辑判断
public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgumentResolver {
protected final Log logger = LogFactory.getLog(getClass());
private final List<HandlerMethodArgumentResolver> argumentResolvers =
new LinkedList<HandlerMethodArgumentResolver>();
private final Map<MethodParameter, HandlerMethodArgumentResolver> argumentResolverCache =
new ConcurrentHashMap<MethodParameter, HandlerMethodArgumentResolver>(256);
@Override
public boolean supportsParameter(MethodParameter parameter) {
return (getArgumentResolver(parameter) != null);
}
private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
if (result == null) {
for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) {
if (methodArgumentResolver.supportsParameter(parameter)) {
result = methodArgumentResolver;
this.argumentResolverCache.put(parameter, result);
break;
}
}
}
return result;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
if (resolver == null) {
throw new IllegalArgumentException("Unknown parameter type [" + parameter.getParameterType().getName() + "]");
}
return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
}
}