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

第108章 如何开发 SAI Extension

第108章 如何开发 SAI Extension

第107章建立了 SAI Object,解决了 SAI 如何表示对象、属性、方法、关系和状态的问题。

但是,一个完整的 SAI Framework 不可能把所有功能都直接写进 Core。

例如以后可能增加:

Temperature Extension
Robot Extension
Vehicle Extension
Industrial Extension
Web Extension
File Extension
Sensor Extension
Device Extension
Detection Extension
Learning Extension

这些功能应该能够:

  • 独立存在
  • 独立注册
  • 独立加载
  • 独立配置
  • 独立启动
  • 独立停止
  • 独立卸载

因此需要 Extension System

本章核心结构:

Extension
│
├── Interface
├── Directory
├── Registry
├── Manager
├── Loading
├── Configuration
└── Runtime

1. Extension Interface

1.1 Extension 定义

Extension 是 SAI Framework 中用于扩展 Core 功能的独立功能单元。

可以定义为:

Extension =
Identity
+
Function
+
Interface
+
Lifecycle
+
Configuration

Extension 本身不是 Individual,也不是 Module、Engine。

它更接近于:

一个可以被 Framework 注册、加载、启动、停止和卸载的扩展载体。


1.2 ExtensionInterface

建立统一接口:

<?php

interface ExtensionInterface
{
    public function getId();

    public function getName();

    public function getVersion();

    public function initialize();

    public function start();

    public function stop();

    public function shutdown();

    public function getState();
}

这样 Framework 就可以统一处理不同 Extension。

例如:

RobotExtension
VehicleExtension
SensorExtension
LearningExtension

都必须实现:

ExtensionInterface

1.3 Extension 生命周期

一个 Extension 可以经过:

NEW
 ↓
REGISTERED
 ↓
LOADED
 ↓
INITIALIZED
 ↓
READY
 ↓
RUNNING
 ↓
STOPPING
 ↓
STOPPED
 ↓
UNLOADED

异常状态:

ERROR
CONFLICT
DISABLED
INVALID
UNKNOWN

2. Extension Directory

2.1 为什么需要 Extension Directory

Extension 不能全部放在 Framework Core 中。

因此建立独立目录:

sai/
│
├── core/
│
├── modules/
│
├── engines/
│
├── objects/
│
└── extensions/

例如:

extensions/
│
├── RobotExtension/
│   ├── Extension.php
│   ├── config.php
│   └── README.md
│
├── VehicleExtension/
│   ├── Extension.php
│   └── config.php
│
└── TemperatureExtension/
    ├── Extension.php
    └── config.php

2.2 一个 Extension 的基本目录

例如:

TemperatureExtension/
│
├── Extension.php
├── config.php
└── engines/
    └── TemperatureEngine.php

如果 Extension 需要 Object:

TemperatureExtension/
│
├── Extension.php
├── config.php
├── engines/
│   └── TemperatureEngine.php
└── objects/
    └── TemperatureObject.php

因此 Extension 可以作为一个功能集合的载体。


3. Extension Registry

3.1 Registry 定义

Extension Registry 用于记录系统中有哪些 Extension。

例如:

$registry = array(
    'temperature' => array(
        'id' => 'temperature',
        'name' => 'Temperature Extension',
        'version' => '1.0.0',
        'class' => 'TemperatureExtension',
        'path' => 'extensions/TemperatureExtension/Extension.php',
        'enabled' => true,
        'state' => 'REGISTERED'
    )
);

3.2 Registry 的作用

Registry 主要记录:

id
name
version
class
path
type
dependencies
configuration
enabled
state

例如:

TemperatureExtension
│
├── id = temperature
├── version = 1.0.0
├── class = TemperatureExtension
├── path = extensions/TemperatureExtension/Extension.php
├── enabled = true
└── state = REGISTERED

3.3 Registry ≠ Manager

必须区分:

Registry
=
记录有哪些 Extension

而:

Manager
=
管理当前 Extension

例如:

ExtensionRegistry
│
├── RobotExtension
├── VehicleExtension
├── TemperatureExtension
└── SensorExtension

运行时:

ExtensionManager
│
├── RobotExtension
└── TemperatureExtension

所以:

Registered ≠ Loaded
Loaded ≠ Running

