首页 理论 架构 工程 文档 白皮书 著作 研究 案例 下载 博客 关于 开始使用 →

第61章 Renderer

第61章 Renderer

1. Renderer 定义

Renderer 是 SATE 中负责将已经确定的结构化表现数据转换为具体表现形式的组件。

前面的 Expression 定义了“需要表现什么”,Template 定义了“按照什么结构表现”,而 Renderer 负责确定:

这些结构化内容最终应该以什么表现形式输出。

基本关系:

Expression
    ↓
Template
    ↓
Renderer
    ↓
Rendered Result

Renderer 本身不负责:

  • 感知
  • 认知
  • 理解
  • 推理
  • 决策
  • 学习
  • 记忆

Renderer 只处理表现转换。

例如:

Expression
{
    type: "RESULT",
    data: {
        name: "Product A",
        state: "available"
    }
}

经过不同 Renderer,可以形成:

WebRenderer
→ HTML

UiRenderer
→ UI结构

ApiRenderer
→ JSON/XML

DeviceRenderer
→ 设备可识别的数据或控制表示

因此:

Renderer ≠ Expression
Renderer ≠ Template
Renderer ≠ Adapter

可以定义为:

Renderer 是 SATE 中将 Expression 与 Template 所形成的结构化表现内容转换为指定表现格式的处理组件。


2. Expression → Renderer

Expression 表示内部结果需要如何对外表现,Renderer 则负责完成具体的表现转换。

基本流程:

ICAI Result
    ↓
Expression
    ↓
Template
    ↓
Renderer
    ↓
Rendered Result
    ↓
Adapter
    ↓
External Output

例如:

ActionResult
{
    state: "SUCCESS",
    output: {
        order_id: 1001,
        status: "created"
    }
}

首先形成 Expression:

Expression
{
    type: "RESULT",
    target: "user",
    data: {
        order_id: 1001,
        status: "created"
    }
}

然后选择 Renderer。

WebRenderer

HTML
<div>
    <span>Order: 1001</span>
    <span>Status: created</span>
</div>

ApiRenderer

{
    "order_id": 1001,
    "status": "created"
}

DeviceRenderer

DEVICE_RESULT
ORDER=1001
STATUS=CREATED

因此 Renderer 的核心不是“产生内容”,而是:

Structured Expression
        ↓
Representation

3. WebRenderer

WebRenderer 用于将 Expression 和 Template 转换为 Web 环境可以使用的表现结果。

最典型的结果是 HTML。

例如:

Expression
{
    type: "RESULT",
    data: {
        title: "Product",
        name: "Electric Toothbrush",
        state: "available"
    }
}

Template:

<h1>{{title}}</h1>

<div class="product">
    <h2>{{name}}</h2>

    {{if state == "available"}}
        <span>Available</span>
    {{else}}
        <span>Unavailable</span>
    {{/if}}
</div>

经过:

Template
    ↓
TemplateEngine
    ↓
WebRenderer
    ↓
HTML

得到:

<h1>Product</h1>

<div class="product">
    <h2>Electric Toothbrush</h2>
    <span>Available</span>
</div>

WebRenderer 可以负责:

  • HTML 文本
  • HTML 属性
  • 页面结构
  • 表格
  • 列表
  • 状态显示
  • 页面组件

但它不应该负责:

HTML → 修改认知状态
HTML → 执行推理
HTML → 修改 Memory

这些属于其他系统。


4. UiRenderer

UiRenderer 用于将结构化 Expression 转换为 UI 所需要的结构。

WebRenderer 主要面向 Web 页面表现,而 UiRenderer 更强调:

界面对象、组件、属性和状态的表现结构。

例如:

Expression
{
    type: "UI",
    component: "ProductCard",
    data: {
        name: "Product A",
        price: 29.90,
        state: "available"
    }
}

UiRenderer 可以转换为:

UI
{
    component: "ProductCard",
    properties: {
        title: "Product A",
        price: 29.90,
        state: "available"
    }
}

进一步可以形成:

Screen
 ├── Header
 ├── ProductCard
 │    ├── Name
 │    ├── Price
 │    └── State
 └── Footer

UiRenderer 可以处理:

  • UI Component
  • Component Property
  • Component State
  • Layout
  • Event 表现定义
  • UI 数据绑定结构

例如:

