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); } }