6.2 KiB
Structive Extension 架构指南
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 可以拥有自己的持久化 metadata,RPC 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-valued,Extension 可以允许同 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 和 mutex,managed 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 前检查:
- Core 是否已经提供所需的通用结构机制?
- 能否表达成 Extension-owned Attribute?
- Fallback 是否由 Extension 自己拥有?
- Access / Exposure Policy 是否仍在 Core 外?
- 是否把 intrinsic
readable/writable当结构事实,而不是 authorization? - 是否避免无意 raw write 绕过 managed synchronization?
- Core 是否仍完全独立于 Extension?