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

第12章 Controller

第12章 Controller

本章大纲

  1. Controller 定义
  2. Controller 的职责
  3. Web Controller
  4. API Controller
  5. Device Controller
  6. Event Controller
  7. Controller 与 Central
  8. Controller 与 Individual
  9. Controller 调用方式
  10. Controller 实际案例

12.1 Controller 定义

在 SAI Framework 中,Controller 是外部输入进入 SAI Framework 的控制入口层

Controller 的核心任务不是进行认知、推理和决策,而是:

接收外部输入
 ↓
识别输入类型
 ↓
组织 Request / Event
 ↓
转换为 Information
 ↓
把 Information 交给 SAI
 ↓
接收 SAI 输出
 ↓
转换为外部结果

因此可以定义为:

Controller 是连接外部输入与 SAI Runtime 的入口控制对象。

基本结构:

External World
      │
      ▼
   Request
      │
      ▼
 Controller
      │
      ▼
 Information
      │
      ▼
     SAI

Controller 本身不应该承担:

Cognition
Reasoning
Decision
Learning
Memory

这些属于 SAI 内部功能。


12.2 Controller 的职责

Controller 可以承担以下职责:

① 接收输入
② 验证输入
③ 识别输入类型
④ 创建 Request / Event
⑤ 转换 Information
⑥ 调用 SAI Runtime
⑦ 接收执行结果
⑧ 调用 Renderer / Adapter
⑨ 返回外部结果

因此可以形成:

Input
 ↓
Controller
 ↓
Information
 ↓
SAI
 ↓
Result
 ↓
Controller
 ↓
Output

Controller 最重要的是边界转换

例如 Web:

HTTP
 ↓
Controller
 ↓
Information

设备:

Device
 ↓
Controller
 ↓
Information

事件:

Event
 ↓
Controller
 ↓
Information

12.3 Web Controller

Web Controller 是最常见的 Controller。

例如:

Browser
 ↓
HTTP Request
 ↓
WebController
 ↓
Information
 ↓
SAI

假设浏览器发送:

GET /temperature?room=A

WebController 可以读取:

method = GET
path = /temperature
room = A

然后转换:

Information
{
    type: web_request,
    source: browser,
    content:
    {
        action: get_temperature,
        room: A
    }
}

然后:

Information
 ↓
SAI

因此 WebController 不负责“思考”。

它只负责把 Web 世界的信息正确送入 SAI。


12.4 API Controller

API Controller 与 Web Controller 类似,但重点是处理 API 输入。

例如:

POST /api/device

请求:

{
    "device": "fan_001",
    "action": "on"
}

API Controller 接收到以后:

JSON Request
 ↓
API Controller
 ↓
Information

例如:

$information = new Information(
    'api_request',
    'client',
    array(
        'device' => 'fan_001',
        'action' => 'on'
    )
);

进入 SAI:

Information
 ↓
Perception
 ↓
Cognition
 ↓
Reasoning
 ↓
Decision
 ↓
Behavior

执行结果:

Action Result

然后 API Controller 可以把结果交给:

ApiRenderer

最终:

{
    "success": true,
    "device": "fan_001",
    "action": "on"
}

12.5 Device Controller

SAI 不只面对 Web。

外部设备也可能产生输入。

例如:

Temperature Sensor
 ↓
Device Controller
 ↓
Information
 ↓
SAI

设备发送:

temperature = 32

Controller 转换为:

Information
{
    type: device_request,
    source: temperature_sensor,
    content:
    {
        temperature: 32
    }
}

进入:

SAI

之后 SAI 可以根据已有对象、事实和规则进行处理。

例如:

Room.temperature = 32
Fan.state = OFF
Person.state = PRESENT

规则:

IF temperature > 30
AND person = PRESENT
AND fan = OFF

THEN fan.turnOn()

Controller 并不负责执行这个推理。

它只负责:

Device Input
 ↓
Information

12.6 Event Controller

Event Controller 用于处理事件。

例如:

Sensor Event
System Event
Timer Event
Device Event
Task Event

事件:

device_connected

进入:

EventController
 ↓
Information
 ↓
SAI

例如:

$information = new Information(
    'system_event',
    'device_manager',
    array(
        'event' => 'device_connected',
        'device_id' => 'motor_001'
    )
);

SAI 可以进一步判断:

