第214章 ICAI Repository模式
214.1 Repository模式的提出
第213章已经建立了 ICAI 的数据持久化体系:
DomainObject↔PersistenceObject↔Repository↔MySQLDomainObject \leftrightarrow PersistenceObject \leftrightarrow Repository \leftrightarrow MySQL
但是,如果每一个 Service 或 Domain Object 都直接编写 SQL,就会产生严重的问题:
IndividualService → SQL
ObjectService → SQL
GoalService → SQL
CapabilityService → SQL
MethodService → SQL
MemoryService → SQL
LearningService → SQL
最终业务逻辑、认知逻辑和数据库逻辑全部混合。
因此 ICAI 需要建立一个明确的持久化边界:
Domain→Repository→Database\boxed{ Domain \rightarrow Repository \rightarrow Database }
**Repository Pattern(仓储模式)**就是用于解决这一问题的工程模式。
Repository 的核心目标不是“减少 SQL”,而是:
让领域对象不需要知道 MySQL 如何存储自己。
214.2 Repository 定义
**Repository(仓储)**是 Domain Object 与持久化存储之间的抽象访问层。
它向上提供:
- 保存;
- 读取;
- 更新;
- 删除;
- 查询;
- 存在性判断;
- 持久化映射。
向下连接:
- MySQL;
- PDO;
- SQL;
- 数据表;
- 数据库事务。
因此:
Repository=DomainPersistenceBoundary\boxed{ Repository = DomainPersistenceBoundary }
Repository 不负责认知计算。
它不负责:
Decision
Learning
Diagnosis
Risk Calculation
Method Selection
Behavior Execution
它只负责:
DomainData↔PersistenceDataDomainData \leftrightarrow PersistenceData
214.3 Repository 的核心模型
Repository 可以定义为:
Repo=(D,M,P,Q,T)Repo=(D,M,P,Q,T)
其中:
- DD:Domain Object;
- MM:Mapping;
- PP:Persistence;
- QQ:Query;
- TT:Transaction Support。
进一步表示:
Repository=Mapping+Query+PersistenceRepository = Mapping + Query + Persistence
即:
Domain Object
↓
Mapping
↓
Query / Persistence
↓
MySQL
214.4 Repository 与数据库访问的区别
Repository 经常被错误理解为:
一个专门写 SQL 的 PHP 类。
这是不完整的。
如果:
class ObjectRepository
{
public function save($object)
{
mysql_query(...);
}
}
它虽然可以完成数据库操作,但还没有完整体现 Repository 模式。
Repository 更重要的作用是:
Domain̸ depend on SQLDomain \not\ depend\ on\ SQL
也就是说:
Domain Object
↓
Repository Interface
↓
MySQL Repository
Domain 层只需要知道:
find()
save()
update()
delete()
而不需要知道:
SELECT ...
INSERT ...
UPDATE ...
DELETE ...
214.5 Repository 的核心职责
ICAI Repository 主要承担以下职责。
1. Object Load
从持久化存储读取 Domain Object:
Database→Repository→DomainObjectDatabase \rightarrow Repository \rightarrow DomainObject
2. Object Save
保存新对象:
DomainObject→Repository→DatabaseDomainObject \rightarrow Repository \rightarrow Database
3. Object Update
保存对象变化:
DomainObjectt→Δ→Repository→DatabaseDomainObject_t \rightarrow \Delta \rightarrow Repository \rightarrow Database
4. Object Delete
删除或归档对象。
5. Query
根据条件获取领域对象。
6. Exists
判断对象是否存在。
7. Mapping
完成:
DomainObject↔PersistenceDataDomainObject \leftrightarrow PersistenceData
8. Persistence Boundary
阻止上层业务代码直接依赖 MySQL 细节。
214.6 Repository 不负责什么
Repository 同样必须有明确的职责边界。
Repository 不应该负责:
不负责业务决策
Repository≠DecisionEngineRepository \neq DecisionEngine
不负责认知计算
Repository≠CognitiveEngineRepository \neq CognitiveEngine
不负责学习
Repository≠LearningEngineRepository \neq LearningEngine
不负责状态推理
Repository≠StateEngineRepository \neq StateEngine
不负责方法选择
Repository≠MethodEngineRepository \neq MethodEngine
不负责行为执行
Repository≠BehaviorEngineRepository \neq BehaviorEngine
不负责异常诊断
Repository≠DiagnosisEngineRepository \neq DiagnosisEngine
不负责风险计算
Repository≠RiskEngineRepository \neq RiskEngine
Repository 只保存和读取已经由上层确认的数据。
214.7 Domain Object 与 Repository
Domain Object 是 ICAI 中描述领域实体的对象。
例如:
Individual
Object
Goal
Capability
Method
Behavior
Memory
Experience
Learning
Repository 则负责这些对象的持久化。
因此:
DomainObject=WhatDomainObject = What
Repository:
Repository=HowToPersistRepository = HowToPersist
例如:
Object
表示:
当前系统中的一个对象。
而:
ObjectRepository
表示:
如何找到、保存、更新这个对象。
二者不能混为一谈。
214.8 Domain Object 不应该直接操作 MySQL
错误结构:
Object
↓
PDO
↓
MySQL
例如:
class Object
{
public function save()
{
$pdo->query(
"UPDATE objects SET state='running'"
);
}
}
这种方式会导致 Domain Object 同时承担:
对象状态
业务逻辑
数据库连接
SQL
数据表结构
事务
违反职责分离。
正确结构:
Object
↓
ObjectRepository
↓
PDO
↓
MySQL
214.9 Repository 与 Service
Service 与 Repository 也不能混淆。
Service:
负责应用流程和业务协调。
Repository:
负责领域对象的持久化。
例如:
ObjectController
↓
ObjectService
↓
ObjectEngine
↓
ObjectRepository
↓
MySQL
其中:
ObjectService
负责:
Create
Load
Validate
Calculate
Update
Save
Result
ObjectEngine
负责:
Object Calculation
Object Matching
Object Update Evaluation
ObjectRepository
负责:
Insert
Select
Update
Delete
因此:
Service≠RepositoryService \neq Repository
214.10 Repository 与 Engine
Engine 是计算层。
例如 ObjectEngine:
ObjectEngine→CalculationObjectEngine \rightarrow Calculation
Repository:
Repository→PersistenceRepository \rightarrow Persistence
因此:
Object
↓
ObjectEngine
↓
Calculation Result
↓
ObjectService
↓
ObjectRepository
↓
MySQL
不能让 Engine 直接执行:
UPDATE objects ...
否则 Engine 将同时承担:
Calculation
Persistence
Transaction
SQL
从而破坏 ICAI 的 Engine/Service/Repository 分层。
214.11 Repository 与 MySQL
MySQL 是 ICAI 的具体持久化存储。
因此:
MySQL=StorageMySQL = Storage
而:
Repository=PersistenceAccessRepository = PersistenceAccess
Repository 可以使用:
PDO
MySQLi
Database Adapter
但是上层 Domain Object 不需要知道这些实现细节。
结构:
Domain
↓
Repository
↓
Database Adapter
↓
MySQL
这意味着未来即使数据库发生变化:
MySQL
↓
Other SQL Database
Domain 层原则上仍然可以保持稳定。
214.12 Repository Interface
为了进一步降低 Domain 对具体数据库的依赖,可以定义 Repository 接口。
例如:
<?php
interface ObjectRepositoryInterface
{
public function findById($id);
public function save($object);
public function update($object);
public function delete($id);
public function exists($id);
}
然后建立 MySQL 实现:
<?php
class MySQLObjectRepository implements ObjectRepositoryInterface
{
protected $db;
public function __construct($db)
{
$this->db = $db;
}
public function findById($id)
{
$sql = "SELECT *
FROM objects
WHERE id = ?";
$stmt = $this->db->prepare($sql);
$stmt->execute(array($id));
return $stmt->fetch(PDO::FETCH_ASSOC);
}
public function save($object)
{
$sql = "INSERT INTO objects
(id, type, state)
VALUES (?, ?, ?)";
$stmt = $this->db->prepare($sql);
return $stmt->execute(array(
$object->id,
$object->type,
$object->state
));
}
public function update($object)
{
$sql = "UPDATE objects
SET type = ?, state = ?
WHERE id = ?";
$stmt = $this->db->prepare($sql);
return $stmt->execute(array(
$object->type,
$object->state,
$object->id
));
}
public function delete($id)
{
$sql = "DELETE
FROM objects
WHERE id = ?";
$stmt = $this->db->prepare($sql);
return $stmt->execute(array($id));
}
public function exists($id)
{
$sql = "SELECT id
FROM objects
WHERE id = ?";
$stmt = $this->db->prepare($sql);
$stmt->execute(array($id));
return (bool)$stmt->fetch(PDO::FETCH_ASSOC);
}
}
这样形成:
ObjectRepositoryInterface←MySQLObjectRepositoryObjectRepositoryInterface \leftarrow MySQLObjectRepository
214.13 Domain Object 的恢复
Repository 读取数据库之后,不应该只返回原始数据库数组。
例如:
$data = $repository->findById(1001);
如果直接得到:
array(
'id' => 1001,
'type' => 'machine',
'state' => 'ready'
)
那么上层仍然需要自己解释数据库结构。
更完整的 Repository 应该负责:
PersistenceData→DomainObjectPersistenceData \rightarrow DomainObject
例如:
class ObjectMapper
{
public function toDomain($data)
{
$object = new Object();
$object->id = $data['id'];
$object->type = $data['type'];
$object->state = $data['state'];
return $object;
}
public function toPersistence($object)
{
return array(
'id' => $object->id,
'type' => $object->type,
'state' => $object->state
);
}
}
这样:
Repository+Mapper→DomainObjectRepository + Mapper \rightarrow DomainObject
214.14 Repository 的查询职责
Repository 可以提供领域需要的查询。
例如:
public function findById($id)
{
// ...
}
public function findByType($type)
{
// ...
}
public function findByState($state)
{
// ...
}
public function findByIndividual($individualId)
{
// ...
}
这些查询表达的是:
找到什么领域对象。
而不是:
执行什么认知计算。
例如:
findAvailableCapabilities()
如果其中只是数据库状态查询,可以属于 Repository。
但如果需要复杂能力计算:
Capability
+
State
+
Range
+
Condition
+
Rule
则应该交给:
CapabilityEngineCapabilityEngine
所以:
RepositoryQuery≠CognitiveCalculationRepositoryQuery \neq CognitiveCalculation
214.15 Repository 查询与 Engine 计算
这是 ICAI 工程中非常重要的一条边界。
例如:
Repository:
查找所有 Capability
然后:
CapabilityEngine:
计算哪些 Capability 当前可用
正确流程:
Repository→LoadCandidates→CapabilityEngine→CalculateAvailabilityRepository \rightarrow LoadCandidates \rightarrow CapabilityEngine \rightarrow CalculateAvailability
而不是:
Repository→直接决定CapabilityAvailableRepository \rightarrow 直接决定CapabilityAvailable
因为:
Exists≠AvailableExists \neq Available
214.16 Repository 与 State
State 的当前值可以持久化:
states
但是状态转换不能由 Repository 决定。
正确:
StateEngine
↓
Calculate Transition
↓
StateService
↓
StateRepository
↓
MySQL
因此:
StateEngine=StateCalculationStateEngine = StateCalculation StateRepository=StatePersistenceStateRepository = StatePersistence
214.17 Repository 与 Relation
RelationRepository 可以保存:
R=(ID,O1,T,O2,C,S,Tm)R=(ID,O_1,T,O_2,C,S,T_m)
例如:
class RelationRepository
{
public function findOutgoing($objectId)
{
// 查询 source_object_id
}
public function findIncoming($objectId)
{
// 查询 target_object_id
}
public function save($relation)
{
// 保存 Relation
}
public function update($relation)
{
// 更新 Relation
}
}
但是关系是否合法:
ValidRelationValidRelation
应该由:
RelationEngineRelationEngine
判断。
因此:
RelationEngine
→ 计算关系是否合法
RelationRepository
→ 保存关系
214.18 Repository 与 Knowledge
KnowledgeRepository 负责:
Load Knowledge
Save Knowledge
Update Knowledge
Find Knowledge
KnowledgeEngine 负责:
Calculate
Match
Infer
Verify Candidate
所以:
KnowledgeEngine→KnowledgeResultKnowledgeEngine \rightarrow KnowledgeResult
然后:
KnowledgeService→KnowledgeRepositoryKnowledgeService \rightarrow KnowledgeRepository
最终:
MySQLMySQL
214.19 Repository 与 Memory
MemoryRepository 保存:
M=(I,C,W,T,R)M=(I,C,W,T,R)
例如:
memories
memory_relations
memory_history
MemoryEngine 负责:
Memory Calculation
Memory Recall
Memory Update Evaluation
Repository 负责:
Memory Persistence
Memory Retrieval
所以:
MemoryEngine≠MemoryRepositoryMemoryEngine \neq MemoryRepository
214.20 Repository 与 Experience
ExperienceRepository 保存:
E=(H,M,C,R,P)E=(H,M,C,R,P)
ExperienceEngine 负责:
ExperienceCalculation+ExperienceRecall+ExperienceUpdateExperienceCalculation + ExperienceRecall + ExperienceUpdate
完整结构:
ExperienceEngine
↓
Experience Result
↓
ExperienceService
↓
ExperienceRepository
↓
MySQL
这样经验的计算与经验的存储完全分离。
214.21 Repository 与 Learning
LearningEngine 产生:
LearningResultLearningResult
并形成:
UpdateCandidateUpdateCandidate
Repository 可以保存:
learning_records
learning_evidence
learning_history
但是:
LearningRepository≠UpdateEngineLearningRepository \neq UpdateEngine
Repository 只保存学习结果。
真正的正式更新:
UpdateCandidate→UpdateEngineUpdateCandidate \rightarrow UpdateEngine
然后:
UpdateEngine→RepositoryUpdateEngine \rightarrow Repository
214.22 Repository 与 Individual
IndividualRepository 是 ICAI 中比较特殊的 Repository。
因为 Individual 是组合对象:
I=(O,K,C,M,B,MM,E)I=(O,K,C,M,B,MM,E)
因此:
IndividualRepository
可能需要协调读取:
individuals
objects
knowledge
capabilities
methods
behaviors
memories
experiences
最终恢复:
Individual=Objects+Knowledge+Capability+Method+Behavior+Memory+ExperienceIndividual = Objects + Knowledge + Capability + Method + Behavior + Memory + Experience
但是这种“协调读取”仍然属于持久化恢复,不属于认知推理。
214.23 Aggregate 与 Repository
在复杂 Domain 中,可以把相关对象组成一个:
Aggregate(聚合)。
例如:
IndividualIndividual
作为一个较高层的 Aggregate Root。
其下可能包含:
Objects
Capabilities
Methods
Memory
Experience
Repository 可以围绕 Aggregate Root 建立。
例如:
IndividualRepository
负责恢复:
IndividualAggregateIndividualAggregate
但并不意味着所有数据都必须一次性查询。
可以采用:
Individual
├── ObjectRepository
├── CapabilityRepository
├── MethodRepository
├── MemoryRepository
└── ExperienceRepository
根据当前 Use Case 进行加载。
214.24 Repository 与事务
Repository 可以参与事务,但不应该独占事务控制权。
例如:
IndividualService
↓
Begin Transaction
↓
ObjectRepository
↓
StateRepository
↓
FeedbackRepository
↓
LearningRepository
↓
Commit
事务由:
Service+TransactionManagerService + TransactionManager
协调。
Repository 参与执行数据库操作。
因此:
Repository≠TransactionManagerRepository \neq TransactionManager
214.25 Repository 的 Save 生命周期
一个完整的 Repository 保存过程:
DomainObject→Validate→Map→Exists→Insert/Update→ReadBack→VerifyDomainObject \rightarrow Validate \rightarrow Map \rightarrow Exists \rightarrow Insert/Update \rightarrow ReadBack \rightarrow Verify
即:
Domain Object
↓
Validation
↓
Mapping
↓
Existence Check
↓
Insert / Update
↓
Read Back
↓
Persistence Verification
这与第213章的数据持久化原则保持一致。
214.26 Repository 的 Read 生命周期
读取:
Request→Repository→Query→PersistenceData→Mapping→DomainObjectRequest \rightarrow Repository \rightarrow Query \rightarrow PersistenceData \rightarrow Mapping \rightarrow DomainObject
例如:
findById(1001)
↓
SELECT
↓
Data
↓
Mapper
↓
Object
如果对象不存在:
findById→nullfindById \rightarrow null
而不是伪造一个对象。
214.27 Repository 的 Update 生命周期
更新:
DomainObjectt→Compare→Δ→Validate→Update→VerifyDomainObject_t \rightarrow Compare \rightarrow \Delta \rightarrow Validate \rightarrow Update \rightarrow Verify
例如:
Old:
state = ready
New:
state = running
得到:
ΔS:ready→running\Delta S: ready\rightarrow running
Repository 保存这个合法变化。
如果 StateEngine 没有允许:
ready→runningready\rightarrow running
那么 Service 应该在进入 Repository 前阻止更新。
Repository 不应该自己创造状态转换规则。
214.28 Repository 的 Delete 生命周期
删除:
Delete→CheckReference→LogicalDelete/Archive/PhysicalDeleteDelete \rightarrow CheckReference \rightarrow LogicalDelete/Archive/PhysicalDelete
尤其对于 ICAI:
Object
↓
Relation
↓
Memory
↓
Experience
↓
Learning
存在大量历史关系。
因此删除对象前需要判断:
Referenced?Referenced?
如果:
Referenced=trueReferenced=true
则不能简单:
DELETE
而可能使用:
inactive
archived
deleted
214.29 Repository 数据一致性
Repository 保存的数据必须满足数据库层的一致性要求。
包括:
- Primary Key;
- Foreign Key;
- Unique;
- NOT NULL;
- Data Type;
- Index;
- Transaction。
例如 Relation:
(O1,T,O2)(O_1,T,O_2)
如果:
O1O_1
不存在,则不能形成有效关系。
因此数据库可以通过:
Foreign Key
提供最后一层数据约束。
但必须注意:
DatabaseConstraint≠DomainRuleDatabaseConstraint \neq DomainRule
数据库保证数据结构合法。
Engine 保证认知计算合法。
Service 保证流程合法。
214.30 Repository 的异常处理
数据库操作可能产生:
Connection Error
SQL Error
Constraint Error
Transaction Error
Timeout
Duplicate Key
Not Found
Repository 应该把这些错误转换为明确的持久化结果或异常。
例如:
try {
$stmt = $this->db->prepare($sql);
$stmt->execute($params);
return true;
} catch (PDOException $e) {
throw new RepositoryException(
'Object persistence failed'
);
}
但是 Repository 不应该把数据库错误伪装成:
Learning failed
Decision failed
Diagnosis failed
因为:
PersistenceFailure≠CognitiveFailurePersistenceFailure \neq CognitiveFailure
214.31 Repository Result
Repository 可以返回明确的持久化结果:
RR=(O,A,S,E,T)RR=(O,A,S,E,T)
其中:
- OO:Object;
- AA:Action,例如 save/update/delete;
- SS:Persistence Status;
- EE:Error/Evidence;
- TT:Time。
例如:
$result = array(
'object_id' => 1001,
'action' => 'update',
'status' => 'saved',
'time' => time()
);
不要简单使用:
return true;
作为所有持久化操作的唯一信息。
214.32 Repository 与 MySQL 表结构
以 Object 为例:
CREATE TABLE objects (
id INT NOT NULL,
type VARCHAR(100) NOT NULL,
state VARCHAR(100) NOT NULL,
created_at INT NOT NULL,
updated_at INT NOT NULL,
PRIMARY KEY (id)
);
Repository 负责把:
Object
映射到:
objects
但是 Domain Object 不应该知道:
objects
是 MySQL 中的一张表。
这就是持久化隔离。
214.33 ICAI Repository 的分类
随着 ICAI 体系继续扩展,可以建立:
IndividualRepository
ObjectRepository
StateRepository
RelationRepository
KnowledgeRepository
GoalRepository
CapabilityRepository
MethodRepository
DecisionRepository
BehaviorRepository
ActionRepository
ExecutionRepository
FeedbackRepository
MemoryRepository
ExperienceRepository
RiskRepository
ConflictRepository
DiagnosisRepository
ProtectionRepository
RepairRepository
LearningRepository
UpdateRepository
这些 Repository 都遵守同一原则:
DomainObject↔PersistenceDomainObject \leftrightarrow Persistence
214.34 Repository 的统一接口思想
可以抽象基础接口:
<?php
interface RepositoryInterface
{
public function findById($id);
public function save($object);
public function update($object);
public function delete($id);
public function exists($id);
}
然后:
ObjectRepository
CapabilityRepository
MethodRepository
MemoryRepository
ExperienceRepository
LearningRepository
分别实现自己的领域持久化逻辑。
但不能为了“统一”而强行让所有 Repository 的查询都完全一样。
因为:
DomainDifference→RepositoryDifferenceDomainDifference \rightarrow RepositoryDifference
例如:
MemoryRepository
可能需要:
findByContext()
findByWeight()
findRelated()
而:
MethodRepository
可能需要:
findByType()
findByCapability()
findByCondition()
214.35 Repository 与 ICAI 完整架构
到目前为止,ICAI 的工程架构可以进一步明确:
Controller
↓
Service
↓
┌──────────┴──────────┐
↓ ↓
Engine Domain Object
↓ ↓
└──────────┬──────────┘
↓
Repository
↓
Database Adapter
↓
MySQL
五个核心层分别承担:
Controller=入口Controller=入口 Service=流程协调Service=流程协调 Engine=计算Engine=计算 DomainObject=领域结构DomainObject=领域结构 Repository=持久化Repository=持久化 MySQL=存储MySQL=存储
214.36 一次完整 ICAI 操作
例如系统需要更新某个 Method。
完整过程:
Request
↓
MethodController
↓
MethodService
↓
Load Method
↓
MethodRepository
↓
MySQL
↓
Method Object
↓
MethodEngine
↓
Calculate / Validate
↓
MethodService
↓
Update Candidate
↓
Validation
↓
MethodRepository
↓
MySQL
↓
Read Back
↓
Verification
↓
MethodService
↓
Result
完整公式:
Request→Service→Repository→DomainObject→Engine→Repository→MySQL\boxed{ Request \rightarrow Service \rightarrow Repository \rightarrow DomainObject \rightarrow Engine \rightarrow Repository \rightarrow MySQL }
214.37 Learning → Update → Repository
结合第212章和第208章:
Feedback
↓
Memory
↓
Experience
↓
LearningEngine
↓
Learning Candidate
↓
UpdateEngine
↓
Updated Domain Object
↓
Repository
↓
MySQL
这里必须保持三个不同动作:
Learning≠Update≠PersistenceLearning \neq Update \neq Persistence
Learning:
产生认知变化候选。
Update:
正式应用认知变化。
Repository:
保存已经确认的变化。
214.38 Self-Maintenance → Repository
第211章 Self-Maintenance Engine 产生:
Detection
Risk
Protection
Conflict
Diagnosis
Repair
Verification
这些结果需要持久化:
maintenance_events
maintenance_risks
maintenance_protections
maintenance_conflicts
maintenance_diagnoses
maintenance_repairs
maintenance_verifications
但 SelfMaintenanceEngine 不直接执行:
INSERT
正确结构:
SelfMaintenanceEngine→Result→SelfMaintenanceService→Repository→MySQLSelfMaintenanceEngine \rightarrow Result \rightarrow SelfMaintenanceService \rightarrow Repository \rightarrow MySQL
214.39 Repository 不等于 Active Record
ICAI 应明确区分:
Repository Pattern
与:
Active Record Pattern。
Active Record 往往让对象本身拥有:
save()
update()
delete()
并直接对应数据库。
Repository Pattern 则强调:
Domain Object
↓
Repository
↓
Database
对于 ICAI 这种具有:
- Engine;
- Service;
- Domain Object;
- State;
- Relation;
- Memory;
- Experience;
- Learning;
复杂认知结构的系统,Repository 更适合保持领域对象与持久化机制之间的分离。
214.40 Repository 与 OOP
Repository 本身也是 OOP 对象。
例如:
ObjectRepository
CapabilityRepository
MethodRepository
MemoryRepository
这些对象可以:
- 注入 Database Adapter;
- 注入 Mapper;
- 使用 Interface;
- 被 Service 调用;
- 被测试替换;
- 独立处理持久化逻辑。
因此:
Repository⊂OOPArchitectureRepository \subset OOPArchitecture
而不是简单的:
SQL Helper
214.41 Repository 的依赖方向
推荐依赖方向:
Controller→Service→RepositoryController \rightarrow Service \rightarrow Repository
同时:
Service→EngineService \rightarrow Engine
Repository 不应该反过来调用:
DecisionService
LearningService
BehaviorService
否则形成循环依赖:
Service→Repository→ServiceService \rightarrow Repository \rightarrow Service
容易造成:
- 初始化循环;
- 隐式业务逻辑;
- 难以追踪;
- 难以测试。
因此 Repository 应保持较低层级。
214.42 Repository 的核心工程原则
ICAI Repository 模式可以归纳为八项原则。
原则一:领域对象不直接依赖 MySQL
DomainObject↛MySQLDomainObject \not\rightarrow MySQL
原则二:Repository 是持久化边界
Repository=PersistenceBoundaryRepository=PersistenceBoundary
原则三:Engine 不负责数据库
Engine≠PersistenceEngine\neq Persistence
原则四:Service 负责协调
Service=OrchestrationService=Orchestration
原则五:Repository 不负责认知计算
Repository≠CognitionRepository\neq Cognition
原则六:数据库不等于领域规则
DatabaseConstraint≠DomainRuleDatabaseConstraint\neq DomainRule
原则七:保存必须可验证
Save→ReadBack→VerifySave\rightarrow ReadBack\rightarrow Verify
原则八:历史不能被无条件覆盖
CurrentData+HistoryCurrentData+History
共同构成完整持久化事实。
214.43 Repository 的完整 PHP 工程结构
最终可以形成:
app/
├── Domain/
│ ├── Individual/
│ ├── Object/
│ ├── State/
│ ├── Relation/
│ ├── Knowledge/
│ ├── Capability/
│ ├── Method/
│ ├── Behavior/
│ ├── Memory/
│ ├── Experience/
│ └── Learning/
│
├── Engines/
│ ├── CognitiveEngine.php
│ ├── ObjectEngine.php
│ ├── StateEngine.php
│ ├── KnowledgeEngine.php
│ ├── MethodEngine.php
│ └── LearningEngine.php
│
├── Services/
│ ├── IndividualService.php
│ ├── ObjectService.php
│ ├── MethodService.php
│ └── LearningService.php
│
├── Repositories/
│ ├── RepositoryInterface.php
│ ├── IndividualRepository.php
│ ├── ObjectRepository.php
│ ├── StateRepository.php
│ ├── RelationRepository.php
│ ├── KnowledgeRepository.php
│ ├── CapabilityRepository.php
│ ├── MethodRepository.php
│ ├── MemoryRepository.php
│ ├── ExperienceRepository.php
│ └── LearningRepository.php
│
└── Infrastructure/
├── Database/
│ ├── Database.php
│ └── MySQLConnection.php
└── Mapping/
├── ObjectMapper.php
├── MethodMapper.php
└── LearningMapper.php
形成:
Domain+Engine+Service+Repository+InfrastructureDomain + Engine + Service + Repository + Infrastructure
的完整 PHP OOP 分层。
214.44 Repository 与 MySQL 的最终关系
可以把 Repository 与 MySQL 的关系明确为:
Repository≠MySQL\boxed{ Repository \neq MySQL }
Repository 是:
Application/Domain→PersistenceApplication/Domain \rightarrow Persistence
MySQL 是:
Persistence→StoragePersistence \rightarrow Storage
因此:
Domain Object
↓
Repository
↓
PDO / Adapter
↓
MySQL
↓
Table / Index / Constraint
Repository 把 MySQL 的:
SQL
Connection
Table
Column
Transaction
隔离在基础设施层。
214.45 本章总结
Repository 模式解决的是 ICAI 中一个非常基础但非常重要的问题:
领域对象如何在不依赖数据库实现细节的情况下获得稳定的持久化能力。
其核心模型为:
DomainObject↔Repository↔MySQL\boxed{ DomainObject \leftrightarrow Repository \leftrightarrow MySQL }
其中:
| 层 | 核心职责 |
|---|---|
| Domain Object | 表达领域对象 |
| Engine | 计算、匹配、推导、验证 |
| Service | 协调业务流程 |
| Repository | 持久化对象 |
| MySQL | 长期数据存储 |
Repository 的核心职责:
Load+Save+Update+Delete+Query+Mapping+Persistence\boxed{ Load + Save + Update + Delete + Query + Mapping + Persistence }
但 Repository 不负责:
DecisionDecision LearningLearning DiagnosisDiagnosis RiskRisk BehaviorBehavior CognitiveCalculationCognitiveCalculation
因此 ICAI 的完整分层可以定义为:
Controller→Service→Engine→DomainObject→Repository→MySQL\boxed{ Controller \rightarrow Service \rightarrow Engine \rightarrow DomainObject \rightarrow Repository \rightarrow MySQL }
实际运行过程中则可能表现为:
Request→Service→Repository→DomainObject→Engine→Service→Repository→MySQL\boxed{ Request \rightarrow Service \rightarrow Repository \rightarrow DomainObject \rightarrow Engine \rightarrow Service \rightarrow Repository \rightarrow MySQL }
而学习持久化形成:
Feedback→Memory→Experience→Learning→Update→DomainObject→Repository→MySQL\boxed{ Feedback \rightarrow Memory \rightarrow Experience \rightarrow Learning \rightarrow Update \rightarrow DomainObject \rightarrow Repository \rightarrow MySQL }
Self-Maintenance 持久化形成:
Detection→Risk→Protection→Conflict→Diagnosis→Repair→Verification→Repository→MySQL\boxed{ Detection \rightarrow Risk \rightarrow Protection \rightarrow Conflict \rightarrow Diagnosis \rightarrow Repair \rightarrow Verification \rightarrow Repository \rightarrow MySQL }
最终,Repository 成为 ICAI 中连接:
认知对象↔运行对象↔持久化对象↔数据库\boxed{ 认知对象 \leftrightarrow 运行对象 \leftrightarrow 持久化对象 \leftrightarrow 数据库 }
的核心边界。
因此,Repository 的本质不是一个“SQL 类”,而是:
Repository=Domain Persistence Boundary\boxed{ Repository = Domain\ Persistence\ Boundary }
它使 ICAI 的认知计算能够保持独立,使 PHP OOP Domain Object 不直接依赖 MySQL,使 Engine 保持纯计算职责,使 Service 保持流程协调职责,同时让系统的对象、状态、关系、知识、能力、方法、记忆、经验、学习和维护记录能够长期保存并在下一次运行时重新恢复。
由此,第213章建立的“数据持久化体系”,在第214章正式落实为:
MemoryObject↔DomainObject↔Repository↔Persistence\boxed{ MemoryObject \leftrightarrow DomainObject \leftrightarrow Repository \leftrightarrow Persistence }
为后续 ICAI 的 Repository 统一接口、Repository Factory、Unit of Work、TransactionManager、对象聚合加载以及完整 MVC + Service + Engine + Repository + MySQL 工程体系奠定基础。