Итак, позвольте мне предложить другую точку зрения. Описание проблемы кажется достаточно простым - у меня есть два вызова API, один из которых возвращает частичный объект, а другой - полный объект. Я не хочу делать два звонка, если мне не нужно. Итак, я просто сделаю второй звонок и "заполню детали", если понадобится, верно?
Неправильно.
Предлагаемый подход не очень хорошая идея.
Это сходит с рельсов с самого начала с дизайном API. Объекты, возвращаемые API, не должны быть настолько сложными, чтобы требовать множественных вызовов для возврата «полного» объекта, как описано в коде. Но давайте предположим, что у меня нет контроля над дизайном API - что мне делать?
Программисты часто сталкиваются с проблемой противодействия плохо спроектированному API. Они создают негерметичные абстракции , подобные описанной в этой задаче, где существует сильное желание "замаскировать" плохой дизайн API. Проблема в том, что не все плохие проекты могут быть скрыты. Это один
Здесь предлагается ввести болезненный побочный эффект средства доступа get
. Возможно, это худший способ решения проблемы плохого проектирования API. Типичный метод get
возвращается с незначительным количеством времени - это простой доступ к памяти. Предполагаемый метод доступа get
может потенциально занять несколько секунд, чтобы вернуться, он может потерпеть неудачу, он может вызвать исключение. Хуже всего то, что нет никаких указаний вызывающей стороне, что на самом деле это доступ к внешнему интерфейсу. В конце концов, состояние вашего объекта не является детерминированным, что, вероятно, худшее что вы можете иметь в программе.
Если это было не так уж и плохо, в аксессорах get
не предусмотрено асинхронных операций, которые часто встречаются при работе с удаленными API. Пользовательский опыт пострадает. Используя этот подход, я на самом деле рассмотрю одну проблему и создаю новую проблему везде, где используется этот класс.
Лучший подход:
API имеет две отдельные функции, поэтому на самом деле это подразумевает два отдельных типа результатов. Я бы создал один тип для частичного класса и второй тип для полного класса. В конце концов, я пишу код - и если код не имеет привычки переписывать сам себя, во время написания я должен знать, нужно ли мне полное или частичное представление объекта.
Чтобы получить полное представление, я предоставлю отдельный доступ к API с соответствующими методами, обеспечивающими асинхронное выполнение (например, наблюдаемые). Это будет иметь дополнительное преимущество, позволяя мне исследовать (с помощью функции «где используется»), где в программе используются эти различные вызовы API. Это может послужить основанием для того, чтобы я вернулся к конструктору API и предложил изменить дизайн в зависимости от того, как я его использую.