Object = motor_001
State = connected

并更新相应状态。

因此:

Event Controller 负责把外部事件转换成 SAI 可以处理的信息。


12.7 Controller 与 Central

这是 SAI Framework 中一个非常重要的区别。

Controller:

外部
 ↓
Controller
 ↓
Information

Central:

Individual
 ↓
Central
 ↓
内部模块

两者的位置不同。

完整结构:

External World
      │
      ▼
 Controller
      │
      ▼
 Information
      │
      ▼
 Individual
      │
      ▼
 Central
      │
 ┌────┼────┐
 ▼    ▼    ▼
Cognition Memory Reasoning
      │
      ▼
   Decision
      │
      ▼
   Behavior

因此:

Controller Central
外部入口 内部协调
接收外部输入 协调内部模块
Request/Event → Information Information → 内部处理
面向 Framework 外部 面向 Individual 内部
可以是 Web/API/Device/Event 属于 Individual Runtime
不是认知核心 也不是认知本身

最重要的一句话:

Controller 控制“输入如何进入系统”,Central 协调“Individual 内部如何运行”。


12.8 Controller 与 Individual

Controller 也不等于 Individual。

例如:

WebController
      │
      ▼
Information
      │
      ▼
Individual

Controller 是入口。

Individual 是模拟人工个体。

例如一个 SAI 系统:

WebController
DeviceController
SensorController
EventController
       │
       ▼
   Information
       │
       ▼
   Individual
       │
       ▼
     Central

一个 Individual 可以接受多个 Controller 的输入:

                 Individual
                     ▲
          ┌──────────┼──────────┐
          │          │          │
          │          │          │
       WebCtrl   DeviceCtrl  SensorCtrl

因此 Controller 是:

入口对象

Individual 是:

模拟人工个体

两者不能混为一谈。


12.9 Controller 调用方式

Controller 调用 SAI,可以设计成多种方式。

最简单:

Controller
    ↓
Central

但更清晰的设计是:

Controller
    ↓
Information
    ↓
Application / Runtime
    ↓
Individual
    ↓
Central

例如:

$information = $controller->receive(
    $request
);

$result = $application->process(
    $information
);

这里:

Controller

负责:

receive()

而:

Application / Runtime

负责:

process()

这样 Controller 不需要知道 SAI 内部每一个模块的具体实现。


12.10 Controller 基类

可以设计一个简单的 Controller 基类:

<?php

namespace SAI\Core;

abstract class Controller
{
    protected $application;

    public function __construct(
        $application
    ) {
        $this->application = $application;
    }

    abstract public function handle(
        $request
    );
}

这样不同 Controller 可以继承:

Controller
    │
    ├── WebController
    ├── ApiController
    ├── DeviceController
    └── EventController

12.11 WebController

例如:

<?php

namespace SAI\Controller;

use SAI\Core\Controller;
use SAI\Information\Information;

class WebController extends Controller
{
    public function handle($request)
    {
        return new Information(
            'web_request',
            'browser',
            array(
                'method' => $request->getMethod(),
                'path' => $request->getPath()
            )
        );
    }
}

它的任务非常明确:

Request
 ↓
WebController
 ↓
Information

而不是:

WebController
 ↓
Reasoning
 ↓
Decision

12.12 DeviceController

<?php

namespace SAI\Controller;

use SAI\Core\Controller;
use SAI\Information\Information;

class DeviceController extends Controller
{
    public function handle($request)
    {
        return new Information(
            'device_request',
            $request['device'],
            $request['content']
        );
    }
}

调用:

$information = $deviceController->handle(
    array(
        'device' => 'temperature_sensor',
        'content' => array(
            'temperature' => 32
        )
    )
);

得到:

Information
type   = device_request
source = temperature_sensor
content.temperature = 32

12.13 EventController

<?php

namespace SAI\Controller;

use SAI\Core\Controller;
use SAI\Information\Information;

class EventController extends Controller
{
    public function handle($event)
    {
        return new Information(
            'system_event',
            'event_system',
            $event
        );
    }
}

例如:

$information = $eventController->handle(
    array(
        'event' => 'device_connected',
        'device_id' => 'motor_001'
    )
);

12.14 Controller 实际案例

下面建立一个完整的教程案例:

Web Request
 ↓
WebController
 ↓
Information
 ↓
Individual

