Java 应用于文本规范化器链的设计模式

Java 应用于文本规范化器链的设计模式,java,design-patterns,Java,Design Patterns,我有一个程序,它定期接收包含我逐行处理的多行文件。为了处理这些行,我开发了一些文本规范化程序,可以对行进行转换。例如,一个规范化可以是删除停止词、语法更正、删除URL等 用于给定文件的规范化器必须动态决定,这样我就可以更改它们的数量并改变其顺序。对于某些文件,我只需要删除,例如stopwords,但其他文件需要更多的规范化程序,在某些情况下,我必须应用一个规范化程序两次 我组织代码的第一个想法是应用责任链模式。在这种情况下,我会有这样的东西: 如图中所示,按顺序使用三个规范化器,然后再次使用第

我有一个程序,它定期接收包含我逐行处理的多行文件。为了处理这些行,我开发了一些文本规范化程序,可以对行进行转换。例如,一个规范化可以是删除停止词、语法更正、删除URL等

用于给定文件的规范化器必须动态决定,这样我就可以更改它们的数量并改变其顺序。对于某些文件,我只需要删除,例如stopwords,但其他文件需要更多的规范化程序,在某些情况下,我必须应用一个规范化程序两次

我组织代码的第一个想法是应用责任链模式。在这种情况下,我会有这样的东西:

如图中所示,按顺序使用三个规范化器,然后再次使用第一个规范化器。这只是一个例子。在其他escenario中,我可以有7个不重复的规范化器,而在其他情况下,第二个规范化器将在第三个之前执行。所以,主要的想法是有多个规范化器,并定义一个可以重复的链

我使用这种方法的问题是,链的所有成员都是始终执行的(没有拒绝条件),而且我有成千上万的行要处理,所以我不想花很多时间在链上迭代

所以,我的问题是,实现我所需要的东西的最佳方式是什么?这样我就有机会添加新的规范化器,而不必重写代码,并在链式迭代中保持高速

如果您需要更多信息,请询问,我将编辑问题。

“这种方法的问题是,链的所有成员都始终执行(无拒绝条件),我有成千上万的行要处理,因此我不想花费大量时间在链上迭代。”

大卫

这有点矛盾。您说要执行所有规范化程序,
e、 g.1,2,3,1,按此顺序在文件的每一行上。然后你说你的
问题是你执行了所有这些操作,这可能会减慢你的速度。这是
取决于当前正在处理的行的规范化程序序列?
如果它不是依赖的,并且您需要在所有行上运行1,2,3,1,那么您
只是需要去做。我真的不明白你如何才能避免打电话给某些人

但仍在每行调用所有的规范化器

我不知道以下内容是否符合您的建筑理念

从XML中的声明性控件模型开始:

  • 正常化者。
    • 每个规范化程序都可以提供的控制消息
  • 规格化器的默认序列
  • 根据控制消息执行的操作-“随后添加规范化器3,删除之前的规范化器1”
这使得我们能够对变化的综合影响进行推理。将控制消息(无更多标记)与实际操作(移除标记规范化器)分离可能是合适的

可以使用POJO和注释通过JAXB读取XML。很简单


控制胶可以记录所有的,因此可以确定不会发生次优情况。

我想看看的分析仪设计,它基本上是一个合成对象的抽象工厂(
分析仪
),并完成与您描述的任务类似的任务。

当您为每行执行所有规范化程序时,设计模式是一个命令列表,因为没有检查每个规范化程序的责任

据我所知,每个文件的规范化器列表是恒定的,因此创建它不是一个问题。您还说过,您对每一行迭代所有这些代码,因此唯一可以调整性能的就是迭代本身

我会使用这样的设计: 1) 所有规范化程序都实现一个公共接口

interface Normalizer {
  String normalize(String line);
}
你很可能已经准备好了类似的东西

2) 打开文件(或开始处理文件)时,您可以确定需要哪些规范化程序。除非你的文件很短,而且你有很多,否则你怎么做并不重要。您可以有一个工厂,为某些条件返回适当的规范化器列表。它可以使用类名的文本列表,也可以创建硬编码的命令列表。也可以考虑JoopEGGEN的答案。
class Factory {
  List<Normalizer> buildNormalizers(DeterminingCriteria criteria) { ... } 
}
类工厂{
列表构建规范化程序(确定标准){…}
}
如果您需要在不重新部署的情况下更改列表,那么带有类名列表的文本文件就很方便了。如果此时还需要添加一个新的规范化程序,那么无论如何都需要更改代码,因此构建规范化程序列表的类也可以

因为这里的规范化程序需要是无状态的,所以可以重用列表中的双规范化程序。事实上,您可以对所有文件重用所有规范化程序,除非您的应用程序一次又一次地为每个文件启动。由于您的命令是无状态的,因此如果需要,它们也会同时处理不同的文件。可能使用这样的设计:

  class Factory {
    private Map<Criteria, Normalizer> cachedNormalizers;
    public Factory() {
      // create all normalizers from a master map 
      // or hard coded here and add to map.
    }
    List<Normalizer> buildNormalizers(DeterminingCriteria criteria) { 
      // create an empty list and get normalizers from 
      // cached map depending on criterias you need.   
    } 
  }
类工厂{
私有地图缓存规范化器;
公共工厂(){
//从主地图创建所有规格化器
//或在此硬编码并添加到地图。
}
列表生成器规范化程序(确定标准){
//创建一个空列表并从中获取规范化器
//缓存的地图取决于您需要的标准。
} 
}
3) 然后在主代码中,您只需对每一行迭代这些代码。迭代列表应该非常快,如下所示(伪代码):

List normalizers=factory.buildNormalizers(CurrentFileCriterias);
for(行中的字符串行){
字符串currentLine=line;
for(规格化器中的规格化器n){
currentLine=n.正常化(currentLine);
}
doSomethingWithFinished(当前行);
}

您在什么条件下决定需要哪个规范化器?收到的文件包含该信息。我不知道
List<Normalizer> normalizers = factory.buildNormalizers(currentFileCriteria);
for (String line in lines) {
  String currentLine = line;
  for (Normalizer n in normalizers) {
    currentLine = n.normalize(currentLine);
  }
  doSomethingWithFinished(currentLine);
}