Статьи

Полиморфные данные ввода / вывода

При разработке любого вида интерфейса кода, будь то элегантный объектно-ориентированный пакет или один из тех уродливых классов «Service», к которым мы так привыкли, очевидно, что он должен быть настолько расширяемым, насколько это возможно, и требовать как можно меньшего обслуживания , Это относится, конечно, к входным и выходным параметрам (возвращаемым типам), особенно если рассматриваемый код не может быть изменен его клиентами.

Вопрос в том, как мы можем иметь гибкие параметры, если они состоят из тупых моделей get / set? Каждый раз, когда требуется новое поле / атрибут, кто-то будет стучать в вашу дверь, чтобы обновить ваш интерфейс, потому что в противном случае он не сможет отправить или получить все необходимые данные.

Полиморфные данные

Возьмите приведенный ниже пример:

1
2
3
4
5
6
public interface People extends Iterable<Person> {
  Person fetch (int id);
  boolean insert (Person person);
 
  //...
}

Предположим, что наш Person — это класс get / set, имеющий firstName , lastName и id . Когда пользователю этого интерфейса потребуется получить или отправить больше атрибутов, которые он не сможет, он попросит вас сначала изменить модель Person а затем добавить логику в ваш код для обработки этих атрибутов.

Решением этой проблемы является Полиморфизм, один из наиболее распространенных принципов ООП — он сделает наши параметры «прозрачными» и более удобными в обслуживании. Предполагая, что наши данные представлены в формате JSON, я бы изменил интерфейс People :

1
2
3
4
5
public interface People extends Iterable<Person> {
  Person fetch (int id);
  boolean insert (JsonObject person);
  //...
}

Есть два больших изменения: Person на самом деле является интерфейсом, расширяющим javax.json.JsonObject и в то же время анимирующим некоторые части базового json или, может быть, все — таким образом, если People.fetch(...) изменяется и возвращает больший JsonObject , новые значения будут доступны автоматически через JsonObject.getString(...) , пока мы не добавим больше метода чтения в интерфейс Person .

Второе изменение — это ввод, который ожидает метод insert(...) . Теперь он требует необработанного JsonObject по той же причине: если инкапсулированный сервис решит ожидать больше значений, пользователь просто добавит их в JsonObject . Это может звучать как уродливое решение, так как они могут использовать его так:

1
2
3
4
5
6
7
8
People people = ...
people.insert(
  Json.createObjectBuilder()
      .add("id", 1)
      .add("firstName", "John")
      .add("lastName", "Doe")
      .build()
);

Вышесказанное довольно уродливо, создание JsonObject означает дублированную логику. Однако пользователь должен понимать, что он может реализовать интерфейс PersonInput extends JsonObject — вся эта логика построения будет в конструкторе реализации PersonInput , в то время как вызовы people.insert(...) будут выглядеть следующим образом:

1
2
3
4
People people = ...
people.insert(
  new PersonInput(1, "John", "Doe")
);

Относительно входного параметра JsonObject остается еще один вопрос: как клиент должен знать, какие значения предоставить? Это та часть, где JavaDocs вступает в игру: все это должно быть тщательно задокументировано в JavaDoc метода. Я думаю, вы можете назвать это хорошим компромиссом: пользователь должен немного изучить, прежде чем использовать ваш метод, но, с другой стороны, разделение очень удобно для вас обоих.

Точный подход, описанный выше, я использовал при разработке docker-java-api . Большинство методов, которые создают что-то на сервере, ожидают JsonObject качестве входных данных и возвращают интерфейсы, расширяющие JsonObject (см., Например, Containers.create (…) и Container ) — таким образом, если API Docker будет развиваться, требуя различных входов Json или верните разные Jsons, мне не обязательно менять какие-либо модели в ближайшее время.

PS Надеюсь, вы заметили, что ключевое слово в этой статье — «интерфейс». Это еще один пример того, почему интерфейсы являются очень важными инструментами, которые должен использовать любой объект.

Опубликовано на Java Code Geeks с разрешения MIhai Andronache, партнера нашей программы JCG. Смотрите оригинальную статью здесь: Полиморфные данные ввода / вывода

Мнения, высказанные участниками Java Code Geeks, являются их собственными.