说明:下面代码属于本章教程示例,用于展示 Controller 的职责与调用关系,不代表已经在实际环境中创建或验证。

目录:

sai-controller-demo/
│
├── app/
│   ├── Core/
│   │   ├── Controller.php
│   │   └── Request.php
│   │
│   ├── Information/
│   │   └── Information.php
│   │
│   ├── Controller/
│   │   └── WebController.php
│   │
│   └── Individual/
│       └── Individual.php
│
├── bootstrap.php
└── index.php

12.14.1 Request.php

<?php

namespace SAI\Core;

class Request
{
    protected $method;
    protected $path;
    protected $query;

    public function __construct(
        $method,
        $path,
        array $query = array()
    ) {
        $this->method = $method;
        $this->path = $path;
        $this->query = $query;
    }

    public function getMethod()
    {
        return $this->method;
    }

    public function getPath()
    {
        return $this->path;
    }

    public function getQuery($name)
    {
        return isset($this->query[$name])
            ? $this->query[$name]
            : null;
    }
}

12.14.2 Controller.php

<?php

namespace SAI\Core;

abstract class Controller
{
    protected $application;

    public function __construct(
        $application = null
    ) {
        $this->application = $application;
    }

    abstract public function handle(
        $request
    );
}

12.14.3 Information.php

<?php

namespace SAI\Information;

class Information
{
    protected $type;
    protected $source;
    protected $content;

    public function __construct(
        $type,
        $source,
        $content
    ) {
        $this->type = $type;
        $this->source = $source;
        $this->content = $content;
    }

    public function getType()
    {
        return $this->type;
    }

    public function getSource()
    {
        return $this->source;
    }

    public function getContent()
    {
        return $this->content;
    }
}

12.14.4 WebController.php

<?php

namespace SAI\Controller;

use SAI\Core\Controller;
use SAI\Information\Information;

class WebController extends Controller
{
    public function handle($request)
    {
        return new Information(
            'web_request',
            'browser',
            array(
                'method' => $request->getMethod(),
                'path' => $request->getPath(),
                'action' => $request->getQuery('action')
            )
        );
    }
}

12.14.5 Individual.php

<?php

namespace SAI\Individual;

class Individual
{
    protected $id;
    protected $name;
    protected $state;

    public function __construct(
        $id,
        $name
    ) {
        $this->id = $id;
        $this->name = $name;
        $this->state = 'created';
    }

    public function start()
    {
        $this->state = 'running';
    }

    public function getId()
    {
        return $this->id;
    }

    public function getName()
    {
        return $this->name;
    }

    public function getState()
    {
        return $this->state;
    }
}

12.15 Bootstrap

<?php

error_reporting(E_ALL);
ini_set('display_errors', '1');

spl_autoload_register(function ($class) {

    $prefix = 'SAI\\';

    if (strpos($class, $prefix) !== 0) {
        return;
    }

    $relative = substr(
        $class,
        strlen($prefix)
    );

    $file = __DIR__
          . '/app/'
          . str_replace(
                '\\',
                '/',
                $relative
            )
          . '.php';

    if (is_file($file)) {
        require_once $file;
    }
});

12.16 index.php

<?php

require_once __DIR__ . '/bootstrap.php';

use SAI\Core\Request;
use SAI\Controller\WebController;
use SAI\Individual\Individual;

$request = new Request(
    isset($_SERVER['REQUEST_METHOD'])
        ? $_SERVER['REQUEST_METHOD']
        : 'CLI',
    isset($_SERVER['REQUEST_URI'])
        ? $_SERVER['REQUEST_URI']
        : '/',
    $_GET
);

$individual = new Individual(
    'sai_001',
    'Indoor SAI'
);

$individual->start();

$controller = new WebController();

$information = $controller->handle(
    $request
);

echo '<pre>';

echo "Controller: WebController"
    . PHP_EOL;

echo "Information Type: "
    . $information->getType()
    . PHP_EOL;

echo "Information Source: "
    . $information->getSource()
    . PHP_EOL;

echo "Action: "
    . $information->getContent()['action']
    . PHP_EOL;

echo "Individual: "
    . $individual->getName()
    . PHP_EOL;

echo "Individual State: "
    . $individual->getState()
    . PHP_EOL;

echo '</pre>';

访问:

/index.php?action=temperature

