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

第217章 StateRepository

第217章 StateRepository

217.1 StateRepository定义

在第216章中,ObjectRepository 负责 Object 的保存、查询、更新和删除。

但是 Object 的状态具有独立的生命周期、变化过程和历史记录,因此不能简单地把 State 当成 Object 的一个普通字段处理。

前面的 StateEngine 已经定义:

S=(O,V,T,C,R)S=(O,V,T,C,R)

其中:

  • OO:Owner,状态所属对象;
  • VV:Value,状态值;
  • TT:Time,状态时间;
  • CC:Context,状态上下文;
  • RR:Reason,状态产生原因。

StateRepository 的职责,是负责这些已经确定的状态事实进行持久化、查询以及历史保存。

因此:

StateRepository=StateSave+StateQuery+StateHistory+StateUpdate\boxed{ StateRepository = StateSave + StateQuery + StateHistory + StateUpdate }

其工程模型可以表示为:

SR=(S,M,Q,H,U,P,T)SR=(S,M,Q,H,U,P,T)

其中:

  • SS:State;
  • MM:Mapping;
  • QQ:Query;
  • HH:History;
  • UU:Update;
  • PP:Persistence;
  • TT:Time。

217.2 StateRepository与StateEngine

必须首先明确两者的边界。

StateEngine 负责:

状态计算
状态判断
状态转换计算
状态规则验证
状态候选生成

StateRepository 负责:

状态保存
状态查询
状态历史保存
状态更新
状态读取

因此:

StateEngine=State CalculationStateEngine=State\ Calculation

而:

StateRepository=State PersistenceStateRepository=State\ Persistence

正确结构:

Event
  ↓
StateEngine
  ↓
Candidate State
  ↓
Validate
  ↓
Verify
  ↓
UpdateEngine
  ↓
StateRepository
  ↓
MySQL

不能变成:

StateRepository
      ↓
自己判断
ready → active

因为:

Repository≠StateEngineRepository \neq StateEngine

Repository 保存已经计算和确认的状态结果。


217.3 当前状态与状态历史

这是 StateRepository 最核心的设计。

必须明确:

CurrentState≠StateHistoryCurrentState \neq StateHistory

当前状态回答:

对象现在是什么状态?

状态历史回答:

对象过去经历过哪些状态变化?

例如一个 Object:

O-001
Current State = active

其历史可能是:

created
   ↓
ready
   ↓
active
   ↓
blocked
   ↓
active

因此:

Current State

只保存:

而:

State History

保存整个变化过程。


217.4 当前状态模型

当前状态:

St=(O,V,T,C,R)S_t=(O,V,T,C,R)

其中:

  • OO:状态所属对象;
  • VV:当前状态值;
  • TT:当前状态时间;
  • CC:当前状态上下文;
  • RR:当前状态原因。

例如:

$state = array(
    'object_id' => 1001,
    'value' => 'active',
    'time' => time(),
    'context' => 'normal_operation',
    'reason' => 'activation_verified'
);

StateRepository 可以把它保存为当前状态。


217.5 状态历史模型

状态历史记录的是状态事件。

可以定义:

SH=(O,Sb,Sc,E,R,T)SH=(O,S_b,S_c,E,R,T)

其中:

  • OO:对象;
  • SbS_b:Before State,变化前状态;
  • ScS_c:Changed State,变化后的状态;
  • EE:Event,触发事件;
  • RR:Reason,变化原因;
  • TT:Time,变化时间。

例如:

ready→activationactiveready \xrightarrow{activation} active

对应:

object_id = 1001
before_state = ready
after_state = active
event = activation
reason = verified_condition
time = ...

因此:

StateHistory=StateChangeFactsStateHistory = StateChangeFacts

而不是简单地把当前状态复制多份。


217.6 状态保存

状态保存流程:

State
 ↓
Validate
 ↓
Map
 ↓
Persist Current State
 ↓
Create History
 ↓
Verify

公式:

