第7章 PHP OOP 与 SAI Framework
本章大纲
- Class
- Object
- Property
- Method
- Constructor
- Inheritance
- Interface
- Abstract Class
- Trait
- Namespace
- Static
- Encapsulation
- Dependency
- Composition
- SAI 中的 OOP 使用方法
- Individual 类示例
- Object 之间的关系
7.1 Class
在 PHP OOP 中,Class 是对象的定义。
例如:
class Fan
{
protected $state;
public function turnOn()
{
$this->state = 'on';
}
}
这里:
Fan
是一个 Class。
Class 描述:
对象是什么
对象有什么属性
对象可以执行什么方法
在 SAI Framework 中,Class 是构建各种 SAI 对象的基本工程单位。
例如:
Individual
Information
Scene
Object
Memory
Cognition
Reasoning
Decision
Behavior
Device
都可以通过 Class 表达。
7.2 Object
Class 是定义,Object 是根据 Class 创建出来的实际对象。
例如:
$fan = new Fan();
此时:
Fan
↓
$fan
Fan 是 Class。
$fan 是 Object。
在 SAI 中,可以进一步表示现实世界中的对象:
Room
Fan
Person
Robot
Vehicle
Sensor
Door
Motor
例如:
$fan = new Fan();
可以形成:
Object
├── Identity
├── Property
├── State
├── Method
└── Relation
例如:
Fan
├── id = fan_001
├── speed = 3
├── state = off
└── turnOn()
因此:
OOP 让 SAI 能够把现实世界中的实体转换为可以操作的软件对象。
7.3 Property
Property 是对象的属性。
例如:
class Fan
{
protected $state;
protected $speed;
protected $direction;
}
这里:
state
speed
direction
都是 Property。
在 SAI 中,Property 可以描述:
对象特征
对象状态
对象参数
对象位置
对象能力参数
例如:
Fan
├── state = off
├── speed = 3
└── direction = left
温度传感器:
TemperatureSensor
├── value = 32
├── unit = C
└── state = active
机器人:
Robot
├── position
├── speed
├── direction
├── energy
└── state
因此 SAI 的 Object + Property 可以形成对现实对象的结构化描述。
7.4 Method
Method 是对象可以执行的操作。
例如:
class Fan
{
public function turnOn()
{
// 开启风扇
}
public function turnOff()
{
// 关闭风扇
}
}
这里:
turnOn()
turnOff()
就是 Method。
在 SAI 中:
Object
↓
Method
↓
Action
例如:
Fan.turnOn()
Robot.move()
Door.open()
Motor.stop()
Light.setBrightness()
Method 不只是普通函数。
从 SAI 的对象模型看,它表达的是:
某个对象能够执行什么操作。
7.5 Constructor
Constructor 是对象创建时自动执行的方法。
PHP 中使用:
__construct()
例如:
class Fan
{
protected $id;
protected $state;
public function __construct($id)
{
$this->id = $id;
$this->state = 'off';
}
}
创建对象:
$fan = new Fan('fan_001');
自动执行:
__construct()
于是对象初始化:
Fan
├── id = fan_001
└── state = off
在 SAI 中 Constructor 可以用于初始化:
Identity
State
Property
Dependency
Configuration
7.6 Inheritance
Inheritance 是继承。
例如:
class Device
{
protected $id;
public function start()
{
// 启动
}
}
然后:
class Fan extends Device
{
public function turnOn()
{
// 开启
}
}
此时:
Device
↑
│
Fan
Fan 可以继承 Device 的公共和受保护成员。
在 SAI 中可以形成:
Device
├── Sensor
├── Motor
├── Fan
├── Robot
└── Machine
或者:
Information
├── TextInformation
├── StateInformation
├── SensorInformation
└── DeviceInformation
继承适合表达:
“A 是一种 B”
例如:
Fan is a Device
Robot is a Device
TemperatureSensor is a Device
但不应该为了继承而继承。
如果两个对象只是存在关联,而不是“是一种”,通常应该使用 Composition 或 Dependency。
7.7 Interface
Interface 定义一个类必须提供什么能力。
例如:
interface RendererInterface
{
public function render($data);
}
Web Renderer:
class WebRenderer implements RendererInterface
{
public function render($data)
{
return '<html>' . $data . '</html>';
}
}
API Renderer:
class ApiRenderer implements RendererInterface
{
public function render($data)
{
return json_encode($data);
}
}
两者虽然实现不同,但都有:
render()
因此:
RendererInterface
│
┌─────┴─────┐
▼ ▼
WebRenderer ApiRenderer
在 SAI 中 Interface 很重要,因为它可以规定模块之间的共同能力。
例如:
EngineInterface
RendererInterface
AdapterInterface
MemoryInterface
CollectorInterface
这样可以让框架保持开放性。
7.8 Abstract Class
Abstract Class 是抽象类。
它可以定义公共结构,同时把部分实现交给子类。
例如:
abstract class Engine
{
protected $name;
public function getName()
{
return $this->name;
}
abstract public function run($input);
}
具体 Engine:
class ReasoningEngine extends Engine
{
public function run($input)
{
return 'reasoning';
}
}
关系:
Engine
│
├── ReasoningEngine
├── CognitionEngine
├── MemoryEngine
└── LearningEngine
Abstract Class 与 Interface 的区别可以简单理解为:
Interface
↓
规定能力
Abstract Class
↓
规定共同结构 + 部分实现
例如:
RendererInterface
可以规定所有 Renderer 都必须有:
render()
而:
abstract class Engine
则可以提供所有 Engine 的公共基础。
7.9 Trait
Trait 用于在多个 Class 之间复用方法。
例如:
trait LoggerTrait
{
public function log($message)
{
echo $message;
}
}
然后:
class MemoryEngine
{
use LoggerTrait;
}
另一个类:
class ReasoningEngine
{
use LoggerTrait;
}
于是:
LoggerTrait
│
┌──┴──────────┐
▼ ▼
MemoryEngine ReasoningEngine
Trait 适合处理一些横向公共能力,例如:
Logging
Validation
EventDispatching
ConfigurationAccess
IdentityAccess
但是 Trait 不应该成为 SAI 的主要架构方式。
SAI 的核心结构仍然应该依靠:
Class
Object
Interface
Abstract Class
Composition
Dependency
来组织。
7.10 Namespace
Namespace 用来组织 Class。
例如:
namespace SAI\Cognition;
class Cognition
{
}
使用:
use SAI\Cognition\Cognition;
$cognition = new Cognition();
SAI Framework 中可以按照模块划分 Namespace:
SAI\Core
SAI\Information
SAI\Scene
SAI\Individual
SAI\Central
SAI\Cognition
SAI\Memory
SAI\Reasoning
SAI\Decision
SAI\Behavior
SAI\Template
SAI\Renderer
SAI\Adapter
SAI\Device
SAI\Feedback
SAI\Experience
SAI\Learning
SAI\Maintenance
这样可以避免大量 Class 名称冲突。
例如:
SAI\Memory\Memory
SAI\Experience\Experience
SAI\Device\Device
分别属于不同模块。
7.11 Static
static 表示属于 Class 本身,而不是某个具体 Object。
例如:
class SAI
{
protected static $version = '0.1.0';
public static function version()
{
return self::$version;
}
}
可以直接:
echo SAI::version();
而不需要:
$sai = new SAI();
Static 可以用于:
配置
常量式信息
工具方法
全局注册信息
类级别状态
但是 SAI 的 Individual、Object、Memory、Cognition 等核心对象不应该大量依赖 Static。
因为:
Individual A
和:
Individual B
应该能够拥有不同的:
State
Memory
Ability
Experience
如果全部使用 Static,就容易变成:
所有 Individual
↓
共享同一份状态
这与人工个体的独立性不符合。
所以:
SAI 核心对象优先使用实例对象,而不是大量使用 Static。
7.12 Encapsulation
Encapsulation 是封装。
例如:
class Fan
{
protected $state = 'off';
public function turnOn()
{
$this->state = 'on';
}
public function getState()
{
return $this->state;
}
}
外部不能直接修改:
$fan->state = 'on';
而应该:
$fan->turnOn();
这样:
外部
↓
Public Method
↓
Object
↓
Protected Property
对象自己控制自己的状态。
在 SAI 中这一点非常重要。
例如:
Memory
Cognition
Decision
Device
Individual
都应该尽可能维护自己的内部状态。
这可以避免:
任何模块
↓
随意修改
↓
其他模块内部状态
7.13 Dependency
Dependency 是依赖。
例如:
class ReasoningEngine
{
protected $ruleEngine;
public function __construct($ruleEngine)
{
$this->ruleEngine = $ruleEngine;
}
}
这里:
ReasoningEngine
↓
RuleEngine
就是依赖。
ReasoningEngine 需要 RuleEngine 才能工作。
SAI 中会存在大量这种关系:
CognitionEngine
↓
Memory
ReasoningEngine
↓
RuleEngine
LearningEngine
↓
ExperienceMemory
BehaviorEngine
↓
Adapter
Dependency Injection 可以让依赖从外部传入:
$reasoning = new ReasoningEngine($ruleEngine);
这样比在类内部直接:
$this->ruleEngine = new RuleEngine();
更加灵活。
7.14 Composition
Composition 是组合。
它表示:
一个对象由其他对象组成。
例如:
class Individual
{
protected $memory;
protected $cognition;
protected $behavior;
public function __construct(
$memory,
$cognition,
$behavior
) {
$this->memory = $memory;
$this->cognition = $cognition;
$this->behavior = $behavior;
}
}
于是:
Individual
├── Memory
├── Cognition
└── Behavior
这就是 Composition。
SAI Framework 非常适合使用 Composition。
因为 Individual 本身就是一个由多个能力模块组成的整体:
Individual
│
├── Identity
├── State
├── Ability
├── Memory
├── Cognition
├── Learning
└── Behavior
7.15 SAI 中的 OOP 使用方法
SAI 不应该简单地把每一个概念都变成一个 Class,然后让 Class 之间毫无关系。
正确的方法是:
现实概念
↓
SAI 概念
↓
Class
↓
Object
↓
Property / Method
↓
Relation
例如现实世界:
一台风扇
SAI 可以描述为:
Object: Fan
属性:
state
speed
direction
方法:
turnOn()
turnOff()
setSpeed()
关系:
Fan
└── locatedIn → Room
于是:
Fan Object
├── Property
├── State
├── Method
└── Relation
7.16 SAI 的 OOP 分层
SAI Framework 可以形成下面的 OOP 层次:
Individual
│
┌────────┴────────┐
▼ ▼
Central Ability
│
┌───────┼────────┐
▼ ▼ ▼
Cognition Memory Reasoning
│ │ │
└───────┼────────┘
▼
Decision
│
▼
Behavior
│
▼
Action
对象层:
Element
↓
Object
├── Property
├── State
├── Method
└── Relation
基础工程层:
Class
Interface
Abstract Class
Trait
Namespace
Dependency
Composition
这些共同构成 SAI 的 OOP 基础。
7.17 Individual 类示例
下面建立一个教程示例,说明如何使用 PHP OOP 表达一个 SAI Individual。
这个例子是架构示例,并不表示当前已经实际创建或运行验证。
<?php
namespace SAI\Individual;
class Individual
{
protected $id;
protected $name;
protected $state;
protected $memory;
protected $cognition;
protected $behavior;
public function __construct(
$id,
$name,
$memory = null,
$cognition = null,
$behavior = null
) {
$this->id = $id;
$this->name = $name;
$this->state = 'created';
$this->memory = $memory;
$this->cognition = $cognition;
$this->behavior = $behavior;
}
public function start()
{
$this->state = 'running';
}
public function stop()
{
$this->state = 'stopped';
}
public function getId()
{
return $this->id;
}
public function getName()
{
return $this->name;
}
public function getState()
{
return $this->state;
}
public function getMemory()
{
return $this->memory;
}
public function getCognition()
{
return $this->cognition;
}
public function getBehavior()
{
return $this->behavior;
}
}
创建:
$individual = new \SAI\Individual\Individual(
'sai_001',
'Indoor SAI'
);
启动:
$individual->start();
此时对象可以表示:
Individual
├── id = sai_001
├── name = Indoor SAI
├── state = running
├── memory
├── cognition
└── behavior
7.18 为 Individual 增加 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;
}
}
创建:
$memory = new \SAI\Memory\Memory();
$memory->remember(
'room_temperature',
32
);
然后注入 Individual:
$individual = new \SAI\Individual\Individual(
'sai_001',
'Indoor SAI',
$memory
);
形成:
Individual
│
▼
Memory
│
└── room_temperature = 32
这就是 Composition + Dependency Injection 的结合。
7.19 Object 之间的关系
SAI 不仅仅需要 Object,还需要 Object 之间的 Relation。
例如:
Room
Fan
Person
TemperatureSensor
可以形成:
Fan
└── locatedIn → Room
Person
└── locatedIn → Room
TemperatureSensor
└── installedIn → Room
进一步:
Room
├── contains → Fan
├── contains → Person
└── contains → TemperatureSensor
可以抽象为:
Subject
│
│ Relation
▼
Object
例如:
Fan
│
└── locatedIn
│
▼
Room
在 PHP 中,可以设计一个 Relation:
class Relation
{
protected $subject;
protected $type;
protected $object;
public function __construct(
$subject,
$type,
$object
) {
$this->subject = $subject;
$this->type = $type;
$this->object = $object;
}
public function getSubject()
{
return $this->subject;
}
public function getType()
{
return $this->type;
}
public function getObject()
{
return $this->object;
}
}
创建关系:
$relation = new Relation(
'fan_001',
'locatedIn',
'room_001'
);
得到:
fan_001
│
│ locatedIn
▼
room_001
7.20 Object、Property、Method、Relation 的统一结构
这样,SAI 的对象模型就可以统一起来:
Object
│
┌──────────────┼──────────────┐
│ │ │
▼ ▼ ▼
Property Method Relation
│ │ │
▼ ▼ ▼
描述对象 操作对象 连接对象
例如:
Fan
│
├── Property
│ ├── speed = 3
│ └── direction = left
│
├── State
│ └── state = off
│
├── Method
│ ├── turnOn()
│ └── turnOff()
│
└── Relation
└── locatedIn → Room
这正是 SAI 使用 OOP 的核心方式之一。
7.21 OOP 与 SAI 生命周期
PHP OOP 最终不是独立存在的。
它要服务于 SAI 生命周期:
Class
↓
Object
↓
Information
↓
Element
↓
Object
↓
Relation
↓
Cognition
↓
Memory
↓
Reasoning
↓
Decision
↓
Behavior
↓
Action
↓
Feedback
↓
Experience
↓
Learning
例如:
TemperatureSensor
是一个 Object。
它产生:
Information
信息经过:
Perception
形成:
Element
然后映射到:
Room.temperature
形成:
Object + Property
再通过:
Relation
Rule
Fact
进入:
Cognition
Reasoning
Decision
最终调用:
Behavior
↓
Action
↓
Device Method
因此 OOP 是 SAI 的工程表达基础,而不是 SAI 的全部。
7.22 本章完整示例:一个室内 SAI
假设:
Individual = IndoorSAI
对象:
Room
Fan
Person
TemperatureSensor
对象关系:
TemperatureSensor
│
└── installedIn → Room
Fan
└── locatedIn → Room
Person
└── locatedIn → Room
属性:
Room.temperature = 32
Person.state = PRESENT
Fan.state = OFF
方法:
Fan.turnOn()
Fan.turnOff()
规则:
IF
Room.temperature > 30
AND
Person.state = PRESENT
AND
Fan.state = OFF
THEN
Fan.turnOn()
完整运行:
TemperatureSensor
│
▼
Information
│
▼
Perception
│
▼
Element
│
▼
Object
│
▼
Property
│
▼
Relation
│
▼
Cognition
│
▼
Memory
│
▼
Reasoning
│
▼
Decision
│
▼
Behavior
│
▼
Action
│
▼
Fan.turnOn()
│
▼
Fan.state=ON
│
▼
Feedback
│
▼
Experience
│
▼
Learning
7.23 本章核心 OOP 关系图
Class
│
▼
Object
│
┌───────────┼───────────┐
▼ ▼ ▼
Property Method Relation
│ │ │
▼ ▼ ▼
State Action Object
Class 的组织方式:
│
├── Inheritance
├── Interface
├── Abstract Class
├── Trait
├── Namespace
├── Encapsulation
├── Dependency
└── Composition
SAI 的核心:
Individual
│
┌──────────────┼──────────────┐
▼ ▼ ▼
Cognition Memory Behavior
│ │ │
└──────────────┼──────────────┘
▼
Central
│
▼
Objects
│
┌──────────┼──────────┐
▼ ▼ ▼
Property Method Relation
本章小结
PHP OOP 是 SAI Framework 的重要工程基础。
本章可以归纳为:
Class
↓
定义对象
Object
↓
实际对象
Property
↓
对象特征
Method
↓
对象操作
Constructor
↓
对象初始化
Inheritance
↓
建立“是一种”关系
Interface
↓
规定共同能力
Abstract Class
↓
规定共同基础结构
Trait
↓
复用横向能力
Namespace
↓
组织模块
Static
↓
类级别能力
Encapsulation
↓
保护对象内部状态
Dependency
↓
建立模块依赖
Composition
↓
组合复杂对象
而在 SAI Framework 中,这些 OOP 能力最终统一服务于:
Information
↓
Element
↓
Object
↓
Property
↓
Relation
↓
Cognition
↓
Memory
↓
Reasoning
↓
Decision
↓
Behavior
↓
Action
↓
Feedback
↓
Experience
↓
Learning
最重要的一点是:
SAI Framework 不是为了展示 PHP OOP,而是利用 PHP OOP 把“模拟人工个体”的结构、对象、属性、关系、方法、能力和生命周期真正组织成可工程化的软件系统。
其中 Individual 是最终对象,Object 是世界建模基础,Property 描述对象,Method 表示对象能力,Relation 连接对象,而 Composition、Dependency、Interface 和 Abstract Class 则负责把这些对象组织成一个完整的 SAI Framework。