按照上述代码,预期得到:

Controller: WebController
Information Type: web_request
Information Source: browser
Action: temperature
Individual: Indoor SAI
Individual State: running

同样需要明确:

这是根据教程代码得到的预期运行结果,并非本次实际执行验证结果。


12.17 Controller 的完整调用链

现在把整个案例连接起来:

Browser
   │
   │ HTTP Request
   ▼
Request
   │
   ▼
WebController
   │
   │ handle()
   ▼
Information
   │
   ▼
Individual
   │
   ▼
Central
   │
   ▼
Cognition / Memory / Reasoning
   │
   ▼
Decision
   │
   ▼
Behavior

如果是 Web 输出:

Behavior
   ↓
Expression
   ↓
WebRenderer
   ↓
Response
   ↓
Browser

因此完整 Web SAI:

Browser
 ↓
HTTP Request
 ↓
Request
 ↓
WebController
 ↓
Information
 ↓
Individual
 ↓
Central
 ↓
Cognition
 ↓
Memory
 ↓
Reasoning
 ↓
Decision
 ↓
Behavior
 ↓
Expression
 ↓
WebRenderer
 ↓
Response
 ↓
Browser

12.18 多种 Controller 统一进入 SAI

SAI Framework 可以同时拥有多个 Controller:

                    SAI Framework
                          │
                     Information
                          ▲
              ┌───────────┼───────────┐
              │           │           │
              │           │           │
         WebController ApiController DeviceController
              │           │           │
           Web Request API Request Device Event

再加上事件:

EventController
      │
      ▼
System Event

最终:

Web
 │
 ▼
WebController ──────┐
                    │
API                 │
 │                  │
 ▼                  │
ApiController ──────┤
                    │
Device              │
 │                  │
 ▼                  │
DeviceController ───┤
                    ├──→ Information → SAI
Event               │
 │                  │
 ▼                  │
EventController ────┘

这样 SAI 核心就不需要关心:

输入来自哪里?

它只接收标准化后的:

Information

12.19 Controller 的边界

Controller 最容易出现的问题,就是承担太多职责。

例如错误设计:

Controller
├── Request
├── Information
├── Cognition
├── Memory
├── Reasoning
├── Decision
├── Learning
└── Response

这样 Controller 会变成“超级类”。

更合理的是:

Controller
   │
   └── 输入转换
          │
          ▼
      Information
          │
          ▼
          SAI

SAI 内部:

Information
 ↓
Perception
 ↓
Cognition
 ↓
Memory
 ↓
Reasoning
 ↓
Decision
 ↓
Behavior

输出:

Behavior
 ↓
Expression / Action
 ↓
Renderer / Adapter
 ↓
External World

本章小结

Controller 是 SAI Framework 的外部输入控制层

它主要解决:

外部输入
 ↓
Request / Event
 ↓
Information
 ↓
SAI

不同场景可以使用不同 Controller:

WebController
ApiController
DeviceController
EventController

它们最终都可以统一进入:

Information

最重要的是理解 Controller 与 Central 的区别:

Controller
    ↓
外部输入
    ↓
Information

而:

Central
    ↓
Individual内部协调
    ↓
Cognition / Memory / Reasoning / Decision / Behavior

因此:

Controller 是外部入口,Central 是 Individual 内部协调中心。

完整架构现在可以连接为:

Bootstrap
    ↓
Application
    ↓
Container
    ↓
Controller
    ↓
Request / Event / Sensor
    ↓
Information
    ↓
Individual
    ↓
Central
    ↓
Cognition
    ↓
Memory
    ↓
Reasoning
    ↓
Decision
    ↓
Behavior
    ↓
Expression / Action
    ↓
Renderer / Adapter
    ↓
Response / Device

到这里,第8章 Application、第9章 Bootstrap、第10章 Container、第11章 Request/Response、第12章 Controller 已经形成完整的基础 Framework 链路:

Bootstrap
   ↓
Application
   ↓
Container
   ↓
Controller
   ↓
Information
   ↓
Individual

下一章进入 第13章 Model,重点就可以解决另一个核心问题:

Controller
    ↓
Information
    ↓
Model / Object
    ↓
SAI

并进一步明确 传统 Web Model 与 SAI Object、Property、State、Relation、Fact、Memory 数据对象之间的区别

Leave a Reply

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