Управляемые пространства имен

Краткое содержание

Введение

Управляемые пространства имен используются в Weave SDK, чтобы предоставить как разработчикам, так и интеграторам Weave SDK рекламируемое руководство и подтекст по назначению конкретных наборов API в SDK, чтобы они могли планировать и прогнозировать путь миграции между выпусками Weave SDK и, потенциально, управлять несколькими одновременными API-интерфейсами Weave для данного модуля.

Обозначение

Управляемые пространства имен могут управляться как одно из четырех обозначений:

Разработка

Любое пространство имен, управляемое с помощью обозначения «Разработка», указывает разработчикам и интеграторам на то, что содержащиеся в нем API находятся в стадии активной разработки, могут быть изменены и официально не поддерживаются. Интеграторам обычно не рекомендуется использовать эти API, если им это специально не предписано.

Следующий

Любое пространство имен, управляемое с помощью обозначения Next, указывает разработчикам и интеграторам на то, что содержащиеся в нем API, несмотря на то, что они в основном завершили активную разработку, все еще могут быть изменены и поддерживаются для целей ранней оценки. Назначенные таким образом API представляют собой следующий этап развития API Weave SDK и станут текущими API по умолчанию в цикле основных выпусков в ближайшем или ближайшем будущем.

Обратная совместимость, как с точки зрения API, так и с точки зрения беспроводного протокола, может существовать, но не гарантируется в API, обозначенных таким образом.

Обозначение управляемого пространства имен Next эффективно дает разработчикам и интеграторам представление о том, в каком направлении движется Weave SDK, намекая, какой API станет текущим по умолчанию в будущем выпуске.

Обозначение Следующее управляемое пространство имен является необязательным, так что управляемое пространство имен может переходить через жизненный цикл без его использования (см. Жизненный цикл управляемого пространства имен ).

Текущий

Любое пространство имен, управляемое с текущим обозначением, или любое неуправляемое пространство имен (т. е. не имеющее обозначения управляемого пространства имен) представляет собой текущий официально поддерживаемый API по умолчанию для этой части или модуля Weave SDK. Хотя такие API-интерфейсы все еще могут быть усовершенствованы, изменения в основном будут постепенными, и следует поддерживать обратную совместимость, как API, так и по беспроводной сети.

Обозначение текущего управляемого пространства имен является необязательным, так что управляемое пространство имен может проходить через жизненный цикл без его использования (см. Жизненный цикл управляемого пространства имен ). Фактически любое неуправляемое пространство имен неявно является текущим.

Наследие

Любое пространство имен, управляемое с помощью обозначения Legacy, является для разработчиков и интеграторов показателем того, что содержащиеся в нем API устарели и заменены новым, текущим API. Эти API представляют собой то, что раньше было текущим API.

Обозначенные таким образом API полностью исчезнут в следующем крупном выпуске Weave SDK; следовательно, разработчикам и интеграторам следует разработать планы перехода от этих API, если они намерены оставаться на переднем крае выпусков Weave SDK.

Жизненный цикл управляемого пространства имен

На следующем рисунке показан жизненный цикл управляемого пространства имен при его переходе от разработки и, возможно, к устаревшей версии:

.-------------.      .- - - .      .- - - - -.      .--------.
| Development | -.->   Next   -.->   Current   ---> | Legacy |
'-------------'  |   '- - - '  |   ' - - - - '      '--------'
                 |             |
                 '-------------'

Если он используется, жизненный цикл управляемого пространства имен начинается с обозначения «Разработка».

Когда разработка завершена и код готов к оценке и интеграции, обозначение меняется на «Следующий» или «Текущий». Альтернативно, обозначение можно вообще удалить и управляемое пространство имен больше не использовать, что фактически делает обозначение неявно текущим.

Если код должен жить рядом с текущим кодом, а не заменять его, то обозначение должно перейти на Next. Если код должен заменить текущий код, то обозначение должно перейти на текущий.

При использовании обозначения Next после того, как код прошел желаемое количество циклов выпуска и оценки, обозначение мигрирует в Current или, опять же, Обозначение может быть вообще отброшено.

