代码中经常遇到这样的场景:对一个业务处理过程抽象出来一个接口,针对不同的业务有不同的接口实现,然后有一个管理这些实现类的类根据业务信息负责路由到不同的实现类。实现方式大同小异,大致方式都是如此。
class XXHandlerManager { private Map<String, IHandler> handlerKeyToHandler; public void setHandlerKeyToHandler(Map<String,IHandler> handlers) { this. handlerKeyToHandler = handlers; } public IHandler getByBizInfo(xxBizInfo ...args) { String key = generateKey(args); if (handlerKeyToHandler.containsKey(key)) { return handlerKeyToHandler.get(key); } throw HandlerNotFoundException(); } private String generateKey(xxBizInfo ...args) { ..... } }
看到我们一个业务系统很多这种基本完全一样的代码,觉得或许可以提供一个简单的抽象,从而使代码简单清晰,减少冗余代码。小小思考了下,觉得可以简化抽象的,代码如下:
public class VelocityBaseKeyMapSelector<T> { private final static Logger LOG = LoggerFactory.getLogger(VelocityBaseKeyMapSelector.class); /** * 对象到字符串的转化模板 */ private String keyTemplate; /** * 对象字符串到处理器的映射 */ private Map<String, T> keyToHandler = Collections.emptyMap(); public void setKeyTemplate(String keyTemplate) { this.keyTemplate = keyTemplate; } public void setKeyToHandler(Map<String, T> keyToHandler) { this.keyToHandler = keyToHandler; } public T resolveHandler(Object ...objs) { String key = translateToString(objs); if (keyToHandler.containsKey(key)) { T handler = keyToHandler.get(key); if (LOG.isDebugEnabled()) { LOG.debug("found handler instance ({}) for data ({}).", handler.getClass().getSimpleName(), objs); } return handler; } return null; } /** * 根据对象信息以及Velocity模板生成标识Key */ protected String translateToString(Object ...objs) { Map<String, Object> ctx = Maps.newHashMap(); ctx.put("args", Lists.newArrayList(objs)); return VelocityUtil.rend(ctx, keyTemplate); } }
通过三个点实现了通用,1.使用泛型使得代码更加通用,对于key觉得没必要提取泛型;2.生成key的业务参数使用变参,表示不限制业务参数的维度;3.把“由业务参数生成key的算法”封装在了keyTemplate模板字符串,样式类似$args.get(0).name,预发满足Velocity语法即可,其中args是所有决定key的参数的List,顺序和方法中顺序一致,综合这三点这个工具类基本完全通用了,最起码我们的业务中的类似代码被消除了,事实上,业务完全不需要扩展,因为已经可变的部分交给配置了。结合Spring就会更舒服,来个小例子:
<bean id="platformBasedSelector" class="xxxxxx.VelocityBasedKeyMapSelector"> <property name="keyToHandler"> <map> <entry key="xxx" value-ref="xxxHandler" /> <entry key="yyy" value-ref="yyyHandler" /> <entry key="zzz" value-ref="zzzHandler" /> </map> </property> <property name="keyTemplate" value="$!args.get(0).platformId" /> </bean>
这样每个需要此类功能代码只需要配置一下注入即可,对于key算法的改写也就没必要去修改Java代码了,直接修改keyTemplate对应的模板字符串即可,当然也需要修改上边的handler对应的key。enjoy it!
相关推荐
"风很凉"可能是开发者的个人标识或者是软件的特色描述,"v1.0"则表示这是该软件的第一个正式版本。 在使用QQ好友查找器时,用户需要注意隐私保护和合法合规性。因为访问和操作他人的QQ好友信息可能涉及到用户的隐私...
首先,MATLAB提供了仪器控制工具箱(Instrument Control Toolbox),它包含了一系列函数和类,用于查找、配置和控制各种类型的硬件设备,如示波器、信号发生器等。在标题和描述中提到的“查找仪器”功能,就是这个...
在VC++环境中,开发一个文件查找功能的对话框应用程序是一个常见的任务,这涉及到对操作系统文件系统接口的调用。在这个程序中,我们主要利用了Windows API中的`FindFirstFile`和`FindNextFile`函数来实现文件的遍历...
【超级文本查找替换器】是一款高效实用的工具,专门用于批量处理文件中的文本查找与替换操作。这款软件能够遍历指定文件夹及其所有子文件夹内的文件,对每个文件的内容进行精准查找和替换,极大地提高了工作效率,...
查找时先在一个索引表(通常较小且有序)中查找到目标所在的块,然后在该块内进行顺序查找。分块查找的平均时间复杂度优于纯顺序查找,尤其是在块大小适中且索引查找快速的情况下。 **二叉排序树**是一种自平衡的...
这里我们将深入探讨两种常见的查找算法:二分查找和顺序查找。 **一、顺序查找** 顺序查找是最基础的查找算法之一。它的工作原理是从数据集(如数组或列表)的第一个元素开始,逐个比较目标值与当前元素,直到找到...
在`TreeH.h`中,我们可能会看到一个名为`BinarySearchTree`的模板类,它的模板参数可以是任何可以比较大小的类型,如整型、浮点型或者自定义类型。模板类通常用于提高代码的可复用性,使得数据结构可以处理多种数据...
本文将深入探讨这些接口的用法以及如何在一个集合类中实现它们,同时结合二分法查找来提高搜索效率。 首先,`IComparable`接口用于定义对象之间的比较规则。当类实现`IComparable`时,它需要提供一个名为`CompareTo...
在IT领域,编程语言C#和.NET框架是开发桌面应用的常见工具,而"隐藏文件查找器"则是一个实用的应用程序,专为发现并管理计算机中的隐藏文件设计。这款应用程序基于C#编程语言,利用.NET Framework 1.1版本进行构建,...
"LCS 最长公共子序列"虽然不直接属于排序或查找,但它是比较和匹配问题中的一个重要概念,主要用于找出两个序列的最长公共子序列,广泛应用于生物信息学和文本处理等领域。 总的来说,这些算法和数据结构在不同的...
接着,通配符在Word查找与替换功能中扮演了非常重要的角色,它允许用户通过一个或多个字符的模式来指定查找的内容。通配符包括“?”代表任意单个字符,“*”代表任意多个字符,“^”用于指定行的开头,“$”指定行的...
文本查找替换编辑器是一种强大的工具...总之,文本查找替换编辑器是IT行业不可或缺的工具之一,无论是日常的文本处理还是专业的工作任务,都能发挥巨大的作用。熟练掌握其使用技巧,能显著提升工作效率,减少重复劳动。
Java解压和jar类查找工具是一种实用的开发辅助软件,尤其在处理大量jar包和zip文件时,能够高效地定位到所需的class文件。这个工具基于Java编程语言开发,支持在Linux和Windows操作系统环境下运行,其核心功能是通过...
"28个PHP常用类"可能包含了多个常见的、实用的类,这些类通常被广泛应用于各种PHP项目中,以解决特定的问题或提升开发效率。下面将详细讨论一些可能包含在这些类中的常见主题: 1. **错误和异常处理**: - `...
在C++中,你可以定义一个模板类,其中的成员函数可以处理不同类型的数据。例如,可以定义一个名为`Searcher`的模板类,包含`linear_search`(顺序查找)和`binary_search`(二分查找)两个成员函数,分别实现上述两...
在当今信息化时代,文件管理是日常工作中一项常见的任务,尤其在数据处理和整理中尤为重要。...对于对Python编程和文件处理感兴趣的读者来说,这篇文章不仅提供了解决问题的方法,也是理解Python编程实践的一个好例子。
7. **代码组织**:将相关的工具方法放在同一个类中,便于管理和查找。例如,所有与字符串处理相关的工具方法可以放在`StringUtil`类中。 8. **代码重用**:工具类的一个核心目标是提高代码复用性,避免重复编写相同...
标题中的"C#工具类库类库 包含所有的常用工具类"暗示了这是一个集合,包含了多种实用工具类,能够极大地提升开发效率。这些工具类涵盖了从文件操作到网络通信的多个领域。 首先,FTP操作类是用于与FTP服务器进行...
- **ImageMagick**: 可以通过Magick.NET库在C#中调用,它是一个跨平台的图像处理工具,支持多种格式的图片和视频处理。 6. 其他实用工具类: - **DateTime**: C#中的日期和时间处理类,提供了丰富的日期运算和...
标题提到的“JAVA中处理字符串的类”很可能就是一个这样的自定义工具类,它集成了对字符串进行各种操作的方法,旨在简化编程工作。 在Java中,最常用的字符串类是`String`。`String`类是不可变的,意味着一旦创建了...