我处于两难境地。我有一个接口Parser,实现它的类将解析具体的文件格式。例如 - CSVParser将解析CSV文件,XMLParser将解析XML文件等。
因此,接口Parser将是:
public interface Parser{
public SomeObject parseFile(String pathToFile);
}
另一方面,一些解析器将有额外的参数,例如,一个数组将告诉他们在文件中跳过哪些行。现在这让我感到困惑,我应该扩展Parser并添加方法,例如:
public interface BetterParser extends Parser{
public SomeObject parseFileConsideringParameter(String pathToFile, int[] whichLinesToSkip)
}
或者我应该聚合它们以便我的班级需要实现两者:
public class concreteParser implements Parser, BetterParser{
}
我想在pipline中有解析器不可知部分,你会说:
Parser parser = ParserFactory.giveMeParser(type);
SomeObject so = parser.parseFile(path);
问题是,在某些情况下,我没有参数告诉我要跳过哪一行。
我知道我只能用两个参数创建一个方法,所以一些实现会传递另一个参数,而其他参数会传递null,但这看起来很难看。
我真的想避免受到具体实施的约束,但我该如何克服这个问题呢?也许我错过了什么?
答案 0 :(得分:1)
这些接口的原因主要是服务提供商可以将接口绑定到其实现。如果所述实现具有“变体”,那么允许这种变化的一种方法是实现常规SomeObject parseFile(String pathToFile)
方法,该方法使用默认parseFileConsideringParameter()
参数调用whichLinesToSkip
来传递。然后,如果你需要告诉哪些行要跳过,你要检查解析器是instanceof
BetterParser,然后将解析器转换为BetterParser并使用该方法(但如下所述,instanceof
是很少解决方案)。
话虽如此,你的问题有两个部分:
对于1,这是个人偏好。两者都可以工作,但是扩展可能会显示BetterParser 是一个解析器,而不是依靠实现来传达它,只需实现两者。
对于2,我在上面提到过它。但是,大多数人说,如果您使用instanceof
,there's probably a better way。为此,您可以考虑让服务提供者使用两种方法,一种用于获取常规解析器,另一种用于获取SkippableParser(例如)。
答案 1 :(得分:1)
另一方面,一些解析器将有额外的参数,例如,一个数组将告诉他们在文件中跳过哪些行。现在这让我很困惑,我应该扩展Parser并添加方法,比如
interface Parser { public List<Token> parse(String pathToFile); } abstract class ParserDecorator implements Parser { protected Parser realParser; protected ParserDecorator(Parser rp) {} // delegates most of the methods to real parser... } class LineFilterParserDecorator extends ParserDecorator { private int[] linesToSkip; public LineFilterParserDecorator(Parser rp, int[] linesToSkip) { super(rp); this.linesToSkip = linesToSkip; } @override public List<Token> parse(Strint path) { List<Token> l = this.realParser.parse(path); // remove the skipped lines from the list return l; } } // Usage: Parser myParser = new LineFilterParserDecorator(new CSVParser(...), new int{10, 20,30}); // will skip lines 10, 20 and 30
不,请,不要。
您可以使用Decorator Pattern尝试一种方法。
{{1}}