Save(S)→Validate→Persist→History→VerifySave(S) \rightarrow Validate \rightarrow Persist \rightarrow History \rightarrow Verify

这里存在两个不同的持久化动作:

CurrentStateSaveCurrentStateSave

和:

StateHistorySaveStateHistorySave

二者不能混为一谈。


217.7 状态保存的原子性

状态发生变化时:

ready → active

至少需要考虑:

更新当前状态
+
记录状态变化历史

理想事务:

Begin→UpdateCurrentState→InsertHistory→Verify→CommitBegin \rightarrow UpdateCurrentState \rightarrow InsertHistory \rightarrow Verify \rightarrow Commit

如果当前状态已经更新,但是历史没有保存,就会形成:

Current State = active
History = missing

这样系统会失去状态变化的可追踪性。

因此:

CurrentStateUpdate+HistoryRecordCurrentStateUpdate + HistoryRecord

应该尽可能处于同一个数据库事务中。


217.8 状态查询

StateRepository 的查询不是状态计算。

基本查询模型:

Query(C)→{S}Query(C)\rightarrow\{S\}

其中 CC 是查询条件。

常见查询包括:

按照对象查询
按照状态值查询
按照时间查询
按照状态类型查询
按照上下文查询
按照状态ID查询

217.9 按对象查询当前状态

最常用:

findCurrentByObjectId(OID)→SfindCurrentByObjectId(OID)\rightarrow S

例如:

public function findCurrentByObjectId($objectId)
{
    $sql = "
        SELECT *
        FROM states
        WHERE object_id = :object_id
        AND is_current = 1
        LIMIT 1
    ";

    $stmt = $this->pdo->prepare($sql);

    $stmt->execute(array(
        ':object_id' => $objectId
    ));

    $data = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$data) {
        return null;
    }

    return $this->mapper->toDomain($data);
}

需要注意:

is_current 只是示例字段。

真实工程必须以实际数据库结构为准。


217.10 按状态值查询

例如查询所有:

active

状态:

findByValue(V)→{S}findByValue(V)\rightarrow\{S\}

public function findByValue($value)
{
    $sql = "
        SELECT *
        FROM states
        WHERE value = :value
        ORDER BY id ASC
    ";

    $stmt = $this->pdo->prepare($sql);

    $stmt->execute(array(
        ':value' => $value
    ));

    $states = array();

    while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $states[] = $this->mapper->toDomain($data);
    }

    return $states;
}

这只是查询。

是否允许:

ready → active

不是 Repository 决定的。


217.11 按时间查询状态

状态具有时间属性,因此可以查询:

Query(O,T1,T2)→{S}Query(O,T_1,T_2) \rightarrow \{S\}

例如:

public function findByTimeRange($objectId, $startTime, $endTime)
{
    $sql = "
        SELECT *
        FROM state_history
        WHERE object_id = :object_id
        AND changed_at >= :start_time
        AND changed_at <= :end_time
        ORDER BY changed_at ASC
    ";

    $stmt = $this->pdo->prepare($sql);

    $stmt->execute(array(
        ':object_id' => $objectId,
        ':start_time' => $startTime,
        ':end_time' => $endTime
    ));

    $history = array();

    while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $history[] = $this->historyMapper->toDomain($data);
    }

    return $history;
}

时间查询对于:

Diagnosis
Experience
Risk
Learning

都非常重要。


217.12 状态历史保存

状态变化:

St→St+1S_t\rightarrow S_{t+1}

必须可以形成历史:

Ht+1=Ht+ΔSH_{t+1} = H_t+\Delta S

其中:

  • HtH_t:当前状态历史;
  • ΔS\Delta S:本次状态变化;
  • Ht+1H_{t+1}:更新后的历史。

例如:

ready
 ↓
active

记录:

before = ready
after = active
event = activate
reason = condition_verified

217.13 状态历史不能被当前状态覆盖

错误结构:

states
    id = 1
    value = active

然后每次:

