Глава 20. KObject — общий фундамент объекта
20.1. Самый маленький общий знаменатель
Теперь мы знаем, что KObject — базовый класс.
Значит, в нём должна находиться та часть, которая нужна каждому объекту независимо от его типа.
Но что это? Изделию нужно описание. Документу нужно содержание. Пользователю нужны свойства. Проекту нужны участники. Связи имеют собственные характеристики.
Ничего из этого нельзя считать общей частью всех объектов.
Остаётся более простой уровень. Система должна знать:
этот объект существует.
И должна уметь отличить его от любого другого объекта. Поэтому фундамент начинается с идентификатора.
KObject
id = 12345
Это не имя. Не номер изделия. Не обозначение документа. Не код проекта.
Это идентификатор самого объекта внутри модели.
20.2. Почему идентификатор не является именем
Рассмотрим объект:
KProduct
id = 12345
Сегодня изделие называется:
Насос Н1
Через несколько лет его название может измениться:
Насос Н1А
Сам объект при этом не становится другим. Поэтому название не должно определять сам KObject.
Название — это информация об объекте.
KObject 12345
│
└── KAttribute
name = "Насос Н1"
Позже:
KObject 12345
│
└── KAttribute
name = "Насос Н1А"
KObject остаётся тем же. Изменилось знание о нём.
20.3. Почему свойства не входят в KObject
То же самое относится к инженерным свойствам.
У изделия может измениться:
- масса;
- материал;
- производитель;
- назначение;
- статус;
- любое другое значение, которое модель допускает изменять.
Если поместить эти данные непосредственно в KObject, базовый объект начнёт представлять текущее состояние объекта.
Но это уже не фундамент. Это становится контейнером изменяемой информации. Вместо этого модель разделяет уровни:
KObject
│
└── KAttribute
├── material
├── mass
└── ...
KObject остаётся основой.
KAttribute хранит сведения об объекте.
Это различие особенно важно для истории: изменение свойства не должно менять сам объект.
20.4. Почему описание не входит в KObject
То же правило относится к описанию.
У одного объекта может быть несколько описаний. Например:
KProduct
│
├── KDesignDefinition
│ └── Revision A
│
└── KTechnologyDefinition
└── Revision B
Каждое описание развивается независимо.
Revision фиксирует состояние соответствующего описания.
Если описание изменилось, KObject не меняется. Поэтому KObject не должен содержать Definition.
Он только является объектом, к которому Definition относится.
20.5. Почему контекст не входит в KObject
Та же граница действует для административного состояния.
Владелец может измениться. Проект может измениться. Группа владения может измениться. Административное состояние объекта может измениться.
Поэтому эти данные относятся к KContext.
KObject
│
└── KContext
├── owner
├── project
└── owningGroup
Причём связь направлена именно так:
KContext знает, к какому KObject он относится.
KObject не обязан знать о существовании KContext. Это принципиально.
Факт существования объекта не должен зависеть от административных условий его управления.
Поэтому объект и его административный контекст остаются разделёнными.
20.6. Почему состояние не входит в KObject
Объект может проходить через разные состояния:
в разработке
↓
в производстве
↓
в эксплуатации
↓
выведен из эксплуатации
Состояние изменяется. Сам объект при этом продолжает существовать.
Следовательно, состояние не может быть частью неизменяемого фундамента.
Оно относится к той части модели, которая описывает состояние объекта во времени.
20.7. Что тогда действительно входит в KObject
Теперь можно сформулировать правило.
KObject содержит только то, что необходимо для общего механизма существования любого объекта.
В первую очередь это:
KObject
└── id
Именно здесь находится минимальная общая часть. Всё, что отвечает на вопросы:
что это за тип? как оно называется? какими свойствами обладает? как оно описано? в каком административном контексте находится? с чем связано?
относится уже к специализированным частям модели.
20.8. Тип находится в наследнике
Здесь особенно важно исправить возможное недоразумение.
Нельзя говорить:
KObjectне имеет типа.
Правильнее сказать:
KObjectявляется базовым классом, а конкретный объект имеет конкретный тип — один из его наследников.
Например:
KObject
│
├── KProduct
├── KDocument
├── KUser
└── KProject
Конкретный объект:
KProduct
id = 12345
является одновременно:
- конкретным
KProduct; KObject.
Как и положено объекту-наследнику в объектно-ориентированной модели.
KObject задаёт общую часть.
KProduct добавляет специфику изделия.
KDocument добавляет специфику документа.
KUser добавляет специфику пользователя.
Поэтому типизация не исчезает. Наоборот — она становится частью самой структуры модели.
20.9. KObject не должен становиться «универсальной таблицей»
Есть соблазн решить проблему универсальности иначе:
KObject
id
type
name
owner
status
project
material
mass
description
...
На первый взгляд это удобно. Все объекты находятся в одном месте. Но цена такой универсальности высока.
Базовый класс начинает знать о свойствах, которые нужны только некоторым типам.
Появляются поля, которые для одних объектов обязательны, для других бессмысленны, а для третьих вообще не существуют.
В результате общий класс перестаёт быть общим фундаментом. Он превращается в хранилище всего, что когда-либо понадобилось системе.
Модель делает обратное.
Она оставляет в KObject только действительно общую часть.
20.10. Что получается в результате
Теперь модель можно увидеть целиком:
KObject
│
┌─────────────────┼──────────────────┐
│ │ │
KProduct KDocument KUser
│
├── KDefinition
│ └── Revision
│
├── KAttribute
│
├── KContext
│
└── KRelation
Эти сущности относятся к одному объекту, но не являются внутренними полями KObject.
Здесь каждый уровень отвечает за свою задачу.
KObject:
какой объект существует?
Тип объекта:
чем является этот объект?
KAttribute:
что известно о его свойствах?
KDefinition:
как он описан?
Revision:
какое состояние этого описания зафиксировано?
KContext:
в каких административных условиях находится объект?
KRelation:
как этот объект связан с другими объектами?
Эти вопросы различаются. Поэтому они не должны быть сведены в одну сущность.
20.11. Почему это важно
Такое разделение позволяет изменять разные части модели независимо.
Изменилось название — объект не изменился. Изменилось свойство — объект не изменился. Появилась новая Revision — объект не изменился. Изменился административный контекст — объект не изменился. Изменились связи — объект не изменился.
Меняется информация вокруг объекта. Сам фундамент остаётся тем же.
Именно поэтому KObject может существовать на протяжении всего жизненного цикла объекта, не превращаясь в контейнер его текущего состояния.
20.12. Связь с предыдущими главами
Глава 11 установила: идентичность объекта стабильна, описание изменяется во времени.
Глава 19 установила: все самостоятельные объекты имеют общий базовый класс KObject. Конкретные типы объектов являются его наследниками.
Глава 20 добавляет: KObject содержит общую для всех объектов основу. Свойства, описания, контекст и связи относятся к другим сущностям модели.
Это не новая идея, появившаяся из технической реализации. Это следствие всей модели, построенной в предыдущих главах.
Если объект существует независимо от описания, если описание изменяется, если контекст изменяется, если свойства изменяются, а связи имеют собственную жизнь, то всё это нельзя помещать в сам объект.
Должна существовать устойчивая точка, относительно которой всё остальное определяется.
В KModel этой точкой является KObject.
20.13. Главный вывод
KObject — не «пустой объект». И не объект без типа.
Это базовый класс всех объектов модели.
Он содержит минимальную общую часть, необходимую для существования объекта в системе.
Конкретные наследники определяют, чем объект является. Другие сущности модели хранят сведения о нём:
KObject
│
┌─────────┼─────────┐
↓ ↓ ↓
KProduct KDocument KUser
│
┌────┼────┬────────┬────────┐
↓ ↓ ↓ ↓ ↓
Attribute Definition Context Relation
│
Revision
Эти сущности относятся к одному объекту, но не являются внутренними полями KObject.
Именно здесь проходит важная граница:
KObject — это не весь объект и не все знания о нём. Это общий базовый фундамент, на котором строятся конкретные типы объектов и всё остальное знание системы об этих объектах.
В следующей главе мы сделаем следующий шаг: если свойства не являются полями KObject, что именно представляет собой атрибут и почему он сам становится объектом модели?
Примечания к главе 20
Источники:
- ISO 10303-239, Industrial automation systems and integration — Product data representation and exchange — Part 239: Application protocol: Product life cycle support.
- NATO CALS Office, NPDM Version 4.10 — NATO Product Data Model, STANAG 4613 / ALP-14.
- ANSI/EIA-649-D, Configuration Management Standard, SAE International, 2019. §3.2.
- ГОСТ Р 2.101-2023. Единая система конструкторской документации. Виды изделий.
- ГОСТ Р 2.005-2023. Единая система конструкторской документации. Термины и определения.
- ГОСТ Р 2.052-2024. Единая система конструкторской документации. Электронная модель изделия. Общие положения.
- ГОСТ Р 2.053-2023. Единая система конструкторской документации. Электронная структура изделия. Общие положения.
- Rönnbäck, L. et al. Anchor Modeling: An Agile Modeling Technique Using the Sixth Normal Form. 2010.
Типы доказательств:
| Утверждение | Тип | Источник |
|---|---|---|
product является устойчивой сущностью, отделённой от определений | ПНУ | ISO 10303-239 |
| Идентичность CI стабильна, данные изменяются | ПНУ | ANSI/EIA-649-D §3.2 |
| Изделие является предметом производства | ТО | ГОСТ Р 2.101-2023 |
| Объект существует как KObject с единственным идентификатором | ЛВА | Архитектурный принцип Constructum |
| KObject не содержит прикладных свойств, имени, владельца или административного состояния | ЛВА | Архитектурный принцип Constructum |
| Конкретный тип объекта определяется наследником KObject | ЛВА | Архитектурный вывод книги |
| KObject является базовым классом всех объектов модели | ЛВА | Архитектурный принцип Constructum |
| Устойчивое существование и изменяемое знание не должны быть одной сущностью | СС + ЛВА | ISO 10303-239, NPDM, Rönnbäck et al. |
| KObject является точкой сборки информации для распределённой системы | ЛВА | Архитектурный вывод книги |
| Сущности вокруг KObject не являются его внутренними полями | ЛВА | Архитектурный принцип Constructum |