При использовании текущего обозначения, если код должен быть заменен новым кодом, но его все еще необходимо поддерживать в течение нескольких циклов выпуска, обозначение переходит в устаревшее.

Судя по обозначению Legacy, код в конечном итоге вообще удаляется из Weave SDK.

Использование управляемых пространств имен

Пользователи Weave SDK могут взаимодействовать с управляемыми пространствами имен либо в качестве разработчика , расширяя и поддерживая существующий код, либо в качестве интегратора , интегрируя Weave в собственное приложение, платформу и системный код. В следующих двух разделах подробно описаны рекомендации по работе с пространствами имен, управляемыми Weave, с этих двух точек зрения.

Использование управляемых пространств имен разработчиком

Ключевым направлением деятельности разработчика Weave SDK является улучшение и разработка новых API и функций Weave SDK, при этом во многих случаях в то же время поддерживается существующее развертывание API и функций.

Там, где невозможно удовлетворить обе эти основные области с помощью обратной совместимости в рамках одного и того же API, управляемые пространства имен предоставляют механизм для параллельного управления этими API таким образом, чтобы не нарушать существующие развертывания API и функций.

В качестве рабочего примера предположим, что профиль Weave, Mercury, который в настоящее время существует в следующей неуправляемой иерархии пространства имен:

namespace nl {
namespace Weave {
namespace Profiles {
namespace Mercury {

// ...

}; // namespace Mercury
}; // namespace Profiles
}; // namespace Weave
}; // namespace nl

и следующие общедоступные заголовки:

  • Weave/Профили/Mercury/Mercury.hpp
  • Weave/Профили/Mercury/Bar.hpp
  • Weave/Профили/Mercury/Foo.hpp
  • Weave/Профили/Mercury/Foobar.hpp

где Mercury.hpp — это заголовок «зонтика» модуля. Большинство интеграторов просто включают заголовок «зонтика» модуля, как показано:

#include 

Однако в настоящее время разработка Mercury достигла точки, когда возникла необходимость в разработке API-интерфейсов следующего поколения и, возможно, протокола беспроводной связи, которые не имеют обратной совместимости с существующими развертываниями. Использование управляемых пространств имен может помочь добиться этого, не нарушая существующие развертывания.

Переместить существующее пространство имен в текущее

Чтобы продолжить поддержку текущей версии API и функциональности существующих развернутых интеграций, первой задачей является перемещение текущего кода:

% cd src/lib/profiles/mercury
% mkdir Current
% mv Mercury.hpp Bar.hpp Foo.hpp Foobar.hpp *.cpp Current/

Обратите внимание: в дополнение к перемещению файлов следует также переименовать заголовки, включающие защиту для перемещенных файлов, потенциально украшая их «_CURRENT», поскольку новые файлы с одинаковыми именами будут созданы на их месте ниже.

После перемещения кода следующим шагом будет управление пространством имен с соответствующим обозначением, здесь «Текущее». Сначала создайте заголовок, определяющий управляемое пространство имен, например «Current/MercuryManagedNamespace.hpp». Создание такого заголовка предпочтительнее, чем повторение и дублирование этого содержимого в каждом файле заголовка, если файлов заголовков несколько.

% cat << EOF > Current/MercuryManagedNamespace.hpp
#ifndef _WEAVE_MERCURY_MANAGEDNAMESPACE_CURRENT_HPP
#define _WEAVE_MERCURY_MANAGEDNAMESPACE_CURRENT_HPP

#include <Weave/Support/ManagedNamespace.hpp>

#if defined(WEAVE_CONFIG_MERCURY_NAMESPACE) && WEAVE_CONFIG_MERCURY_NAMESPACE != kWeaveManagedNamespace_Current
#error Compiling Weave Mercury current-designation managed namespace file with WEAVE_CONFIG_MERCURY_NAMESPACE defined != kWeaveManagedNamespace_Current
#endif

#ifndef WEAVE_CONFIG_MERCURY_NAMESPACE
#define WEAVE_CONFIG_MERCURY_NAMESPACE kWeaveManagedNamespace_Current
#endif