4. Extension Manager

4.1 ExtensionManager 定义

ExtensionManager 是 Extension 的运行管理组件。

主要负责:

register
get
load
initialize
start
stop
shutdown
unload

4.2 基本代码

<?php

class ExtensionManager
{
    protected $extensions = array();

    public function register(ExtensionInterface $extension)
    {
        $this->extensions[$extension->getId()] = $extension;

        return true;
    }

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

        return $this->extensions[$id];
    }

    public function exists($id)
    {
        return isset($this->extensions[$id]);
    }

    public function start($id)
    {
        $extension = $this->get($id);

        if ($extension === null) {
            return false;
        }

        return $extension->start();
    }

    public function stop($id)
    {
        $extension = $this->get($id);

        if ($extension === null) {
            return false;
        }

        return $extension->stop();
    }

    public function all()
    {
        return $this->extensions;
    }
}

5. Extension Loading

5.1 Loading 定义

Extension Loading 是 Framework 把一个已经登记的 Extension 转换成运行对象的过程。

基本流程:

Registry
   ↓
Read Configuration
   ↓
Check Enabled
   ↓
Check Directory
   ↓
Check File
   ↓
Load Class
   ↓
Check Interface
   ↓
Create Object
   ↓
Initialize
   ↓
READY

5.2 File Check

首先确认 Extension 文件存在:

if (!file_exists($path)) {
    return false;
}

不能因为 Registry 中存在记录,就认为 Extension 一定可用。


5.3 Class Check

加载文件:

require_once $path;

然后检查:

if (!class_exists($className)) {
    return false;
}

5.4 Interface Check

必须确认:

$interfaces = class_implements($className);

if (!isset($interfaces['ExtensionInterface'])) {
    return false;
}

这样可以避免一个普通 PHP Class 被错误当成 Extension。


5.5 Create Object

检查通过后:

$extension = new $className();

然后:

NEW
 ↓
INITIALIZING
 ↓
READY

6. Extension Configuration

6.1 Configuration 定义

Extension 不应该把所有参数直接写死在 Class 中。

例如:

TemperatureExtension

可能需要:

temperature_limit
check_interval
enabled
logging

因此需要 Configuration。


6.2 config.php

例如:

<?php

return array(

    'enabled' => true,

    'temperature_limit' => 85,

    'check_interval' => 10,

    'logging' => true

);

6.3 Configuration 结构

可以统一:

Extension Configuration
│
├── enabled
├── version
├── dependencies
├── parameters
├── runtime
└── logging

例如:

$config = array(

    'enabled' => true,

    'version' => '1.0.0',

    'parameters' => array(
        'temperature_limit' => 85
    ),

    'runtime' => array(
        'interval' => 10
    ),

    'logging' => true
);

6.4 Configuration ≠ Cognition

Configuration 只是参数。

例如:

temperature_limit = 85

表示系统配置。

真正的运行判断:

temperature = 92
limit = 85

92 > 85
    ↓
HIGH

属于 Engine / Rule 等运行逻辑。

所以:

Configuration ≠ Rule
Configuration ≠ Cognition
Configuration ≠ Reasoning

7. Extension Runtime

7.1 Runtime 定义

Extension Runtime 是 Extension 被加载并开始提供功能后的运行阶段。

例如:

Framework
   ↓
ExtensionManager
   ↓
TemperatureExtension
   ↓
TemperatureEngine
   ↓
Input
   ↓
Processing
   ↓
Result

7.2 Extension 可以包含 Engine

例如:

TemperatureExtension
│
├── TemperatureEngine
├── TemperatureObject
└── TemperatureRule

因此:

Extension
   ├── Module
   ├── Engine
   ├── Object
   ├── Rule
   └── Adapter

具体包含什么,由 Extension 自己的功能需求决定。


7.3 Extension Runtime 不等于 Individual Runtime

这是非常重要的边界。

Individual Runtime
=
运行 SAI Individual 的认知生命周期

而:

Extension Runtime
=
运行某个扩展功能

例如:

Individual_A
     ↓
Cognition
     ↓
Reasoning
     ↓
Decision
     ↓
TemperatureExtension
     ↓
TemperatureEngine

Extension 是 Individual 可以使用的功能资源之一。


