Шаблон проектирования для хранения данных из разных источников в одном объекте - PullRequest
0 голосов
/ 12 марта 2019

Я работаю над проектом блокчейна (Hyperledger Indy), чтобы хранить в цепочке поддающиеся проверке заявления ( более подробно ) о стенограммах и т. Д.У меня есть разные поставщики данных об учениках, и все они используют свой собственный формат для данных, в которых они передают их мне.Я лично думал о каком-то шаблоне адаптера, но хотел бы услышать другие мнения об этой ситуации.В приведенном ниже примере я попытаюсь прояснить ситуацию и показать, например, два разных формата.

Цель состоит в том, чтобы сохранить эти ответы в одном объекте, чтобы иметь возможность сохранить его в цепочке

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


<students>
    <student>
        <name>
        xxx
    </name>
        <age>
        17
    </age>
    </student>
</students>

1 Ответ

1 голос
/ 12 марта 2019

Один из вариантов - создать класс, который выбирает соответствующий синтаксический анализатор в зависимости от формата данных. Например, предположим, что есть два формата, в которых могут отображаться данные об ученике: (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 выбирается в зависимости от того, какой формат обнаружен. Я не уверен, существует ли официальное название для такого шаблона, но я слышал, что раньше его называли Switchboard .


Дополнительно

Если вы хотите, чтобы 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 вместо их ручной регистрации.

...