Files
Structive/docs/EXTENSIONS.zh-CN.md
2026-08-07 17:50:04 +08:00

6.2 KiB
Raw Permalink Blame History

Structive Extension 架构指南

English

1. Extension 的职责

Extension 给 Structive 增加领域 metadata 与领域解释,但不能让 Property Core 反向依赖具体领域。

依赖方向:

Extension → Property Core
Property Core -X→ Extension

Core 提供:

  • Schema 与 Property Descriptor
  • intrinsic readable/writable
  • Attribute 协议;
  • Constraint
  • Synchronization metadata 与 managed access
  • Runtime structural access。

Extension 定义自己的 category 与解释逻辑。

2. Extension 基本原则

Extension 只拥有自己的领域语义。

例如 Presentation 拥有:

label
description
group
order

Property Core 不需要理解 presentation。

未来 Persistence Extension 可以拥有自己的持久化 metadataRPC Extension 可以拥有协议 metadata。

3. 外部 Policy 永远属于外部

Property Core 完全没有内建访问控制模式。

Extension 或应用层自己负责:

这个属性要不要显示?
这个 endpoint 要不要允许写?
这个 Property 要不要持久化?
当前用户是否有权限?

Extension 可以读取结构事实:

Property::readable
Property::writable
sensitive metadata
Extension 自己的 metadata

但最终 policy 属于 Consumer。

read_only 只表示 Structive managed object 自身没有这个 Property 的写操作,不代表任何外部系统必须暴露它。

4. 当前 Presentation Extension

Include

#include <structive/property/extensions/presentation.hpp>

Link

target_link_libraries(my_target PRIVATE structive::property_extensions)

当前 Attribute

presentation::label<"Temperature">
presentation::description<"Current device temperature">
presentation::group<"Environment">
presentation::order<2>

示例:

field<&Device::temperature>(
    key<"temperature">,
    unit<"C">,
    presentation::label<"Temperature">,
    presentation::description<"Current device temperature">,
    presentation::group<"Environment">,
    presentation::order<2>
)

5. Presentation 解释

auto info = presentation::describe<&Device::temperature>(device.schema());

Presentation_Info

key
label
description
group
order
has_order

没有 label 时,Presentation Extension fallback 到 Property key。这个 fallback 属于 Presentation,不属于 Core。

6. 可继承 Extension Attribute

Extension category 可以选择 inheritable

defaults(
    presentation::group<"Environment">
)

Property-level metadata 覆盖同 category 的 inheritable single-valued default。

只有真正适合继承的 metadata 才应该这样设计。

7. 设计新的 Extension Attribute

namespace my_extension {
struct Format_Category {};
template <Fixed_String Value>
struct Format_Attribute {
    using attribute_category = Format_Category;
    static constexpr bool single_valued = true;
    static constexpr bool inheritable = false;
    static constexpr auto value = Value;
};
template <Fixed_String Value>
inline constexpr Format_Attribute<Value> format{};
}

直接挂在 Property

field<&Device::temperature>(
    key<"temperature">,
    my_extension::format<"0.0 C">
)

不需要修改 Core。

8. 读取 Extension Attribute

Descriptor-local metadata

using Property = std::remove_cvref_t<decltype(schema.property<&Device::temperature>())>;
static_assert(Property::template has_attribute<my_extension::Format_Category>);

可继承 metadata 可以使用 Core 的通用 effective-Attribute 工具。

Fallback 和解释规则由 Extension 自己拥有。

9. Multi-Valued Metadata

如果 category 不是 single-valuedExtension 可以允许同 category 多个 Attribute。

只有重复声明本身结构非法时才应该设置 single_valued = true

10. 推荐 Extension 边界

适合的领域包括:

  • Presentation / Editor Hint
  • Serialization Name / Format Hint
  • Persistence Mapping Metadata
  • RPC / Protocol Naming Metadata
  • Diagnostics / Telemetry Metadata
  • Documentation Metadata。

领域实现继续放在 Property Core 外部。

11. 使用 Intrinsic Capability

Consumer 可以把 intrinsic capability 当作结构事实。

例如 Editor 可以先用:

Property::writable

判断一个 Property 是否具备“可编辑的结构资格”,但 Editor 仍然可以叠加自己的应用 policy。

Persistence Adapter 即使看到 Property::readable == true,也完全可以决定不保存它。

RPC Endpoint 即使看到一个 Property writable,也可以完全不暴露它。

这种分离是刻意设计。

12. Read-Only 优化属于 Core 保证

Extension 不需要为 stored read_only Property 自己实现特殊锁逻辑。

Core 保证这类 Property 不贡献 lock slot 和 mutexmanaged read 走 no-lock path。

如果 Extension 故意通过 raw C++ 写它,就已经绕过该保证,同步责任由 Extension 自己承担。

13. Fallback 属于 Consumer

Core 不应该决定:

没有 label -> key
没有 database column -> key
没有 RPC name -> key

这些 fallback 属于对应 Extension 或 Adapter。

14. 防止 Extension 语义泄漏进 Core

不要因为一个 Extension 需要某个概念,就给 Core 增加特殊 enum 或分支。

优先:

Extension-owned Attribute category
+ Extension-owned interpretation

而不是:

Core 学会 Extension 领域语义

15. Header-Only Metadata 与 Linked Code

Metadata 类型通常可以保持 header-only。领域确实需要非模板 runtime behavior 时,再放 linked implementation。

当前 Presentation Extension 把 metadata 放头文件,把 make_presentation_info 放 linked target。

16. Extension 审核清单

新增 Extension feature 前检查:

  1. Core 是否已经提供所需的通用结构机制?
  2. 能否表达成 Extension-owned Attribute
  3. Fallback 是否由 Extension 自己拥有?
  4. Access / Exposure Policy 是否仍在 Core 外?
  5. 是否把 intrinsic readable/writable 当结构事实,而不是 authorization
  6. 是否避免无意 raw write 绕过 managed synchronization
  7. Core 是否仍完全独立于 Extension