8. 完整 Extension 示例

现在开发一个最简单的:

TemperatureExtension

功能:

输入 temperature
输入 limit
判断 temperature 是否超过 limit
返回 HIGH / NORMAL

整个过程使用:

Extension
+
Engine
+
Configuration
+
Manager

不使用任何生成式模型机制。


8.1 项目目录

simple-sai/
│
├── index.php
│
├── core/
│   ├── ExtensionInterface.php
│   └── ExtensionManager.php
│
└── extensions/
    │
    └── TemperatureExtension/
        ├── Extension.php
        ├── config.php
        └── TemperatureEngine.php

8.2 ExtensionInterface.php

<?php

interface ExtensionInterface
{
    public function getId();

    public function getName();

    public function getVersion();

    public function initialize();

    public function start();

    public function stop();

    public function shutdown();

    public function getState();
}

8.3 TemperatureEngine.php

<?php

class TemperatureEngine
{
    protected $limit = 85;

    public function __construct($config = array())
    {
        if (isset($config['temperature_limit'])) {
            $this->limit = $config['temperature_limit'];
        }
    }

    public function execute($temperature)
    {
        if (!is_numeric($temperature)) {
            return array(
                'state' => 'INVALID',
                'error' => 'TEMPERATURE_INVALID'
            );
        }

        if ($temperature > $this->limit) {

            return array(
                'state' => 'SUCCESS',
                'level' => 'HIGH',
                'temperature' => $temperature,
                'limit' => $this->limit
            );
        }

        return array(
            'state' => 'SUCCESS',
            'level' => 'NORMAL',
            'temperature' => $temperature,
            'limit' => $this->limit
        );
    }
}

8.4 config.php

<?php

return array(

    'enabled' => true,

    'temperature_limit' => 85

);

8.5 Extension.php

<?php

require_once dirname(__FILE__) . '/../../core/ExtensionInterface.php';
require_once dirname(__FILE__) . '/TemperatureEngine.php';

class TemperatureExtension implements ExtensionInterface
{
    protected $id = 'temperature';

    protected $name = 'Temperature Extension';

    protected $version = '1.0.0';

    protected $state = 'NEW';

    protected $config = array();

    protected $engine;

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

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

    public function getVersion()
    {
        return $this->version;
    }

    public function initialize()
    {
        $this->state = 'INITIALIZING';

        $configFile = dirname(__FILE__) . '/config.php';

        if (!file_exists($configFile)) {
            $this->state = 'ERROR';

            return false;
        }

        $this->config = require $configFile;

        if (isset($this->config['enabled'])
            && !$this->config['enabled']) {

            $this->state = 'DISABLED';

            return false;
        }

        $this->engine = new TemperatureEngine(
            $this->config
        );

        $this->state = 'READY';

        return true;
    }

    public function start()
    {
        if ($this->state !== 'READY') {
            return false;
        }

        $this->state = 'RUNNING';

        return true;
    }

    public function stop()
    {
        if ($this->state !== 'RUNNING') {
            return false;
        }

        $this->state = 'STOPPED';

        return true;
    }

    public function shutdown()
    {
        $this->engine = null;

        $this->state = 'SHUTDOWN';

        return true;
    }

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

    public function execute($temperature)
    {
        if ($this->state !== 'RUNNING') {
            return array(
                'state' => 'NOT_RUNNING'
            );
        }

        return $this->engine->execute($temperature);
    }
}

9. ExtensionManager 完整示例

<?php

class ExtensionManager
{
    protected $extensions = array();

    public function register(ExtensionInterface $extension)
    {
        $this->extensions[$extension->getId()] = $extension;

        return true;
    }

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

        return $this->extensions[$id];
    }

    public function initialize($id)
    {
        $extension = $this->get($id);

        if ($extension === null) {
            return false;
        }

        return $extension->initialize();
    }

    public function start($id)
    {
        $extension = $this->get($id);

        if ($extension === null) {
            return false;
        }

        return $extension->start();
    }

    public function stop($id)
    {
        $extension = $this->get($id);

        if ($extension === null) {
            return false;
        }

        return $extension->stop();
    }
}

10. index.php

<?php

require_once 'core/ExtensionInterface.php';
require_once 'core/ExtensionManager.php';

