我有以下代码(缩写为示例):
while (reader.ready()) {
String line = reader.readLine();
Matcher responseCodeMatcher = responseCodePattern.matcher(line);
if (responseCodeMatcher.matches()) {
responseCode = Integer.parseInt(responseCodeMatcher.group(1));
continue;
}
Matcher cacheControlMatcher = cacheControlPattern.matcher(line);
if (cacheControlMatcher.matches()) {
cacheControl = CacheControl.parseString(responseCodeMatcher.group(1));
continue;
}
...
}
模式都是类的静态最终成员。 所以我有一堆模式,我想找出每一行,如果它匹配其中一个,如果是这样 - 做一些事情(从模式到模式的变化)。你能想出一种以某种方式很好地重构它的方法吗?也许是我过去的模式集合(如果匹配,我怎么知道该怎么做?)或其他一些想法。
答案 0 :(得分:2)
因为到目前为止没有人回答,我会,虽然我不懂Java 在C#中,我将创建一个元组列表。元组的第1项是要检查的模式,第2项是一个匿名方法,它包含要执行的模式特定代码。在C#中,它看起来像这样:
var patterns = new List<Tuple<Pattern, Action<Matcher>>>();
patterns.Add(Tuple.Create(responseCodePattern, matcher =>
{
responseCode = Integer.parseInt(matcher.group(1));
}));
patterns.Add(Tuple.Create(cacheControlPattern, matcher =>
{
cacheControl = CacheControl.parseString(matcher.group(1));
}));
while (reader.ready()) {
String line = reader.readLine();
foreach(var tuple in patterns)
{
Matcher matcher = tuple.Item1.matcher(line);
if(matcher.matches())
{
tuple.Item2(matcher);
break;
}
}
}
我不知道,如果这对Java家伙有任何意义,尤其是lambda语法...请问,如果没有: - )
答案 1 :(得分:2)
我最终以下面的方式进行重构。我创建了一个班级HttpPatterns
:
package cs236369.proxy.types;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public enum HttpPatterns {
RESPONSE_CODE("^HTTP/1\\.1 (\\d+) .*$"),
CACHE_CONTROL("^Cache-Control: (\\w+)$"),
HOST("^Host: (\\w+)$"),
REQUEST_HEADER("(GET|POST) ([^\\s]+) ([^\\s]+)$"),
ACCEPT_ENCODING("^Accept-Encoding: .*$"),
CONTENT_ENCODING("^Content-Encoding: ([^\\s]+)$");
private final Pattern pattern;
HttpPatterns(String regex) {
pattern = Pattern.compile(regex);
}
public boolean matches(String expression) {
return pattern.matcher(expression).matches();
}
public Object process(String expression) {
Matcher matcher = pattern.matcher(expression);
if (!matcher.matches()) {
throw new RuntimeException("Called `process`, but the expression doesn't match. Call `matches` first.");
}
if (this == RESPONSE_CODE) {
return Integer.parseInt(matcher.group(1));
} else if (this == CACHE_CONTROL) {
return CacheControl.parseString(matcher.group(1));
} else if (this == HOST) {
return matcher.group(1);
} else if (this == REQUEST_HEADER) {
return new RequestHeader(RequestType.parseString(matcher.group(1)), matcher.group(2), matcher.group(3));
} else if (this == CONTENT_ENCODING) {
return ContentEncoding.parseString(matcher.group(1));
} else { //never happens
return null;
}
}
}
我这样使用它:
String line;
while ((line = reader.readLine()) != null) {
if (HttpPatterns.CACHE_CONTROL.matches(line)) {
cacheControl = (CacheControl) HttpPatterns.RESPONSE_CODE.process(line);
} else if (HttpPatterns.REQUEST_HEADER.matches(line)) {
requestHeader = (RequestHeader) HttpPatterns.REQUEST_HEADER.process(line);
} else if (HttpPatterns.HOST.matches(line)) {
requestHost = (String) HttpPatterns.HOST.process(line);
} else if (HttpPatterns.ACCEPT_ENCODING.matches(line)) {
continue;
} else if (line.isEmpty()) {
break;
}
fullRequest += "\r\n" + line;
}
我不喜欢我必须投出一切,但这是我迄今为止找到的最佳解决方案。
答案 2 :(得分:0)
好的,这是我的简短回答:这不是一个语言问题,到目前为止,这里的答案和评论都非常偏离基础。所有语言,无论多么具体,都包括类型。这是一个关于如何检测这些类型然后调用适当的相应操作的问题。答案是四人帮中的几种模式。
首先,对于解析部分,我建议您将其视为中介。动作应该对模式或文件一无所知,同样,动作的知识也不应该注入触发上下文。你可以将这个东西称为解析器,探测器等等,但该类的核心是将模式映射到适当的动作。
在动作方面,使用的模式当然是命令模式。使用命令时有很多可能性。如果你不需要上下文,那么命令非常简单,它只有一个执行方法。如果您需要传递一些将要改变的上下文,您可以模拟命令或动态创建新命令然后调用它们。