代管命名空間

摘要

簡介

Weave SDK 使用代管命名空間,為 Weave SDK 開發人員和整合商提供宣傳指引和次要文字,說明 SDK 中特定 API 集的設計,以便規劃和預測在所有 Weave SDK 版本中的遷移路徑,甚至還能針對特定模組管理多個並行 Weave API。

稱號

代管命名空間可能會以下列任一種身分管理:

開發

凡是透過「開發」標示管理的命名空間,都代表開發人員和整合商會指示內含的 API 仍在開發階段,因此可能隨時變動,而且並不正式支援。除非整合商另有明確指示,否則供應商通常不建議使用這些 API。

繼續

任何透過「下一個」標示管理的命名空間,都代表開發人員和整合商認為其中的 API 大部分仍在積極開發階段,可能還是可能會有變動,且可支援初期評估用途。指定的 API 代表 Weave SDK API 中的未來發展領域,且會在不久後立即成為當前的主要 API,並成為當前的主要 API。

從 API 和無線通訊協定的角度來看,可能存在回溯相容性,但不保證在指定的 API 中。

下一個代管命名空間標示功能可為開發人員和整合商提供檢視畫面,提示 Weave SDK 的主要位置,提示將在日後版本中成為目前預設的預設 API。

「下一個代管命名空間」為選用功能,當代管命名空間在不使用生命週期的情況下,可能會在生命週期內轉換 (請參閱代管命名空間生命週期)。

目前

任何以目前指定名稱或任何非受管命名空間 (例如缺少代管命名空間指定) 管理的命名空間,都代表 Weave SDK 中該部分或模組目前支援的最新預設 API。雖然這些 API 可能仍在改良中,但變動內容主要分為遞增和回溯相容性,但 API 和無線更新都應持續維護。

目前的代管命名空間為選用項目,讓代管命名空間在不使用生命週期的情況下轉換生命週期 (請參閱代管命名空間生命週期)。事實上,所有非受管命名空間都是隱含的「Current」。

舊版

凡是使用舊版標示管理的命名空間,都代表開發人員和整合商知道其中所含的 API 已淘汰,並以最新的 API 取代。這些 API 代表先前使用的 API。

指定的 API 將在下一次的 Weave SDK 重大版本中完全消失;因此,如果開發人員和整合商計劃要採用 Weave SDK 最先進的平台,應制定遷移這些 API 的計畫。

代管命名空間生命週期

下圖說明代管命名空間從「開發」轉換,且可能轉換至舊版時的生命週期:

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

如果採用這種方式,代管命名空間生命週期會從「開發」名稱開始計算。

一旦開發完成,且程式碼已可進行評估和整合,標示就會遷移至「下一個」或「現行」兩個版本。或者,標示也可以完全捨棄,不再使用代管命名空間,而有效率地指定目前為「 Current」。

如果程式碼仍與現有程式碼一同運作,但尚未取代目前的程式碼,則應將標示遷移至「Next」。如果程式碼是取代目前的程式碼,則應將標示遷移至 Current。

使用「下一個」標示後,當程式碼達到所需的發布版本和評估週期後,標示就會遷移至目前版本,也可能完全捨棄標示。

使用目前指定時,如果程式碼希望取代新程式碼,但仍需長時間執行多個發布週期,標示會遷移至舊版。

從舊版指定,程式碼最終會完全從 Weave SDK 中移除。

使用代管命名空間

Weave SDK 使用者可以透過開發人員、擴充及維護現有程式碼,或以整合商的方式將 Weave 整合至自己的應用程式、平台和系統程式碼中。以下兩個部分詳細說明瞭如何處理 Weave 代管命名空間的建議。

以開發人員的身分使用代管命名空間

強化及開發新的 Weave SDK API 和功能,是 Weave SDK 開發人員的一大重點,同時在許多情況下,他們會同時支援現有的 API 和功能部署。

無法在相同的 API 中以回溯相容的方式同時滿足這兩個重點領域,但代管命名空間提供一種機制,可用來平行管理這些 API,而不會中斷現有的 API 和功能部署作業。

做為實際範例,假設 Mercury 目前存在下列非受管命名空間階層:

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

// ...

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

和下列公開標頭:

  • Weave/Profiles/Mercury/Mercury.hpp
  • Weave/Profiles/Mercury/Bar.hpp
  • Weave/Profiles/Mercury/Foo.hpp
  • Weave/Profiles/Mercury/Foobar.hpp

其中的 Mercury.hpp 是「umbrella」模組標頭。大部分的整合商只會包含「umbrella」模組標頭,如下所示:

#include 