require_once
    'extensions/TemperatureExtension/Extension.php';

$manager = new ExtensionManager();

$extension = new TemperatureExtension();

$manager->register($extension);

$manager->initialize('temperature');

$manager->start('temperature');

$result = $extension->execute(92);

echo '<pre>';
print_r($result);
echo '</pre>';

$manager->stop('temperature');

$extension->shutdown();

11. 完整运行过程

输入:

temperature = 92

配置:

temperature_limit = 85

运行:

92 > 85

得到:

state       = SUCCESS
level       = HIGH
temperature = 92
limit       = 85

完整执行过程:

index.php
   ↓
ExtensionManager
   ↓
TemperatureExtension
   ↓
initialize()
   ↓
读取 config.php
   ↓
TemperatureEngine
   ↓
start()
   ↓
execute(92)
   ↓
92 > 85
   ↓
HIGH
   ↓
Result

12. Extension 与 Framework 的完整关系

到第108章,SAI Framework 的结构进一步形成:

SAI Framework
│
├── Kernel
│
├── Individual
│
├── Module
│
├── Engine
│
├── Object
│
├── Extension
│
├── Event
│
├── Task
│
├── Memory
│
├── Renderer
│
└── Adapter

其中 Extension 可以承载其他组件:

Extension
│
├── Module
│
├── Engine
│
├── Object
│
├── Rule
│
├── Renderer
│
└── Adapter

这使 Framework Core 不需要因为增加一个新功能而不断修改核心结构。


13. Extension 完整生命周期

最终可以统一为:

NEW
 ↓
REGISTERED
 ↓
LOADED
 ↓
INITIALIZING
 ↓
READY
 ↓
RUNNING
 ↓
STOPPING
 ↓
STOPPED
 ↓
SHUTDOWN
 ↓
UNLOADED

异常:

ERROR
CONFLICT
DISABLED
INVALID
UNKNOWN

14. Extension 与其他组件的区别

这一章之后几个概念需要严格区分:

组件 主要职责
Individual SAI 个体运行主体
Module 功能组织单元
Engine 具体功能执行
Object 实体结构表示
Extension 功能扩展载体
Registry 登记组件
Manager 管理组件
Adapter 连接外部环境
Renderer 转换外部表现形式

最重要的关系:

Extension
   ↓
承载
   ↓
Module / Engine / Object / Rule / Adapter / Renderer

而:

Registry
=
登记

Manager
=
管理

Runtime
=
运行

本章核心定义

Extension Interface

规定 Extension 必须具备的统一生命周期和基本身份接口。

Extension Directory

保存 Extension 独立代码、配置及其相关组件的目录结构。

Extension Registry

记录 Extension 身份、Class、路径、版本、依赖、配置和状态的登记结构。

Extension Manager

负责 Extension 注册、获取、初始化、启动、停止和关闭等运行管理。

Extension Loading

将 Registry 中登记的 Extension 检查、载入、实例化并初始化为可运行对象的过程。

Extension Configuration

为 Extension 提供启用状态、参数、依赖和运行配置的结构化参数。

Extension Runtime

Extension 被初始化并进入运行状态后实际提供功能的运行过程。


本章最终模型

                    SAI Framework
                         │
                         ↓
                  Extension Registry
                         │
                         ↓
                  Extension Manager
                         │
                         ↓
                    Extension
                         │
          ┌──────────────┼──────────────┐
          ↓              ↓              ↓
       Module         Engine         Object
          │              │              │
          └──────────────┼──────────────┘
                         ↓
                     Runtime
                         │
                         ↓
                       Result

Extension 的核心价值可以概括为:

Core
 ↓
Extension Interface
 ↓
Extension
 ↓
独立功能
 ↓
注册
 ↓
加载
 ↓
配置
 ↓
运行
 ↓
停止 / 卸载

因此,第108章建立的是 SAI Framework 的动态扩展机制

Core 提供稳定基础,Extension 提供可注册、可加载、可配置、可运行、可停止的外部功能。

并且 Extension 本身仍然只是功能扩展机制,它不承担 Cognition、Reasoning、Decision 等认知职责,也不改变 SAI 的符号、规则、对象、关系和离散计算基础。

Leave a Reply

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