ready
↓
active
↓
blocked

都覆盖同一条记录。

这样最终只剩:

blocked

系统不知道:

之前是否 active?
什么时候 active?
为什么 blocked?

因此必须分离:

Current State
+
State History

217.14 状态更新

状态更新模型:

St+ΔS→St+1S_t+\Delta S\rightarrow S_{t+1}

但是 StateRepository 不负责计算 ΔS\Delta S

正确过程:

Event
 ↓
StateEngine
 ↓
State Transition
 ↓
Candidate State
 ↓
Verification
 ↓
UpdateEngine
 ↓
StateRepository
 ↓
Current State + History

因此 Repository 接收到的应该是:

Confirmed State Change

而不是一个未经计算的事件,让 Repository 自己决定状态。


217.15 状态更新实例

当前:

St=readyS_t=ready

事件:

E=activationE=activation

StateEngine 计算:

T(ready,activation,C,Ru)→activeT(ready,activation,C,Ru)\rightarrow active

得到:

St+1=activeS_{t+1}=active

然后:

UpdateEngine
      ↓
StateRepository
      ├── Current State = active
      └── History = ready → active

这样状态计算和状态持久化完全分离。


217.16 状态更新验证

更新之后不能只判断:

UPDATE执行成功

应该验证:

VerifiedStateUpdate=CurrentStateMatch∧HistoryExists∧IdentityMatchVerifiedStateUpdate = CurrentStateMatch \land HistoryExists \land IdentityMatch

也就是:

更新当前状态
       ↓
重新读取
       ↓
确认新状态
       ↓
读取历史
       ↓
确认状态变化记录
       ↓
Verification

217.17 StateRepository PHP接口

兼容 PHP 5.6 / PHP 7:

<?php

interface StateRepositoryInterface
{
    public function findById($id);

    public function findCurrentByObjectId($objectId);

    public function findByObjectId($objectId);

    public function findByValue($value);

    public function findHistoryByObjectId($objectId);

    public function save($state);

    public function update($state);

    public function saveHistory($history);
}

这里明确把:

Current State

与:

State History

作为不同 Repository 数据操作。


217.18 StateMapper

StateMapper:

State↔PersistenceDataState \leftrightarrow PersistenceData

例如:

<?php

class StateMapper
{
    public function toPersistence($state)
    {
        return array(
            'id' => $state->getId(),
            'object_id' => $state->getObjectId(),
            'value' => $state->getValue(),
            'context' => $state->getContext(),
            'reason' => $state->getReason(),
            'state_time' => $state->getTime()
        );
    }

    public function toDomain($data)
    {
        $state = new State();

        $state->setId($data['id']);
        $state->setObjectId($data['object_id']);
        $state->setValue($data['value']);
        $state->setContext($data['context']);
        $state->setReason($data['reason']);
        $state->setTime($data['state_time']);

        return $state;
    }
}

Mapper 不负责状态转换。


217.19 StateHistoryMapper

状态历史应该有独立 Mapper:

<?php

class StateHistoryMapper
{
    public function toPersistence($history)
    {
        return array(
            'object_id' => $history->getObjectId(),
            'before_state' => $history->getBeforeState(),
            'after_state' => $history->getAfterState(),
            'event' => $history->getEvent(),
            'reason' => $history->getReason(),
            'changed_at' => $history->getTime()
        );
    }

    public function toDomain($data)
    {
        $history = new StateHistory();

        $history->setObjectId($data['object_id']);
        $history->setBeforeState($data['before_state']);
        $history->setAfterState($data['after_state']);
        $history->setEvent($data['event']);
        $history->setReason($data['reason']);
        $history->setTime($data['changed_at']);

        return $history;
    }
}

这样:

StateMapper≠StateHistoryMapperStateMapper \neq StateHistoryMapper


217.20 StateRepository基本实现

<?php

class MySQLStateRepository implements StateRepositoryInterface
{
    protected $pdo;
    protected $mapper;
    protected $historyMapper;