ProductCard
{
    title: "Electric Toothbrush",
    price: 29.90,
    state: "available"
}

需要特别区分:

UiRenderer
    ↓
表现 UI 状态

Behavior
    ↓
实际行为

Action
    ↓
实际行动

例如:

Button.state = "disabled"

只是 UI 表现。

它并不意味着:

Action = disabled

5. ApiRenderer

ApiRenderer 用于将 Expression 转换为 API 可以传输的结构化数据。

常见表现形式包括:

JSON
XML
Structured Text

例如:

Expression
{
    type: "RESULT",
    data: {
        id: 1001,
        name: "Product A",
        state: "available"
    }
}

ApiRenderer 可以输出:

{
    "id": 1001,
    "name": "Product A",
    "state": "available"
}

也可以输出 XML:

<product>
    <id>1001</id>
    <name>Product A</name>
    <state>available</state>
</product>

ApiRenderer 的重点是:

结构稳定
字段明确
类型明确
格式确定

例如:

API Result
{
    success: true,
    data: {
        id: 1001,
        state: "available"
    },
    error: null
}

ApiRenderer 不负责决定:

应该返回什么知识?
应该采取什么行动?
应该选择哪个方案?

这些结果应该已经由前面的认知、推理、决策和 Expression 层确定。

ApiRenderer 只是:

Existing Structured Data
        ↓
API Representation

6. DeviceRenderer

DeviceRenderer 用于将 Expression 转换为特定设备、终端或系统接口能够识别的表现结构。

例如一个设备状态:

Expression
{
    type: "STATE",
    target: "Device_A",
    data: {
        power: "ON",
        temperature: 25,
        mode: "NORMAL"
    }
}

DeviceRenderer 可以转换为:

DEVICE_STATE
POWER=ON
TEMPERATURE=25
MODE=NORMAL

或者转换为设备接口需要的结构:

{
    "device": "Device_A",
    "command": "SET_STATE",
    "parameters": {
        "power": "ON",
        "mode": "NORMAL"
    }
}

DeviceRenderer 的具体输出取决于设备接口规范。

可以包括:

Device
 ├── Sensor
 ├── Controller
 ├── Terminal
 ├── Display
 ├── Industrial Device
 └── System Interface

但需要保持一个重要边界:

DeviceRenderer
    ↓
生成设备表现/接口数据

DeviceAdapter
    ↓
发送到设备

Device
    ↓
实际执行

所以:

Renderer ≠ Device Control

Renderer 只负责表现转换。


7. Renderer Interface

为了让不同 Renderer 可以被 SATE 统一管理,可以定义 Renderer Interface。

基本接口:

interface RendererInterface
{
    public function render($expression, $template = null);
    public function supports($type);
    public function getName();
}

例如 WebRenderer:

class WebRenderer implements RendererInterface
{
    public function render($expression, $template = null)
    {
        return $this->renderHtml($expression, $template);
    }

    public function supports($type)
    {
        return $type === 'WEB';
    }

    public function getName()
    {
        return 'WebRenderer';
    }

    protected function renderHtml($expression, $template)
    {
        return '';
    }
}

ApiRenderer:

class ApiRenderer implements RendererInterface
{
    public function render($expression, $template = null)
    {
        return json_encode($expression);
    }

    public function supports($type)
    {
        return $type === 'API';
    }

    public function getName()
    {
        return 'ApiRenderer';
    }
}

这样 Renderer 就具有统一入口:

RendererInterface
       │
       ├── WebRenderer
       ├── UiRenderer
       ├── ApiRenderer
       └── DeviceRenderer

以后增加:

XmlRenderer
TextRenderer
ConsoleRenderer
FileRenderer

也不需要改变 Renderer 的基本体系。


8. Renderer Manager

当系统存在多个 Renderer 时,需要 Renderer Manager 负责管理和选择 Renderer。

基本结构:

RendererManager
{
    renderers
    register()
    remove()
    get()
    find()
    render()
}

例如:

class RendererManager
{
    protected $renderers = array();

    public function register(RendererInterface $renderer)
    {
        $this->renderers[$renderer->getName()] = $renderer;
    }

    public function get($name)
    {
        if (!isset($this->renderers[$name])) {
            return null;
        }

        return $this->renderers[$name];
    }