namespace nl {
namespace Weave {
namespace Profiles {

namespace WeaveMakeManagedNamespaceIdentifier(Mercury, kWeaveManagedNamespaceDesignation_Current) { };

namespace Mercury = WeaveMakeManagedNamespaceIdentifier(Mercury, kWeaveManagedNamespaceDesignation_Current);

}; // namespace Profiles
}; // namespace Weave
}; // namespace nl

#endif // _WEAVE_MERCURY_MANAGEDNAMESPACE_CURRENT_HPP
EOF

Затем включите этот заголовок перед другими директивами включения, специфичными для модуля, в существующие заголовки. Например:

#include 

#include 

Создание заголовков совместимости

Однако перемещения существующих заголовков в новое место и управления их пространством имен недостаточно, чтобы гарантировать, что существующие развертывания будут работать без изменений, поскольку все они используют директивы include, которые указывают заголовки, только что перемещенные выше.

Чтобы решить эту проблему, необходимо создать заголовки оболочки совместимости с именами, соответствующими только что перемещенным.

% touch Mercury.hpp Bar.hpp Foo.hpp Foobar.hpp

Если создается только управляемое пространство имен, назначенное Current, без создания для него управляемого пространства имен, назначенного Development или Next, содержимое этих файлов может просто состоять из заголовка include Guard и директивы include, определяющей недавно перемещенный заголовок то же имя:

#ifndef _WEAVE_MERCURY_BAR_HPP
#define _WEAVE_MERCURY_BAR_HPP

#include 

#endif // _WEAVE_MERCURY_BAR_HPP

Однако если создается управляемое пространство имен, назначенное «Разработка» или «Далее», для размещения новой, несовместимой разработки, необходимо сделать что-то немного более сложное.

Как и раньше, создается заголовок для конфигурации управляемого пространства имен, здесь как MercuryManagedNamespace.hpp. Опять же, это предпочтительнее, чем повторение и дублирование этого содержимого в каждом файле заголовка, если файлов заголовков несколько.

% cat << EOF > MercuryManagedNamespace.hpp
#ifndef _WEAVE_MERCURY_MANAGEDNAMESPACE_HPP
#define _WEAVE_MERCURY_MANAGEDNAMESPACE_HPP

#include <Weave/Support/ManagedNamespace.hpp>

#if defined(WEAVE_CONFIG_MERCURY_NAMESPACE)                             \
  && (WEAVE_CONFIG_MERCURY_NAMESPACE != kWeaveManagedNamespace_Current) \
  && (WEAVE_CONFIG_MERCURY_NAMESPACE != kWeaveManagedNamespace_Development)
#error "WEAVE_CONFIG_MERCURY_NAMESPACE defined, but not as namespace kWeaveManagedNamespace_Current or kWeaveManagedNamespace_Development"
#endif

#if !defined(WEAVE_CONFIG_MERCURY_NAMESPACE)
#define WEAVE_CONFIG_MERCURY_NAMESPACE kWeaveManagedNamespace_Current
#endif

#endif // _WEAVE_MERCURY_MANAGEDNAMESPACE_HPP
EOF

Обратите внимание, что при этом по умолчанию для управляемого пространства имен по умолчанию устанавливается значение «Текущее», если конфигурация не была определена.

При наличии этого заголовка заголовки оболочки совместимости теперь можно редактировать, чтобы они содержали:

#include 

#if WEAVE_CONFIG_MERCURY_NAMESPACE == kWeaveManagedNamespace_Development
#include 
#else
#include 
#endif // WEAVE_CONFIG_MERCURY_NAMESPACE == kWeaveManagedNamespace_Development

или что-то еще, подходящее для рассматриваемого варианта использования управления пространством имен.

Создание контента для разработки

На данный момент инфраструктура готова, чтобы начать создавать новые функциональные возможности и API наряду с существующими.

% mkdir Development
% touch Development/Mercury.hpp Development/Bar.hpp Development/Foo.hpp Development/Foobar.hpp
% cat << EOF > Development/MercuryManagedNamespace.hpp
#ifndef _WEAVE_MERCURY_MANAGEDNAMESPACE_DEVELOPMENT_HPP
#define _WEAVE_MERCURY_MANAGEDNAMESPACE_DEVELOPMENT_HPP

#include <Weave/Support/ManagedNamespace.hpp>