    public function __construct(
        PDO $pdo,
        StateMapper $mapper,
        StateHistoryMapper $historyMapper
    ) {
        $this->pdo = $pdo;
        $this->mapper = $mapper;
        $this->historyMapper = $historyMapper;
    }

    public function findById($id)
    {
        $sql = "
            SELECT *
            FROM states
            WHERE id = :id
            LIMIT 1
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':id' => $id
        ));

        $data = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$data) {
            return null;
        }

        return $this->mapper->toDomain($data);
    }

    public function findCurrentByObjectId($objectId)
    {
        $sql = "
            SELECT *
            FROM states
            WHERE object_id = :object_id
            AND is_current = 1
            LIMIT 1
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':object_id' => $objectId
        ));

        $data = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$data) {
            return null;
        }

        return $this->mapper->toDomain($data);
    }

    public function findByObjectId($objectId)
    {
        $sql = "
            SELECT *
            FROM states
            WHERE object_id = :object_id
            ORDER BY state_time ASC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':object_id' => $objectId
        ));

        $states = array();

        while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
            $states[] = $this->mapper->toDomain($data);
        }

        return $states;
    }

    public function findByValue($value)
    {
        $sql = "
            SELECT *
            FROM states
            WHERE value = :value
            ORDER BY id ASC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':value' => $value
        ));

        $states = array();

        while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
            $states[] = $this->mapper->toDomain($data);
        }

        return $states;
    }

    public function findHistoryByObjectId($objectId)
    {
        $sql = "
            SELECT *
            FROM state_history
            WHERE object_id = :object_id
            ORDER BY changed_at ASC
        ";

        $stmt = $this->pdo->prepare($sql);

        $stmt->execute(array(
            ':object_id' => $objectId
        ));

        $history = array();

        while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
            $history[] = $this->historyMapper->toDomain($data);
        }

        return $history;
    }

    public function save($state)
    {
        $data = $this->mapper->toPersistence($state);

        $sql = "
            INSERT INTO states
            (
                id,
                object_id,
                value,
                context,
                reason,
                state_time,
                is_current
            )
            VALUES
            (
                :id,
                :object_id,
                :value,
                :context,
                :reason,
                :state_time,
                1
            )
        ";

        $stmt = $this->pdo->prepare($sql);

        return $stmt->execute(array(
            ':id' => $data['id'],
            ':object_id' => $data['object_id'],
            ':value' => $data['value'],
            ':context' => $data['context'],
            ':reason' => $data['reason'],
            ':state_time' => $data['state_time']
        ));
    }

    public function update($state)
    {
        $data = $this->mapper->toPersistence($state);

        $sql = "
            UPDATE states
            SET
                value = :value,
                context = :context,
                reason = :reason,
                state_time = :state_time
            WHERE id = :id
        ";

        $stmt = $this->pdo->prepare($sql);

        return $stmt->execute(array(
            ':id' => $data['id'],
            ':value' => $data['value'],
            ':context' => $data['context'],
            ':reason' => $data['reason'],
            ':state_time' => $data['state_time']
        ));
    }

    public function saveHistory($history)
    {
        $data = $this->historyMapper->toPersistence($history);

        $sql = "
            INSERT INTO state_history
            (
                object_id,
                before_state,
                after_state,
                event,
                reason,
                changed_at
            )
            VALUES
            (
                :object_id,
                :before_state,
                :after_state,
                :event,
                :reason,
                :changed_at
            )
        ";

        $stmt = $this->pdo->prepare($sql);

        return $stmt->execute(array(
            ':object_id' => $data['object_id'],
            ':before_state' => $data['before_state'],
            ':after_state' => $data['after_state'],
            ':event' => $data['event'],
            ':reason' => $data['reason'],
            ':changed_at' => $data['changed_at']
        ));
    }
}

上述字段中的 is_currentstate_time 等属于示例数据库字段,真正实现时必须根据项目实际数据库结构调整。


