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

第10章 Container

第10章 Container

本章大纲

  1. Container 定义
  2. 为什么需要 Container
  3. 对象注册
  4. 对象获取
  5. 依赖管理
  6. Singleton
  7. Factory
  8. Service
  9. Engine 注册
  10. Manager 注册
  11. Individual 注册
  12. 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。

Leave a Reply

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