我正在开发一个区块链(hyperledger indy)项目,用于存储关于链中转录本等的可验证声明(more detail)。我有不同的学生数据提供者,他们都使用自己的格式来提供给我的数据。我个人想过某种适配器模式但想听听有关这种情况的其他意见。在下面的示例中,我尝试将情况清楚并显示,例如,两种不同的格式。
目标是将这些响应存储到一个对象中,以便能够将其保存在链中
{
"student": "xxx",
"grades": {
"english": 9,
}
}
<students>
<student>
<name>
xxx
</name>
<age>
17
</age>
</student>
</students>
一种选择是创建一个类,该类根据数据的格式选择适当的解析器。例如,假设有两种格式可以显示学生数据:(1)JSON和(2)XML:
public class Student {
// ...
}
public interface StudentParser {
public Student parse(String data);
}
public class JsonStudentParser {
@Override
public Student parse(String data) {
// ...
}
}
public class XmlStudentParser {
@Override
public Student parse(String data) {
// ...
}
}
public class StudentDeserializer {
private final StudentParser jsonParser = new JsonStudentParser();
private final StudentParser xmlParser = new XmlStudentParser();
public Student deserialize(String data) {
if (isJson(data)) {
return jsonParser.parse(data);
}
else if (isXml(data)) {
return xmlParser.parse(data);
}
else {
throw new UnknownStudentFormatException();
}
}
}
public class UnknownStudentFormatException extends RuntimeException {
// ...
}
我已经决定区分JSON和XML数据,但结构是上面的重要部分。对于系统中可用的每种格式都有一个StudentParser
,并根据发现的格式选择正确的StudentParser
。我不确定这样的模式是否有正式名称,但我之前听说它被称为交换机。
更先进
如果你想让StudentDeserializer
更通用(不仅仅依赖于JSON和XML),你可以移动逻辑来决定StudentParser
实现可以处理的格式从StudentDeserializer
到实现本身。然后,StudentDeserializer
可以包含已注册的StudentParser
对象列表,并选择一个可用于解析数据的对象。例如(Student
和UnknownStudentFormatException
与前面的示例相同,并且已被省略):
public interface StudentParser {
public Student parse(String data);
public boolean canHandle(String data);
}
public class JsonStudentParser {
@Override
public Student parse(String data) {
// ...
}
@Override
public boolean canHandle(String data) {
// ... is JSON? ...
}
}
public class XmlStudentParser {
@Override
public Student parse(String data) {
// ...
}
@Override
public boolean canHandle(String data) {
// ... is XML? ...
}
}
public class StudentDeserializer {
private final List<StudentParser> parsers = new ArrayList<>();
public void registerParser(StudentParser parser) {
parsers.add(parser);
}
public Student deserialize(String data) {
return parsers.stream()
.filter(parser -> parser.canHandle(data))
.findFirst()
.orElseThrow(() -> new UnknownStudentFormatException())
.parse(data);
}
}
然后可以注册StudentParser
实现:
JsonStudentParser jsonParser = new JsonStudentParser();
XmlStudentParser xmlParser = new XmlStudentParser();
StudentDeserializer deserializer = new StudentDeserializer();
deserializer.registerParser(jsonParser);
deserializer.registerParser(xmlParser);
deserializer.deserialize(someData);
如果您有某种依赖注入(DI)框架,则可以自动装配StudentParser
实现,而不是手动注册它们。