217.21 状态更新的完整事务实现

状态更新最重要的不是单独 UPDATE,而是:

CurrentState+HistoryCurrentState + History

保持一致。

例如:

public function updateStateWithHistory($state, $history)
{
    try {

        $this->pdo->beginTransaction();

        $updated = $this->update($state);

        if (!$updated) {
            throw new Exception('state update failed');
        }

        $saved = $this->saveHistory($history);

        if (!$saved) {
            throw new Exception('state history save failed');
        }

        $this->pdo->commit();

        return true;

    } catch (Exception $e) {

        if ($this->pdo->inTransaction()) {
            $this->pdo->rollBack();
        }

        return false;
    }
}

其逻辑:

Begin→UpdateState→SaveHistory→CommitBegin \rightarrow UpdateState \rightarrow SaveHistory \rightarrow Commit

失败:

Failure→RollbackFailure \rightarrow Rollback

这样避免:

状态已经变了
但历史没有保存

217.22 状态历史是认知数据的重要来源

State History 不只是日志。

它可以作为后续:

MemoryEngine
ExperienceEngine
RiskEngine
DiagnosisEngine
LearningEngine

的事实输入。

例如:

ready
↓
active
↓
blocked
↓
active

DiagnosisEngine 可以分析:

blocked发生前发生了什么?

ExperienceEngine 可以形成:

某条件下容易进入 blocked 状态

RiskEngine 可以根据历史统计:

某条件下发生异常的频率

LearningEngine 可以形成:

新的状态转换经验

因此:

StateHistory→Memory/Experience/LearningStateHistory \rightarrow Memory/Experience/Learning

但是 StateRepository 本身不负责这些认知计算。


217.23 状态历史与Memory的区别

必须避免:

StateHistory=MemoryStateHistory=Memory

两者完全不同。

StateHistory:

事实:
对象什么时候从什么状态变成什么状态

Memory:

保留:
哪些过去信息值得未来调用

因此:

StateHistory→MemoryCandidate→MemoryEngineStateHistory \rightarrow MemoryCandidate \rightarrow MemoryEngine

而不是:

StateRepository=MemoryEngineStateRepository = MemoryEngine


217.24 状态历史与Experience的区别

同样:

StateHistory≠ExperienceStateHistory \neq Experience

历史:

ready → active
active → blocked
blocked → active

经验:

某类条件下,资源不足时对象更容易进入blocked状态。

经验已经是结构化模式。

因此:

History→Memory→Comparison→Pattern→ExperienceHistory \rightarrow Memory \rightarrow Comparison \rightarrow Pattern \rightarrow Experience

Repository 只保存历史事实。


217.25 状态查询与状态判断

查询:

QueryState(O)→SQueryState(O) \rightarrow S

判断:

EvaluateState(O,C,Ru)→StateResultEvaluateState(O,C,Ru) \rightarrow StateResult

前者属于 Repository。

后者属于 StateEngine。

例如:

StateRepository
    ↓
读取 state = blocked

然后:

StateEngine
    ↓
判断 blocked 是否允许执行当前 Method

这两个过程必须分离。


217.26 状态更新与ObjectRepository

ObjectRepository 可以保存 Object:

Object O-001

StateRepository 保存 State:

State S-001

二者关系:

ObjectRepository
      ↓
Object
      ↓
StateRepository
      ↓
Current State

但 State 的计算过程:

Object
 ↓
Event
 ↓
StateEngine
 ↓
Candidate State
 ↓
Verification

不能交给 ObjectRepository 或 StateRepository 完成。


217.27 状态Repository与UpdateEngine

完整更新路径:

Feedback
   ↓
StateEngine
   ↓
State Change Candidate
   ↓
Verification
   ↓
UpdateEngine
   ↓
StateRepository
   ↓
Current State + State History

因此:

StateEngine=CalculateStateEngine = Calculate UpdateEngine=ApplyUpdateEngine = Apply StateRepository=PersistStateRepository = Persist

