在java中类型安全解析

时间:2018-03-16 07:58:15

标签: java parsing design-patterns

我正在java中实现一个解析器。

我正在解析的数据有不同类型的记录。 让我们说这些是记录类型A,B,C,...... 这些记录有一些共同的属性。所以我在考虑接口记录所有记录A,B,C ..将实现。 文件中的数据如下:

A
B
B
C
C
C
...
X
Y
Z

我正在考虑拥有记录的迭代器。但它不是类型安全的。 因为我只能拥有

interface Record {
   String getRecordName();
   RecordType recordType();
}
class A implements Record {
    @Override
    String getRecordName() {...}
    // record type 'A' specific methods/fields here
}
class B implements Record{
    @Override
    String getRecordName() {...}
    // record type 'B' specific methods/fields..
}
class Parser implements Iterable<Record> {

    boolean hasNext() {...}
     // user has to examine record type and cast
    Record next() { ...} 
}

有什么方法可以解决这个问题吗?访客模式可以在这里有用吗?

编辑: 因为我在这里是一个记录流(不同类型),我仍然喜欢组合功能。像普通流一样(如map,filter,takeWhile等)

编辑: 在考虑了访客模式后,我想我得到了另一个想法。 Record接口将具有accept(Visitor)方法而next()将只返回Record(实际类型将是具体记录类型)。客户端将实现访问者并传递给接受方法。

interface Record {

  interface Visitor<R> {
      <R> visit(A a);
      <R> visit(B b);
  }
  // add accept method 
  <R> R accept(Visitor<R> v);
}
class A implements Record {
     @Override
     public <R> R accept(Visitor<R> v) {
          return v.visit(this);
     }
}

// client code; r could be A|B
 Record r = parser.next(); 
 String s = r.accept(new Visitor<String>() { ... });

1 个答案:

答案 0 :(得分:2)

是的:它被称为访客模式:

public interface RecordVisitor {
    void acceptA(A record);
    void acceptB(B record);
    ...
}

public class Parser {
    public void parse(Reader reader, RecordVisitor visitor) {
        ....
    }
}

...
parser.parse(reader, new RecordVisitor() {
    @Override
    void acceptA(A record) {
        ...
    }
    @Override
    void acceptB(B record) {
        ...
    }
    ...
});
...