避免代码重复

发布于 2024-10-31 02:32:20 字数 512 浏览 6 评论 0原文

考虑以下代码:

if (matcher1.find()) {
   String str = line.substring(matcher1.start()+7,matcher1.end()-1);
   /*+7 and -1 indicate the prefix and suffix of the matcher... */    
   method1(str);
}
if (matcher2.find()) {
   String str = line.substring(matcher2.start()+8,matcher2.end()-1);
   method2(str);
}
...

我有 n 个匹配器,所有匹配器都是独立的(如果一个匹配器为真,则它对其他匹配器一无所知......),对于每个为真的匹配器 - 我对它匹配的内容调用不同的方法。
问题:我不喜欢这里的代码重复和“幻数”,但我想知道是否有更好的方法来做到这一点......? (也许是访客模式?)有什么建议吗?

consider the following code:

if (matcher1.find()) {
   String str = line.substring(matcher1.start()+7,matcher1.end()-1);
   /*+7 and -1 indicate the prefix and suffix of the matcher... */    
   method1(str);
}
if (matcher2.find()) {
   String str = line.substring(matcher2.start()+8,matcher2.end()-1);
   method2(str);
}
...

I have n matchers, all matchers are independent (if one is true, it says nothing about the others...), for each matcher which is true - I am invoking a different method on the content it matched.

question: I do not like the code duplication nor the "magic numbers" in here, but I'm wondering if there is better way to do it...? (maybe Visitor Pattern?) any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

神仙妹妹 2024-11-07 02:32:20

创建一个抽象类,并在子类中添加偏移量(也可以进行字符串处理......根据您的要求)。

然后将它们填充到列表中并处理该列表。

这是一个示例抽象处理器:

public abstract class AbsractProcessor {

    public void find(Pattern pattern, String line) {
        Matcher matcher = p.matcher(line);
        if (matcher.find()) {
            process(line.substring(matcher.start() + getStartOffset(), matcher.end() - getEndOffset()));
        }
    }

    protected abstract int getStartOffset();

    protected abstract int getEndOffset();

    protected abstract void process(String str);

}

Create an abstract class, and add offset in subclass (with string processing too... depending of your requirement).

Then populate them in a list and process the list.

Here is a sample absract processor:

public abstract class AbsractProcessor {

    public void find(Pattern pattern, String line) {
        Matcher matcher = p.matcher(line);
        if (matcher.find()) {
            process(line.substring(matcher.start() + getStartOffset(), matcher.end() - getEndOffset()));
        }
    }

    protected abstract int getStartOffset();

    protected abstract int getEndOffset();

    protected abstract void process(String str);

}
撩动你心 2024-11-07 02:32:20

只需使用捕获组标记要传递给方法的正则表达式部分。

例如,如果您的正则表达式是 foo.*bar 并且您对 foobar 不感兴趣,请将正则表达式设置为 foo(. *)栏。然后始终从 Matcher 中获取组 1。

然后,您的代码将如下所示:

method1(matcher1.group(1));
method2(matcher2.group(2));
...

进一步的一步是将您的方法替换为实现如下所示的类:

public interface MatchingMethod {
  String getRegex();
  void apply(String result);
}

然后您可以轻松地自动化该任务:

for (MatchingMethod mm : getAllMatchingMethods()) {
  Pattern p = Pattern.compile(mm.getRegex());
  Matcher m = p.matcher(input);
  while (m.find()) {
    mm.apply(m.group(1));
}

请注意,如果性能很重要,则预编译模式 可以提高运行时间。

Simple mark the part of the regex that you want to pass to the method with a capturing group.

For example if your regex is foo.*bar and you are not interested in foo or bar, make the regex foo(.*)bar. Then always grab the group 1 from the Matcher.

Your code would then look like this:

method1(matcher1.group(1));
method2(matcher2.group(2));
...

One further step would be to replace your methods with classes implementing an like this:

public interface MatchingMethod {
  String getRegex();
  void apply(String result);
}

Then you can easily automate the task:

for (MatchingMethod mm : getAllMatchingMethods()) {
  Pattern p = Pattern.compile(mm.getRegex());
  Matcher m = p.matcher(input);
  while (m.find()) {
    mm.apply(m.group(1));
}

Note that if performance is important, then pre-compiling the Pattern can improve runtime if you apply this to many inputs.

給妳壹絲溫柔 2024-11-07 02:32:20

你可以把它缩短一点,但我的问题是,这真的值得付出努力吗:

private String getStringFromMatcher(Matcher matcher, int magicNumber) {
   return line.subString(matcher.start() + magicNumber, matcher.end() - 1 )
}

if (matcher1.find()) {
method1(getStringFromMatcher(matcher1, 7);
}

if (matcher2.find()) {
method2.(getStringFromMatcher(mather2, 8);
}

You could make it a little bit shorter, but I the question is, is this really worth the effort:

private String getStringFromMatcher(Matcher matcher, int magicNumber) {
   return line.subString(matcher.start() + magicNumber, matcher.end() - 1 )
}

if (matcher1.find()) {
method1(getStringFromMatcher(matcher1, 7);
}

if (matcher2.find()) {
method2.(getStringFromMatcher(mather2, 8);
}
你是暖光i 2024-11-07 02:32:20

将 Cochard 的解决方案与工厂(switch 语句)与所有 methodX 方法结合使用。所以你可以这样称呼它:

Factory.CallMethodX(myEnum.MethodX, str)

你可以在 Cochard 解决方案的填充步骤中分配 myEnum.MethodX

use Cochard's solution combined with a factory (switch statement) with all the methodX methods. so you can call it like this:

Factory.CallMethodX(myEnum.MethodX, str)

you can assign the myEnum.MethodX in the population step of Cochard's solution

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文