不過,Mercury 的開發團隊現在已面臨到需要開發新一代 API 的需求,甚至可能透過 Wi-Fi 通訊協定,與現有部署作業無法回溯相容。使用代管命名空間有助於完成這項工作,而不會影響現有的部署作業。

將現有命名空間移至當前命名空間

為了讓目前部署的整合作業繼續支援目前的 API 版本和功能,第一項工作是移動目前的程式碼:

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

請注意,除了移動檔案之外,移動檔案的標頭也會包含保護設定,並可能以「_CURRENT」來裝飾這些檔案,因為類似名稱的新檔案會在下方建立。

移動程式碼後,下一步就是使用適當名稱來管理命名空間,此處「目前」部分。首先,請建立定義代管命名空間的標頭,例如「Current/MercuryManaged 命名空間.hpp」。當有多個標頭檔案時,建立這類標頭比在各標頭檔案中重複或複製此內容更是比較好的做法。

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

#include 

#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 

建立相容性標頭

然而,將現有標頭移至新位置並單獨管理命名空間,不足以確保現有的部署作業不會變更,因為全都使用指定上述標頭的 include 指令。

如要解決這個問題,您必須建立與剛才移動項目名稱相符的相容性包裝函式標頭。

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

如果正在建立目前指定的代管命名空間,而不建立附帶的「開發」或「下一個」指定的代管命名空間,則這類檔案的內容只需包含標頭,以及指定相同名稱的新移動標頭的 include 指令:

#ifndef _WEAVE_MERCURY_BAR_HPP
#define _WEAVE_MERCURY_BAR_HPP

#include 

#endif // _WEAVE_MERCURY_BAR_HPP

不過,如果建立的是「開發」或「下一代」的代管命名空間,以便配合全新且不相容的開發作業,就需要進行較複雜的操作。

和先前一樣,會建立代管命名空間設定的標頭,此處是 MercuryManaged 命名空間.hpp。再次強調,當有多個標頭檔案時,在各標頭檔案中重複和複製此內容也是較理想的做法。

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

#include 

#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

請注意,如果尚未定義任何設定,則代管命名空間的標示會預設為「Current」。

設定這個標頭後,您現在可以編輯相容性包裝函式標頭,加入以下內容:

#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 

#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 整合商的一大重點,包括適用的 Weave SDK 公用 API 標頭,以及針對這些標頭整合及開發應用程式。

再假設一個實際範例,假設您有一個 Weave 設定檔 Mercury,其中包含 Next-、 Current 和舊版指定的代管命名空間,其公開標頭結構如下:

  • Weave/Profiles/Mercury/Mercury.hpp
  • Weave/Profiles/Mercury/Bar.hpp
  • Weave/Profiles/Mercury/Foo.hpp
  • Weave/Profiles/Mercury/Foobar.hpp
  • Weave/Profiles/Mercury/Next/Mercury.hpp
  • Weave/Profiles/Mercury/Next/Bar.hpp
  • Weave/Profiles/Mercury/Next/Foo.hpp
  • Weave/Profiles/Mercury/Next/Foobar.hpp
  • Weave/Profiles/Mercury/Current/Mercury.hpp
  • Weave/Profiles/Mercury/Current/Bar.hpp
  • Weave/Profiles/Mercury/Current/Foo.hpp
  • Weave/Profiles/Mercury/Current/Foobar.hpp
  • Weave/Profiles/Mercury/Legacy/Mercury.hpp
  • Weave/Profiles/Mercury/Legacy/Bar.hpp
  • Weave/Profiles/Mercury/Legacy/Foo.hpp
  • Weave/Profiles/Mercury/Legacy/Foobar.hpp

其中的 Mercury.hpp 是「umbrella」模組標頭。

除非需要用途是明確在 Weave 中納入命名空間代管模組,例如:

#include 

Weave 模組的公開標頭最好採用非受管的預設路徑 (例如 Weave/Profiles/Mercury/Mercury.hpp)。這麼做可讓 API 開發進化,當這些 API 是透過代管lifecycle流動時,不會持續變更專案的 include 指令。

根據此策略,部署作業便可採用不同的代管命名空間指定項目 (例如目前標示) 重新指定程式碼,並在 C/C++ 預先處理器中指定所需設定。你也可以在指令列、原始碼,或是設定或前置字串標頭中完成這項操作:

#define WEAVE_CONFIG_MERCURY_NAMESPACE kWeaveManagedNamespace_Current

並使用非受管 / 不合格的 include 路徑:

#include 

當目標 API 的代管命名空間指定變更時機和情況時 (例如從目前到舊版),只要調整預先處理器定義即可重新指定:

#define WEAVE_CONFIG_MERCURY_NAMESPACE kWeaveManagedNamespace_Legacy