设计模式以将来自不同源的数据存储在一个对象中

问题描述 投票:0回答:1

我正在开发一个区块链(hyperledger indy)项目,用于存储关于链中转录本等的可验证声明(more detail)。我有不同的学生数据提供者,他们都使用自己的格式来提供给我的数据。我个人想过某种适配器模式但想听听有关这种情况的其他意见。在下面的示例中,我尝试将情况清楚并显示,例如,两种不同的格式。

目标是将这些响应存储到一个对象中,以便能够将其保存在链中

{
  "student": "xxx",
  "grades": {
    "english": 9,
  }
}


<students>
    <student>
        <name>
        xxx
    </name>
        <age>
        17
    </age>
    </student>
</students>
design-patterns format adapter blockchain
1个回答
1
投票

一种选择是创建一个类,该类根据数据的格式选择适当的解析器。例如,假设有两种格式可以显示学生数据:(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对象列表,并选择一个可用于解析数据的对象。例如(StudentUnknownStudentFormatException与前面的示例相同,并且已被省略):

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实现,而不是手动注册它们。

© www.soinside.com 2019 - 2024. All rights reserved.