    public function render($rendererName, $expression, $template = null)
    {
        $renderer = $this->get($rendererName);

        if (!$renderer) {
            return null;
        }

        return $renderer->render($expression, $template);
    }
}

注册:

$manager = new RendererManager();

$manager->register(new WebRenderer());
$manager->register(new ApiRenderer());

调用:

$result = $manager->render(
    'WebRenderer',
    $expression,
    $template
);

或者:

$result = $manager->render(
    'ApiRenderer',
    $expression
);

Renderer Manager 的职责是:

Renderer 注册
      ↓
Renderer 查找
      ↓
Renderer 选择
      ↓
Renderer 执行
      ↓
Rendered Result

它不负责:

认知
推理
决策
学习
记忆

9. Renderer 示例

下面使用一个完整的表现案例。

假设 ICAI 已经完成:

Perception
    ↓
Cognition
    ↓
Understanding
    ↓
Memory
    ↓
Reasoning
    ↓
Decision
    ↓
Behavior
    ↓
Action
    ↓
ActionResult

ActionResult:

ActionResult
{
    action_id: 1001,
    state: "SUCCESS",
    output: {
        product: "Electric Toothbrush",
        quantity: 100,
        status: "created"
    }
}

形成 Expression:

Expression
{
    expression_id: 2001,
    type: "RESULT",
    target: "external",
    data: {
        product: "Electric Toothbrush",
        quantity: 100,
        status: "created"
    }
}

选择 WebRenderer:

Expression
    ↓
WebRenderer
    ↓
HTML

结果:

<div class="result">
    <h2>Order Result</h2>
    <p>Product: Electric Toothbrush</p>
    <p>Quantity: 100</p>
    <p>Status: created</p>
</div>

选择 ApiRenderer:

Expression
    ↓
ApiRenderer
    ↓
JSON

结果:

{
    "product": "Electric Toothbrush",
    "quantity": 100,
    "status": "created"
}

选择 UiRenderer:

Expression
    ↓
UiRenderer
    ↓
UI Structure

结果:

OrderResult
{
    component: "ResultPanel",
    children: [
        {
            component: "Product",
            value: "Electric Toothbrush"
        },
        {
            component: "Quantity",
            value: 100
        },
        {
            component: "Status",
            value: "created"
        }
    ]
}

选择 DeviceRenderer:

Expression
    ↓
DeviceRenderer
    ↓
Device Representation

结果:

RESULT
PRODUCT=Electric Toothbrush
QUANTITY=100
STATUS=CREATED

因此,同一个 Expression 可以拥有不同表现:

                    ┌── WebRenderer ─── HTML
                    │
Expression ─────────┼── UiRenderer ──── UI
                    │
                    ├── ApiRenderer ─── JSON/XML
                    │
                    └── DeviceRenderer ─ Device Data

而这些 Renderer 都可以由 RendererManager 统一管理。


核心模型

第61章可以把 Renderer 放在 SATE 中的这个位置:

ICAI
 ↓
Expression
 ↓
SATE
 ↓
Template
 ↓
Renderer
 ↓
Rendered Result
 ↓
Adapter
 ↓
External Environment

其中:

Expression = 表现什么
Template   = 按什么结构表现
Renderer   = 转换成什么表现形式
Adapter    = 输出到哪里

例如:

Expression
    ↓
Template
    ↓
WebRenderer
    ↓
HTML
    ↓
WebAdapter
    ↓
Browser

或者:

Expression
    ↓
Template
    ↓
ApiRenderer
    ↓
JSON
    ↓
ApiAdapter
    ↓
External System

再或者:

Expression
    ↓
Template
    ↓
DeviceRenderer
    ↓
Device Data
    ↓
DeviceAdapter
    ↓
Device

核心定义

Renderer 是 SATE 中负责将 Expression 按照 Template 所定义的结构转换为具体表现形式的组件。WebRenderer、UiRenderer、ApiRenderer、DeviceRenderer 等 Renderer 面向不同表现环境,但共同遵循统一的 Renderer Interface,并由 Renderer Manager 进行注册、选择和执行。

最终形成:

Expression
    ↓
Template
    ↓
Renderer
    ↓
Rendered Result
    ↓
Adapter
    ↓
Output

这也进一步明确了 Renderer 与 Adapter 的边界:Renderer 负责“表现成什么”,Adapter 负责“输出到哪里”。

Leave a Reply

Your email address will not be published. Required fields are marked *