形成明确的三层边界:

StateEngine→UpdateEngine→StateRepository\boxed{ StateEngine \rightarrow UpdateEngine \rightarrow StateRepository }


217.28 状态持久化数据库结构

基础状态表可以设计为:

CREATE TABLE states (
    id INT NOT NULL AUTO_INCREMENT,
    object_id INT NOT NULL,
    value VARCHAR(100) NOT NULL,
    context TEXT,
    reason TEXT,
    state_time DATETIME NOT NULL,
    is_current TINYINT(1) NOT NULL DEFAULT 1,
    PRIMARY KEY (id)
);

历史表:

CREATE TABLE state_history (
    id INT NOT NULL AUTO_INCREMENT,
    object_id INT NOT NULL,
    before_state VARCHAR(100),
    after_state VARCHAR(100) NOT NULL,
    event VARCHAR(100),
    reason TEXT,
    changed_at DATETIME NOT NULL,
    PRIMARY KEY (id)
);

实际工程中,如果项目已经存在 State 表,应优先适配已有结构,而不是直接创建新的同名表。


217.29 当前状态唯一性

如果采用:

is_current = 1

表示当前状态,则同一个对象原则上只能有一个当前状态。

可以定义:

CurrentStateCount(O)≤1CurrentStateCount(O)\leq1

如果出现:

O-001 → active
O-001 → blocked

两条记录同时标记当前,就产生数据冲突。

这种冲突应该由:

Database Constraint

以及:

Repository Validation

共同防止。


217.30 状态更新的并发问题

状态更新还存在一个重要问题:

Process A
读取 ready

Process B
读取 ready

A → active
B → blocked

如果没有并发控制,就可能产生:

A覆盖B

或者:

B覆盖A

因此需要考虑:

VersionVersion

或:

UpdatedAtUpdatedAt

进行并发验证。

例如:

Current Version = 5

更新要求:

WHERE id = ? AND version = 5

更新成功后:

version = 6

如果版本已经变化:

Update Conflict

就不能直接覆盖。

这类持久化冲突属于 Repository/Infrastructure 层需要处理的问题,而不是由 StateEngine 假设数据库永远没有并发。


217.31 状态删除问题

虽然本章重点不是删除,但状态数据具有特殊性。

当前状态通常不应该被简单物理删除。

因为:

CurrentState→HistoryCurrentState \rightarrow History

如果删除当前状态,却没有明确新的状态,就可能产生:

Object exists
State missing

因此通常应该采用:

State Active
   ↓
State Inactive
   ↓
Archive

而不是直接:

DELETE

对于历史状态尤其应该:

History≠DisposableDataHistory \neq DisposableData


217.32 StateRepository完整工程关系

最终形成:

Controller
     ↓
StateService
     ↓
StateEngine
     ↓
UpdateEngine
     ↓
StateRepository
     ↓
MySQL

读取:

Controller
     ↓
StateService
     ↓
StateRepository
     ↓
State Domain Object

历史读取:

StateRepository
     ↓
StateHistory
     ↓
MemoryEngine
ExperienceEngine
DiagnosisEngine
RiskEngine
LearningEngine

因此 StateRepository 是状态数据进入后续认知计算体系的重要持久化入口。


217.33 状态完整生命周期

State 的持久化生命周期:

State Candidate
      ↓
Validation
      ↓
Verification
      ↓
Save
      ↓
Current State
      ↓
State Change
      ↓
Update
      ↓
History
      ↓
Archive

认知生命周期:

Event
 ↓
StateEngine
 ↓
State Result
 ↓
Feedback
 ↓
StateRepository
 ↓
State History
 ↓
Memory
 ↓
Experience
 ↓
Learning
 ↓
UpdateEngine
 ↓
StateRepository

形成完整闭环。


217.34 StateRepository核心公式

状态保存:

Save(S)→Validate→Persist→Verify\boxed{ Save(S) \rightarrow Validate \rightarrow Persist \rightarrow Verify }

