import { NodeTemplate } from '../../..'; import { Position, NodeType } from '../value-objects'; import { ValidationError } from '../errors'; /** * 行为树节点领域实体 * 封装节点的业务逻辑和验证规则 */ export class Node { private readonly _id: string; private readonly _template: NodeTemplate; private _data: Record; private _position: Position; private _children: string[]; private readonly _nodeType: NodeType; constructor( id: string, template: NodeTemplate, data: Record, position: Position, children: string[] = [] ) { this._id = id; this._template = template; this._data = { ...data }; this._position = position; this._children = [...children]; this._nodeType = NodeType.fromString(template.type); } get id(): string { return this._id; } get template(): NodeTemplate { return this._template; } get data(): Record { return { ...this._data }; } get position(): Position { return this._position; } get children(): ReadonlyArray { return this._children; } get nodeType(): NodeType { return this._nodeType; } /** * 更新节点位置 */ moveToPosition(newPosition: Position): Node { return new Node( this._id, this._template, this._data, newPosition, this._children ); } /** * 更新节点数据 */ updateData(data: Record): Node { return new Node( this._id, this._template, { ...this._data, ...data }, this._position, this._children ); } /** * 添加子节点 * @throws ValidationError 如果违反业务规则 */ addChild(childId: string): Node { // 使用模板定义的约束,undefined 表示无限制 const maxChildren = (this._template.maxChildren ?? Infinity) as number; if (maxChildren === 0) { throw ValidationError.leafNodeNoChildren(); } if (this._children.length >= maxChildren) { if (this._nodeType.isRoot()) { throw ValidationError.rootNodeMaxChildren(); } if (this._nodeType.isDecorator()) { throw ValidationError.decoratorNodeMaxChildren(); } throw new ValidationError(`节点 ${this._id} 已达到最大子节点数 ${maxChildren}`); } if (this._children.includes(childId)) { throw new ValidationError(`子节点 ${childId} 已存在`); } return new Node( this._id, this._template, this._data, this._position, [...this._children, childId] ); } /** * 移除子节点 */ removeChild(childId: string): Node { return new Node( this._id, this._template, this._data, this._position, this._children.filter((id) => id !== childId) ); } /** * 检查是否可以添加子节点 */ canAddChild(): boolean { // 使用模板定义的最大子节点数,undefined 表示无限制 const maxChildren = (this._template.maxChildren ?? Infinity) as number; return this._children.length < maxChildren; } /** * 检查是否有子节点 */ hasChildren(): boolean { return this._children.length > 0; } /** * 检查是否为根节点 */ isRoot(): boolean { return this._nodeType.isRoot(); } /** * 转换为普通对象(用于序列化) */ toObject(): { id: string; template: NodeTemplate; data: Record; position: { x: number; y: number }; children: string[]; } { return { id: this._id, template: this._template, data: this._data, position: this._position.toObject(), children: [...this._children] }; } /** * 从普通对象创建节点 */ static fromObject(obj: { id: string; template: NodeTemplate; data: Record; position: { x: number; y: number }; children: string[]; }): Node { return new Node( obj.id, obj.template, obj.data, Position.fromObject(obj.position), obj.children ); } }