第10章 Container
本章大纲
- Container 定义
- 为什么需要 Container
- 对象注册
- 对象获取
- 依赖管理
- Singleton
- Factory
- Service
- Engine 注册
- Manager 注册
- Individual 注册
- Container 实际运行案例
10.1 Container 定义
在 SAI Framework 中,Container 是 Framework 内部的对象与服务管理容器。
它主要负责:
对象创建
↓
对象注册
↓
对象保存
↓
对象获取
↓
对象依赖管理
简单来说:
Container 负责管理 SAI Framework 运行过程中需要使用的对象。
例如 SAI Framework 中可能存在:
Application
Individual
Central
Memory
Cognition
Reasoning
Decision
Behavior
Learning
Engine
Manager
如果所有对象都由不同代码直接:
new Memory();
new Cognition();
new Reasoning();
new Decision();
随着系统规模扩大,对象之间的依赖会越来越复杂。
Container 就可以成为统一的对象管理中心:
Container
│
┌────────────────┼────────────────┐
▼ ▼ ▼
Individual Memory Cognition
│ │ │
▼ ▼ ▼
Central Reasoning Decision
需要特别强调:
Container 是工程基础设施,不是 SAI 的智能核心。
它不负责:
感知
认知
推理
决策
学习
10.2 为什么需要 Container
假设没有 Container。
Individual 需要 Memory:
$memory = new Memory();
Memory 又需要 MemoryEngine:
$engine = new MemoryEngine();
$memory = new Memory($engine);
Reasoning 又需要:
$ruleEngine = new RuleEngine();
$memory = new Memory($engine);
$reasoning = new Reasoning(
$memory,
$ruleEngine
);
Decision 又需要 Reasoning:
$decision = new Decision(
$reasoning
);
最终代码可能变成:
Individual
├── Memory
│ └── MemoryEngine
│
├── Cognition
│ ├── Matcher
│ └── ...
│
├── Reasoning
│ ├── Memory
│ └── RuleEngine
│
└── Decision
└── Reasoning
对象之间形成复杂依赖。
Container 的目的就是把这些依赖集中管理。
例如:
Container
│
├── memory
├── cognition
├── reasoning
├── decision
└── behavior
其他对象只需要获取:
$container->get('memory');
而不必自己负责寻找 Memory。
10.3 对象注册
Container 最基本的操作就是:
set()
例如:
$container->set(
'memory',
$memory
);
表示:
名称:memory
对象:$memory
Container 内部可以保存:
protected $items = array();
注册以后:
items
│
├── config
├── memory
├── cognition
├── reasoning
└── decision
一个最简单的实现:
<?php
namespace SAI\Core;
class Container
{
protected $items = array();
public function set($name, $object)
{
$this->items[$name] = $object;
}
}
使用:
$container = new Container();
$container->set(
'memory',
$memory
);
这就是:
对象注册。
10.4 对象获取
注册对象以后,需要获取对象。
因此 Container 增加:
get()
例如:
$memory = $container->get('memory');
完整代码:
public function get($name)
{
if (isset($this->items[$name])) {
return $this->items[$name];
}
return null;
}
于是:
注册:
memory → Memory Object
获取:
memory
↓
Memory Object
完整过程:
$memory
│
▼
Container->set('memory', $memory)
│
▼
Container
│
▼
Container->get('memory')
│
▼
$memory
10.5 判断对象是否存在
实际 Framework 中还需要知道某个服务是否已经注册。
因此可以增加:
has()
例如:
public function has($name)
{
return isset($this->items[$name]);
}
使用:
if ($container->has('memory')) {
$memory = $container->get('memory');
}
这样可以避免直接获取不存在的对象。
10.6 依赖管理
Container 更重要的作用是管理对象之间的依赖关系。
例如:
Reasoning
↓ depends on
Memory
↓ depends on
MemoryEngine
可以表示:
$memoryEngine = new MemoryEngine();
$memory = new Memory(
$memoryEngine
);
$reasoning = new Reasoning(
$memory
);
Container 可以管理这些对象:
Container
│
├── memory.engine
│
├── memory
│
└── reasoning
然后:
$memoryEngine = $container->get('memory.engine');
$memory = $container->get('memory');
$reasoning = $container->get('reasoning');
这实际上形成:
Container
│
├── Object A
│
├── Object B
│
└── Object C
│
└── dependencies
10.7 Singleton
Singleton 的核心思想是:
同一个 Container 生命周期中,对某个服务只保留一个实例。
例如:
$memory = new Memory();
$container->set(
'memory',
$memory
);
以后:
$memory1 = $container->get('memory');
$memory2 = $container->get('memory');
两者实际上指向同一个对象实例。
概念上:
get('memory')
│
▼
Memory
▲
│
get('memory')
而不是:
get('memory')
↓
new Memory
get('memory')
↓
new Memory
因此 Container 可以保存共享服务。
例如:
Configuration
Logger
MemoryManager
ObjectManager
RuleManager
这些对象在很多情况下适合共享。
但是要注意:
Singleton 是对象生命周期管理方式,不是 SAI 智能机制。
同时也不应该为了“方便”把所有对象都设计成全局 Singleton。
例如不同 Individual 的独立 Memory,可能必须保持相互隔离:
Individual A
└── Memory A
Individual B
└── Memory B
不能错误地变成:
Global Memory
↑
├── Individual A
└── Individual B
否则不同人工个体可能产生不应该共享的内部状态。
10.8 Factory
Factory 是对象创建机制。
Container 负责:
对象管理
Factory 负责:
对象创建
例如:
class IndividualFactory
{
public function create($id, $name)
{
return new \SAI\Individual\Individual(
$id,
$name
);
}
}
使用:
$factory = new IndividualFactory();
$individual = $factory->create(
'sai_001',
'Indoor SAI'
);
于是:
Factory
│
▼
创建 Individual
│
▼
Container
│
▼
注册 Individual
可以进一步:
$container->set(
'individual',
$individual
);
完整关系:
Factory
↓
Create
↓
Object
↓
Container
↓
Manage
10.9 Service
在 Framework 工程中,经常需要长期提供某种功能的对象。
例如:
MemoryService
ReasoningService
LoggingService
ConfigurationService
这些可以作为 Service 注册到 Container。
例如:
$container->set(
'memory',
$memory
);
其他模块:
$memory = $container->get(
'memory'
);
Service 的核心并不是某个特殊 PHP 语法。
它主要表示:
一个可以被 Framework 其他模块持续使用的功能对象。
例如:
Memory
Cognition
Reasoning
Decision
都可以根据实际架构设计成为由 Container 管理的 Service。
10.10 Engine 注册
SAI Framework 中有很多 Engine。
例如:
PerceptionEngine
CognitionEngine
MemoryEngine
ReasoningEngine
DecisionEngine
BehaviorEngine
LearningEngine
Container 可以统一注册。
例如:
$container->set(
'reasoning.engine',
$reasoningEngine
);
获取:
$engine = $container->get(
'reasoning.engine'
);
完整结构:
Container
│
├── perception.engine
├── cognition.engine
├── memory.engine
├── reasoning.engine
├── decision.engine
├── behavior.engine
└── learning.engine
但是:
Engine 是执行机制,Container 只是管理 Engine。
例如:
Container
↓
ReasoningEngine
↓
执行推理
不能理解成:
Container
↓
负责推理
这是完全不同的职责。
10.11 Manager 注册
SAI Framework 还可以存在大量 Manager。
例如:
ObjectManager
RelationManager
MemoryManager
RuleManager
DeviceManager
ExtensionManager
这些 Manager 同样可以注册:
$container->set(
'object.manager',
$objectManager
);
获取:
$objectManager = $container->get(
'object.manager'
);
于是:
Container
│
├── ObjectManager
├── RelationManager
├── MemoryManager
├── RuleManager
├── DeviceManager
└── ExtensionManager
这里再次体现:
Manager
↓
负责管理某一类资源
Container
↓
负责管理 Framework 中的对象
两者不是同一个层级的概念。
10.12 Individual 注册
Individual 是 SAI Framework 最核心的运行对象之一。
例如:
$individual = new Individual(
'sai_001',
'Indoor SAI'
);
创建以后注册:
$container->set(
'individual',
$individual
);
以后其他 Framework 组件可以:
$individual = $container->get(
'individual'
);
完整关系:
Individual
│
▼
Container
│
├── Central
├── Memory
├── Cognition
├── Reasoning
├── Decision
└── Behavior
对于多 Individual 系统,则不能简单地使用一个:
individual
可能需要:
individual.sai001
individual.sai002
individual.sai003
例如:
$container->set(
'individual.sai001',
$individualA
);
$container->set(
'individual.sai002',
$individualB
);
这样:
Container
│
├── individual.sai001
│ └── Memory A
│
└── individual.sai002
└── Memory B
能够保持不同 Individual 的对象和状态边界。
10.13 Container 实际运行案例
下面建立一个简单的 SAI Framework Container 运行案例。
说明:以下是本章教程示例,用于说明 Container 的对象注册、获取和依赖管理机制;不是当前实际项目的已验证代码。
目录:
sai-container-demo/
│
├── app/
│ ├── Core/
│ │ └── Container.php
│ │
│ ├── Individual/
│ │ └── Individual.php
│ │
│ ├── Central/
│ │ └── Central.php
│ │
│ └── Memory/
│ └── Memory.php
│
├── bootstrap.php
└── index.php
10.13.1 Container
<?php
namespace SAI\Core;
class Container
{
protected $items = array();
public function set($name, $object)
{
$this->items[$name] = $object;
}
public function get($name)
{
if (isset($this->items[$name])) {
return $this->items[$name];
}
return null;
}
public function has($name)
{
return isset($this->items[$name]);
}
}
10.13.2 Memory
<?php
namespace SAI\Memory;
class Memory
{
protected $items = array();
public function remember($key, $value)
{
$this->items[$key] = $value;
}
public function recall($key)
{
if (isset($this->items[$key])) {
return $this->items[$key];
}
return null;
}
}
10.13.3 Central
<?php
namespace SAI\Central;
class Central
{
protected $state;
public function __construct()
{
$this->state = 'created';
}
public function start()
{
$this->state = 'running';
}
public function getState()
{
return $this->state;
}
}
10.13.4 Individual
<?php
namespace SAI\Individual;
class Individual
{
protected $id;
protected $name;
protected $state;
protected $memory;
public function __construct(
$id,
$name,
$memory
) {
$this->id = $id;
$this->name = $name;
$this->memory = $memory;
$this->state = 'created';
}
public function start()
{
$this->state = 'running';
}
public function remember($key, $value)
{
$this->memory->remember(
$key,
$value
);
}
public function recall($key)
{
return $this->memory->recall($key);
}
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
public function getState()
{
return $this->state;
}
}
这里出现了一个非常重要的 OOP 关系:
Individual
│
└── depends on
↓
Memory
Individual 不自己创建 Memory:
new Memory();
而是从外部传入:
$memory
这就是依赖注入的基本思想。
10.14 Bootstrap 中使用 Container
<?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;
}
});
use SAI\Core\Container;
use SAI\Memory\Memory;
use SAI\Central\Central;
use SAI\Individual\Individual;
/*
* Container
*/
$container = new Container();
/*
* Memory
*/
$memory = new Memory();
$container->set(
'memory',
$memory
);
/*
* Individual
*/
$individual = new Individual(
'sai_001',
'Indoor SAI',
$container->get('memory')
);
$container->set(
'individual',
$individual
);
/*
* Central
*/
$central = new Central();
$container->set(
'central',
$central
);
此时 Container 中已经存在:
Container
│
├── memory
│ └── Memory Object
│
├── individual
│ └── Individual Object
│
└── central
└── Central Object
10.15 运行程序
index.php:
<?php
require_once __DIR__ . '/bootstrap.php';
$individual = $container->get(
'individual'
);
$central = $container->get(
'central'
);
$individual->start();
$central->start();
$individual->remember(
'temperature',
32
);
echo '<pre>';
echo "Individual: "
. $individual->getName()
. PHP_EOL;
echo "Individual State: "
. $individual->getState()
. PHP_EOL;
echo "Central State: "
. $central->getState()
. PHP_EOL;
echo "Memory temperature: "
. $individual->recall('temperature')
. PHP_EOL;
echo '</pre>';
按照上述代码,预期结果:
Individual: Indoor SAI
Individual State: running
Central State: running
Memory temperature: 32
这里同样需要明确:
以上是根据示例代码推导出的预期输出,并非本次实际执行验证结果。
10.16 Container 的完整运行过程
把刚才的案例压缩以后:
Bootstrap
│
▼
Create Container
│
▼
Create Memory
│
▼
Register Memory
│
▼
Get Memory
│
▼
Create Individual
│
▼
Inject Memory
│
▼
Register Individual
│
▼
Create Central
│
▼
Register Central
运行以后:
Container
│
├── memory
│
├── individual
│
└── central
Individual 使用:
Individual
↓
Memory
↓
remember()
↓
recall()
这样就形成了最基本的对象依赖关系。
10.17 Container、Factory、Service、Engine、Manager 的关系
这几个概念容易混淆。
可以统一理解为:
Factory
│
│ 创建
▼
Object / Service / Engine / Manager
│
│ 注册
▼
Container
│
│ 获取
▼
Other Object
例如:
MemoryFactory
↓
Memory
↓
Container
↓
Individual
Engine:
ReasoningEngine
↓
Container
↓
Reasoning
Manager:
ObjectManager
↓
Container
↓
Object System
因此:
| 概念 | 主要职责 |
|---|---|
| Container | 管理对象 |
| Factory | 创建对象 |
| Service | 提供持续功能 |
| Engine | 执行某类核心机制 |
| Manager | 管理某类资源 |
| Individual | 模拟人工个体 |
| Central | 协调 Individual 内部模块 |
10.18 Container 在 SAI Framework 中的位置
现在把前面的 Application、Bootstrap 和 Container 连接起来:
Bootstrap
│
▼
Application
│
├── Container
│ │
│ ├── Individual
│ ├── Central
│ ├── Memory
│ ├── Cognition
│ ├── Reasoning
│ ├── Decision
│ └── Engines / Managers
│
▼
Runtime
因此:
Bootstrap
↓
Application
↓
Container
↓
SAI Objects
Container 是 Application 内部非常重要的基础设施。
但它依然不是智能本身。
10.19 Container 与 SAI 智能体系的边界
必须严格区分:
Container
解决:
对象在哪里?
而:
Cognition
解决:
信息意味着什么?
Reasoning
解决:
根据事实、关系和规则可以得到什么结论?
Decision
解决:
应该选择什么行动?
Behavior
解决:
应该执行什么行为?
因此:
Container
↓
提供 Cognition
↓
Cognition 执行认知
不是:
Container
↓
自己执行认知
这一边界对于 SAI Framework 非常重要。
本章小结
Container 是 SAI Framework 的对象与服务管理基础设施。
它解决的核心问题是:
对象创建
对象注册
对象获取
对象依赖
对象生命周期
核心操作:
set()
↓
注册对象
get()
↓
获取对象
has()
↓
判断对象是否存在
进一步可以结合:
Singleton
Factory
Service
Engine
Manager
形成:
Factory
│
创建
▼
Object
│
注册
▼
Container
│
┌──────┼──────┐
▼ ▼ ▼
Memory Central Engine
│
▼
Individual
最终形成第8、9、10章之间的关系:
Bootstrap
│
▼
Application
│
▼
Container
│
├── Individual
├── Central
├── Memory
├── Cognition
├── Reasoning
├── Decision
├── Behavior
├── Engine
└── Manager
其中:
Bootstrap 负责启动,Application 负责运行时管理,Container 负责对象管理,Individual 才是最终的模拟人工个体。
下一章进入 第11章 Request 与 Response 时,可以进一步说明:SAI Framework 如何接收外部请求、如何把请求转换为 Information,以及如何把 Individual 的 Expression/Action 转换成外部 Response。