状态查询:

Query(C)→PersistenceData→State\boxed{ Query(C) \rightarrow PersistenceData \rightarrow State }

状态历史:

St→St+1⇒History(St,St+1)\boxed{ S_t\rightarrow S_{t+1} \Rightarrow History(S_t,S_{t+1}) }

状态更新:

St+ΔS→St+1→Repository\boxed{ S_t+\Delta S \rightarrow S_{t+1} \rightarrow Repository }

其中:

  • StS_t:更新前当前状态;
  • ΔS\Delta S:经过计算和验证的状态变化;
  • St+1S_{t+1}:更新后的当前状态;
  • History:状态变化事实。

217.35 本章核心原则

原则一:当前状态与历史分离

CurrentState≠StateHistoryCurrentState\neq StateHistory

原则二:Repository不计算状态

StateRepository≠StateEngineStateRepository\neq StateEngine

原则三:查询不等于判断

QueryState≠EvaluateStateQueryState\neq EvaluateState

原则四:状态更新必须经过合法转换

StateEngine→Verification→UpdateEngineStateEngine \rightarrow Verification \rightarrow UpdateEngine

原则五:当前状态变化必须能够追溯

StateUpdate→StateHistoryStateUpdate \rightarrow StateHistory

原则六:状态历史不能被当前状态覆盖

历史必须保留变化事实。

原则七:保存必须可验证

Save→ReadBack→VerifySave \rightarrow ReadBack \rightarrow Verify

原则八:状态更新遵守事务一致性

CurrentState+HistoryCurrentState + History

应该在同一事务中保持一致。

原则九:Repository不负责认知学习

StateRepository≠MemoryEngine≠ExperienceEngine≠LearningEngineStateRepository \neq MemoryEngine \neq ExperienceEngine \neq LearningEngine

原则十:历史数据优先保护

状态历史是后续诊断、风险、经验和学习的重要事实基础。


217.36 本章总结

StateRepository 是 ICAI 状态持久化体系的核心组件。

它与 ObjectRepository 不同。

ObjectRepository 负责:

Object→PersistenceObject \rightarrow Persistence

StateRepository 负责:

State→PersistenceState \rightarrow Persistence

而 StateRepository 最重要的特点,是必须同时维护:

CurrentState+StateHistory\boxed{ CurrentState + StateHistory }

完整结构为:

StateEngine
     ↓
状态计算
     ↓
Verification
     ↓
UpdateEngine
     ↓
StateRepository
     ├── Current State
     └── State History
             ↓
          MySQL

状态读取:

MySQL→StateRepository→StateMySQL \rightarrow StateRepository \rightarrow State

状态更新:

St+ΔS→St+1S_t+\Delta S\rightarrow S_{t+1}

状态历史:

St→St+1⇒HistoryS_t\rightarrow S_{t+1} \Rightarrow History

最终形成:

StateEngine=状态计算\boxed{ StateEngine = 状态计算 } UpdateEngine=状态应用\boxed{ UpdateEngine = 状态应用 } StateRepository=状态持久化\boxed{ StateRepository = 状态持久化 } StateHistory=状态变化事实\boxed{ StateHistory = 状态变化事实 }

由此,ICAI 的状态体系形成了一个清晰的工程边界:

Event→StateEngine→UpdateEngine→StateRepository→MySQL\boxed{ Event \rightarrow StateEngine \rightarrow UpdateEngine \rightarrow StateRepository \rightarrow MySQL }

而历史数据继续向认知系统反馈:

StateHistory→Memory→Experience→Learning→Update\boxed{ StateHistory \rightarrow Memory \rightarrow Experience \rightarrow Learning \rightarrow Update }

这使状态不再只是 Object 上的一个字符串字段,而成为 ICAI 中具有 当前事实、变化过程、时间记录、原因记录和可追溯历史 的独立 Domain Object。

Leave a Reply

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