#if defined(WEAVE_CONFIG_MERCURY_NAMESPACE) && WEAVE_CONFIG_MERCURY_NAMESPACE != kWeaveManagedNamespace_Development
#error Compiling Weave Mercury development-designated managed namespace file with WEAVE_CONFIG_MERCURY_NAMESPACE defined != kWeaveManagedNamespace_Development
#endif

#ifndef WEAVE_CONFIG_MERCURY_NAMESPACE
#define WEAVE_CONFIG_MERCURY_NAMESPACE kWeaveManagedNamespace_Development
#endif

namespace nl {
namespace Weave {
namespace Profiles {

namespace WeaveMakeManagedNamespaceIdentifier(Mercury, kWeaveManagedNamespaceDesignation_Development) { };

namespace Mercury = WeaveMakeManagedNamespaceIdentifier(Mercury, kWeaveManagedNamespaceDesignation_Development);

}; // namespace Profiles
}; // namespace Weave
}; // namespace nl

#endif // _WEAVE_MERCURY_MANAGEDNAMESPACE_DEVELOPMENT_HPP
EOF

Конечно, если модуль намного проще, чем представленный здесь пример, и не имеет большого количества классов, исходных файлов или заголовков, все это можно выполнить в одном заголовочном файле без перемещения файлов и создания нескольких автономных заголовков конфигурации и совместимости. . Однако этот сложный пример должен вдохновить на создание управляемых пространств имен в диапазоне от сложного к простому.

Использование управляемых пространств имен в качестве интегратора

Ключевой задачей интегратора Weave SDK является включение соответствующих заголовков общедоступного API Weave SDK, а также интеграция и разработка приложений на их основе.

В качестве рабочего примера снова предположим, что профиль Weave, Mercury, имеет управляемые пространства имен Next, Current и Legacy, чьи общедоступные заголовки структурированы следующим образом:

  • Weave/Профили/Mercury/Mercury.hpp
  • Weave/Профили/Меркурий/Bar.hpp
  • Weave/Профили/Mercury/Foo.hpp
  • Weave/Профили/Mercury/Foobar.hpp
  • Weave/Профили/Mercury/Next/Mercury.hpp
  • Weave/Профили/Mercury/Next/Bar.hpp
  • Weave/Профили/Mercury/Next/Foo.hpp
  • Weave/Профили/Mercury/Далее/Foobar.hpp
  • Weave/Профили/Mercury/Current/Mercury.hpp
  • Weave/Профили/Меркурий/Текущий/Bar.hpp
  • Weave/Профили/Меркурий/Текущий/Foo.hpp
  • Weave/Профили/Mercury/Current/Foobar.hpp
  • Weave/Профили/Mercury/Legacy/Mercury.hpp
  • Weave/Профили/Mercury/Legacy/Bar.hpp
  • Weave/Профили/Mercury/Legacy/Foo.hpp
  • Weave/Профили/Mercury/Legacy/Foobar.hpp

где Mercury.hpp — это заголовок «зонтика» модуля.

Если только рассматриваемый вариант использования не требует явного включения модуля, управляемого пространством имен, в Weave, например:

#include 

Лучше всего ссылаться на общедоступные заголовки модулей Weave по их неуправляемым путям по умолчанию (например, Weave/Profiles/Mercury/Mercury.hpp). Это позволяет отслеживать ход разработки API без постоянного изменения директив включения проекта по мере прохождения этих API через управляемый жизненный цикл .

Следуя этой стратегии, развертывания могут затем перенаправить свой код на другое обозначение управляемого пространства имен, например, текущее обозначение, указав желаемую конфигурацию в препроцессоре C/C++. Это можно сделать в командной строке, в исходном коде или в заголовке конфигурации или префикса:

#define WEAVE_CONFIG_MERCURY_NAMESPACE kWeaveManagedNamespace_Current

и используйте неуправляемый/неквалифицированный путь включения:

#include 

Когда и если обозначение управляемого пространства имен изменится для целевых API, например с текущего на устаревшее, просто переназначьте его, изменив определение препроцессора:

#define WEAVE_CONFIG_MERCURY_NAMESPACE kWeaveManagedNamespace_Legacy