Комментарии 186
легко, класс Трасса содержит свойство «участки_Лэп» которое является коллекцией элементов с типом «Участок_Лэп», с композицией в ООП нет сложностей.
«почему-то мы не можем делать обратной операции – композиции процессов в операции»
потому что на верхнем уровне весь объект целиком, а дальше происходит декомпозиция — анализ.
ни кто не проектирует почтовый сервер от тела письма, проектируют от сервера в целом, от объекта который принимает письма ( композиция тела и заголовка ) и отправляет письма и служебные сообщения.
поэтому всегда анализ и ни когда синтез.
«необходимость разделить договор на части привела к переписыванию большой части кода»
изменилось ТЗ — изменилось решение, мне одному это кажется логичным?
как раз пытаться предусмотреть всё наперёд в программировании это очень не эффективная практика.
и именно удобство расширения и перестроения функционала и есть критерий качества работы программиста ( архитектора )
легко, класс Трасса содержит свойство «участки_Лэп» которое является коллекцией элементов с типом «Участок_Лэп»
Вы невнимательно прочитали условие задачи. Трасса не может содержать участки ЛЭП
И эти отношения, ПМСМ, определяётся тем, что у «трасса» является понятием более высокого уровня абстракции, чем «участки ЛЭП между опорами».
потому что на верхнем уровне весь объект целиком, а дальше происходит декомпозиция — анализ.
Неверно, в системной инженерии много времени посвящается тому, чтобы научить инженера синтезу, потому что инженер всегда находится между верхним и нижних холлонами. Если он об этом забудет, плохо ему будет.
Что такое "холлон"?
ни кто не проектирует почтовый сервер от тела письма, проектируют от сервера в целом, от объекта который принимает письма ( композиция тела и заголовка ) и отправляет письма и служебные сообщения.
Не понятно, при чем тут проектирование сервера. Статья о том, как мы анализируем предметную область. То, что в языке программирования нет возможности сделать синтез, — это ограничение языка. То, что программист не умеет делать синтез — это ограничение программиста.
проектируют исходя из бизнес требований в целом, переходя к конкретным бизнес требованиям, переходя к способам реализации конкретных требований в общих чертах (выбор технологий и методик), а потом уже в конкретных сущностях и конкретных действиях над ними.
Нет, это неверно. Тому. как мы мыслим, посвящены тома литературы. Для описания мыслительных процессов были введены термины синтез и анализ. Рассматривать только анализ — все равно, что рассматривать только правые части объектов. Понятно, что разделив объекты на правые и левые части, мы снова получим правые и левые части уже новых объектов. Поэтому аналогия такая: нет анализа без синтеза и нет синтеза без анализа. Эти два процесса — едины и неделимы. То, что синтез был исключен, — скорее признак непонимания того, как мы мыслим и моделируем.
изменилось ТЗ — изменилось решение, мне одному это кажется логичным?
Стандартная отговорка. Если бы аналитик, проектирующий систему, был бы прозорливее, этого бы не случилось. Если бы алгоритм поиска листочков был бы заменен на другой, более осмысленный, этого не случилось.
как раз пытаться предусмотреть всё наперёд в программировании это очень не эффективная практика.
Верно, но к теме разговора не имеет отношения. Я показал, где располагаются стандартные грабли, которые можно избежать, если не рассматривать объекты, как конечные элементы. А пользоваться этим знанием, или нет — решает каждый для себя.
Весьма впечатлен, коллега. Ваша статья из серии "точек кристаллизации" — позволяет различным кусочкам пазла сложиться в единую картинку. Вроде бы все слова давно знакомы — декомпозиция, анализ, синтез, объекты, функции, операции, а вот в такой комбинации приобретают интереснейшую форму.
Как-то в практике решения различных задач принято, что верный ответ должен быть один. Хотя сложные задачи имеют более одного правильного решения, оптимальность которых зависит от критериев оценки этой самой оптимальности (по размеру кода, скорости выполнения, потребляемым ресурсам). В латвийской школе (про российские не знаю), кстати, сейчас попадаются задачи, в которых нет однозначного ответа — оценивается логичность мышления, а не найденный ответ. Поначалу вводило в ступор, когда сын задачки показывал — непривычно.
Вопрос границ применимости предлагаемых решений — весьма недооценен, КМК. И чем сложнее разрабатываемые системы, тем больше вероятность, что на одни и те же вещи придется смотреть с разных точек зрения (представлять их разными программными конструкциями).
В латвийской школе (про российские не знаю), кстати, сейчас попадаются задачи, в которых нет однозначного ответа — оценивается логичность мышления, а не найденный ответ. Поначалу вводило в ступор, когда сын задачки показывал — непривычно.
А поделитесь задачками.
К сожалению не смогу :( Давно это было, сын уже институт заканчивает. Помню, что меня поразил сам факт наличия в школьном учебнике задачи с неоднозначным решением. Я ему еще тогда авторитетно объяснял, насколько калечит мышление молодого поколения такой вот подход. Каждая задача, мол, имеет одно единственное верное решение и главное — его найти. Каюсь, был неправ.
Но, если навскидку, то путей в лабиринте от входа до выхода может быть более одного. Какой из них правильный?
Сын подсказал еще вариант — тесты на знание Правил Дорожного Движения. Если есть свод правил с противоречащими пунктами (любой кодекс, если покопаться, имеет противоречащие пункты), то на их основании можно сформулировать задачи, имеющие более одного (не)правильного решения — зависит от порядка применения противоречащих пунктов. В народе даже поговорка сложилась "закон — что дышло: куда повернёшь — туда и вышло"
Состав и взаимное расположение частей какого-либо сооружения, механизма.
Само сооружение или механизм с таким устройством.
Второе понятие термина «конструкция» значит следующее: конструкция — это объект, который может быть представлен в виде множества объектов.
По-моему, второе понятие используется в отношении самого слова "конструкция". "Берем вот эту конструкцию", "Доходишь до той конструкции, потом налево".
Если там другое слово, то оно используется в первом значении, либо обозначает сам объект, без указания его строения.
Поскольку код был завязан на сущности типа «договор» как на атомарные сущности, необходимость разделить договор на части привела к переписыванию большой части кода.
Интересно, а что вы предлагаете? Предельные атомарные сущности всегда будут, бесконечно делить нельзя.
И возможно тут просто спроектировано было неправильно. Внутреннее устройство сущностей не должно быть доступно снаружи. А если недоступно, то и менять его можно, не переписывая внешний код, разве что пару методов придется добавить для работы с дочерними сущностями.
Если круг задач очерчен, то попытка решить задачу, выходящую за этот круг, должна приводить к изменению стандарта, или отказу от него.
Вот мне надо решить задачу, а стандарта нет. Другому человеку тоже надо решить другую задачу, и на нее стандарта тоже нет. Предлагаете вводить 1000 стандартов на все случаи жизни, которые будут отличаться в нескольких пунктах? Или вообще не решать задачу?
Предельные атомарные сущности всегда будут, бесконечно делить нельзя.
Создание атомарных единиц — это костыль. Просто надо помнить об этом. Как и любой другой костыль, он может выстрелить, а может и нет.
Я повторю вопрос, раз вы его проигнорировали. Что вы предлагаете взамен?
Мы легко справляемся с подобными задачами, потому что выделяем объекты на разном уровне детализации предметной области. На некотором уровне нам удобно работать с картинкой как с атомрным файлом, на другом как с объектом, состоящим из пикселей. Но и там и там у нас есть объект, который считается атомарным. И в программировании делается абсолютно точно так же.
Вы уходите от ответа. Вы сказали, что надо не делать, но не сказали, что надо делать. Все алгоритмы строятся на принципах логики. Вот есть ваш пример с договорами. Там договор это понятие нижнего уровня. Что вы предлагаете использовать вместо него? Разделить договор на буквы? Или на более мелкие договора? Но тогда буквы или мелкие договора станут новыми атомарными единицами.
Когда мы мыслим, мы легко справляемся с задачей поиска нужных нам сущностей. Для этого надо выяснить, как мы это делаем и записать эти правила в коде.
А, я кажется понял, в чем ваша ошибка. Когда мы мыслим, мы рассматриваем уже существующие объекты. Поэтому при необходимости мы можем рассматривать их на более низком уровне и находить там новые листочки.
А когда мы моделируем это на компьютере, мы сначала должны аналогии реальных объектов (модели) создать в оперативной памяти. Мы не сможем это сделать, если не будем знать точное устройство на всех (интересующих нас) уровнях абстракции.
Но есть и другая ошибка. Вы говорите "Потому что листочки могут поменяться в любой момент и тогда то, что раньше выдавалось в результате алгоритма, изменится". Так значит, до этого момента мы считали некоторые объекты листочками, атомарными сущностями, и это нас устраивало. В программировании, даже в ваших примерах, именно так и происходит. Выделяется то, что считается листочками. При уточнении задачи выделяются новые листочки. Вся наука о современном программировании сводится к управлению сложностью. То есть, как сделать так, чтобы при добавлении новых листочков не пришлось переписывать половину программы. При правильном проектировании это достижимо. Поэтому я и предположил, что в примере с договорами программа была спроектирована неправильно.
А когда мы моделируем это на компьютере, мы сначала должны аналогии реальных объектов (модели) создать в оперативной памяти. Мы не сможем это сделать, если не будем знать точное устройство на всех (интересующих нас) уровнях абстракции.
Данное ограничение — лишь плод нашего воображения и инструмента программирования, основанном на концепции ООП. Есть и другие подходы к программированию, которые позволяют преоболеть это ограничение: Функциональное программирование: в Java и C# слишком много церемоний
Эта статья никак не связана с тем, о чем вы говорите. В функциональных языках тоже есть базовые типы, на основе которых строятся остальные. И там тоже надо описывать все это вручную.
Это не плод воображения, это физический принцип. Вы принципиально не сможете описать состав объекта до бесконечной детализации. Вы можете создать в оперативной памяти пустой объект вообще без свойств, и работать с ним, пока вас не заботит его строение, но он в данном случае будет тем листочком, которых вы хотите избежать. В можете даже вообще не создавать объектов, а работать только с типами, но и они будут этими листочками. А когда вам надо будет зарегистрировать конкретного клиента, у вас появятся объекты со свойствами "Имя", и эти свойства тоже будут листочками. Раз уж вы упорно не хотите отвечать на вопросы, я рекомендую вам хотя бы самому задуматься над тем, как можно реализовать то, о чем вы говорите. Написать текст с описанием типов на бумаге. И вы поймете, что принципиально по-другому сделать нельзя. Отличия буду лишь в деталях.
Насколько я понял, коллега maxstroy имеет в виду, что один объект реального мира может в приложении моделироваться множеством программных объектов/типов. Причем каждый программный объект описывает со своей точки зрения тот же самый объект, что и остальные программные объекты из этого множества. А приложение должно само выбирать, с какой программной моделью реального объекта ему сейчас наиболее удобно работать. Это как классическая и релятивистская механики — говорим об одном и том же (движение), но с разных точек зрения (субсветовая скорость или обычная).
Коллега michael_vostrikov же говорит о том, что программная модель является лишь приближением к реальной до некоторого уровня детализации и принципиально невозможно сделать универсальную программную модель реального объекта.
Совмещая обе точки зрения в применении к примеру с (не)делимым договором, в приложении может быть два алгоритма — для работы с сущностями, как с атомами, и для работы с ними же, как с композитами. И приложение само, в зависимости от контекста, может выбирать, является ли объект "договор" в текущем контексте атомом (листом дерева) или композитом (узлом дерева).
Но моя статья и не про программирование. Если в программе нельзя иначе, это не отменяет того, что в предметной области можно. А, следовательно, должно быть возможно и в стандартах моделирования предметной области.
Программирование — это тоже моделирование. И довольно гибкое. Если уж нельзя в программировании, то о каком "моделировании предметной области" вы сейчас говорите?
Не, я немного о другом. Я о том, что атомарные понятия будут всегда, так же как они есть в любой предметной области.
Так понятия и обозначают объекты. Либо их типы. Атомарные понятия обозначают атомарные объекты.
Избежать атомарных объектов нельзя. Вы не привели примера который доказывает обратное.
атомарные объекты в природе не существуют
Они существуют в нашем представлении о природе. В природе вообще объектов нет, есть только материя и энергия. Тем не менее, мы выделяем в окружающей нас материи некоторые объекты. Строение части из них нас в некоторых ситуациях не интересует. Следовательно, в этих ситуациях это атомарные объекты. И на разном уровне абстракции это будут разные объекты.
Я думаю, что должны быть и фрейворки, которые не ограничивают нас в степени детализации.
Поскольку я знаю, как минимум, одну систему, в которой я сейчас работаю, которая позволяет строить бесконечную детализацию объектов
В программировании вас тоже никто не ограничивает в степени детализации. Сколько хотите, столько и детализируйте. Поскольку делать это бесконечно у вас не получится, в какой-то момент вы остановитесь. И вот когда вы остановитесь, у вас на этом уровне будут атомарные объекты, строение которых вы еще не описали.
Кстати, приведите пример описания ЛЭП в этой системе. Я вам покажу, где именно там атомарные объекты.
Не меняется то, что называется английским словом identity. И именно это мы связываем с объектом в целом.
Насколько я понял, предполагается в приложении иметь различные модели (с различным набором атрибутов) для одного и того же identity.
Так с этим сейчас нет никаких проблем. Задаете в моделях один identity и все.
Ага, так и есть. Вот только иметь в программе два разных типа к одному моделируемому объекту на данный момент большинству программистов "религия не позволяет". Это как иметь в БД две таблицы с различными атрибутами для одной и той же сущности User. Это же бред? Бред. Вот и сливают все атрибуты из различных моделей User'а в одну таблицу и делают одну общую, универсальную модель. Так кошерно.
Ну почему же, есть понятие table inheritance, на одном id висят разные атрибуты. Только это больше про расширение, то есть например, объект недвижимости — (квартира | загородная недвижимость).
Просто если атрибуты разные, значит это разные точки зрения, конструкции в терминах автора. Вот с ними и работают. А на родительский объект ссылаются по id. Неправильно называть разные конструкции одним и тем же понятием (User), обозначающим весь объект.
Неправильно называть разные конструкции одним и тем же понятием (User), обозначающим весь объект.
Вот и я за то — иметь в программе два разных типа к одному моделируемому объекту на данный момент большинству программистов "религия не позволяет"
А на родительский объект ссылаются по id.
А вот это "религия позволяет". И если у двух разных конструкций (типов) есть совпадение по атрибутам, то ООП-религия позволяет нам ввести промежуточную конструкцию с общими атрибутами и назвать ее "абстрактным типом". И сделать для нее отдельную таблицу и встроить ее в цепочку наследования тоже допустимо.
Это как иметь в БД две таблицы с различными атрибутами для одной и той же сущности User. Это же бред? Бред
Не бред, а связь 1:1
Связь чего с чем? Левых атрибутов User'а с правыми?
Например, связь паспортных данных юзера с его аутентификационными.
Паспортных с аутентификационными или аутентификационных с паспортными? Кто на кого ссылается? Где находится identity для экземпляра User'а — в паспортных данных или аутентификационных? Могут ли паспортные существовать без идентификационных и наоборот?
Пускай будет двухсторонняя связь на уровне объектной модели. identity хранится в обеих, по нему и осуществляется связь.
И что мы имеем в итоге? Две независимые таблицы, каждая из которых имеет свой набор полей, включающий identity-поле, по значению которого и осуществляется сопоставление данных из одной таблицы данным из другой. Никаких внешних связей (foreign keys) друг с другом на уровне структур базы данных. Связывание данных идет в объектной модели на программном уровне.
CREATE TABLE user_auth (
id int(10) UNSIGNED NOT NULL,
username varchar(255) NOT NULL,
...
PRIMARY KEY (id)
);
CREATE TABLE user_pass (
id int(10) UNSIGNED NOT NULL,
firstname varchar(255) NOT NULL,
...
PRIMARY KEY (id)
);
Но ведь именно это я имел в виду, говоря "бред". А вы что имели в виду, говоря "связь 1:1"?
Эти две таблицы представляют собой одну сущность User. Разные аспекты этой сущности нужные для разных задач, но сущность одна. В чём бред?
Сложнее всего отвечать на вопросы, имеющие очевидный ответ :) Где у вас ведется учет идентификаторов для новых экземпляров сущностей User — в user_auth, в user_pass, в приложении (в каком экземпляре, если идет балансировка нагрузки)? И что будет, если два процесса одновременно вводят разные данные (auth & pass) по одному пользователю?
Если для вас в подобной конфигурации бред не очевиден, то, скорее всего, мы с вами в наших профессиях ходили разными дорогами.
В зависимости от потребностей либо оба экземпляра создаются одновременно, в рамках одной транзакции с одним идентификатором, либо один создаётся на базе другого, используя его идентификатор. Как вариант — для обоих классов создать базовый абстрактный класс, хранящий только идентификатор.
Вот видите, приходится выделять "ведущего" (генератор значения для identity) и от него уже плясать. Можно хоть по одной таблице на атрибут сделать (что, кстати, 6NF и предусматривает), но identity values должны хранится в одном месте, если вы хотите обеспечить их уникальность и консистентность.
Этот подход не является единственно возможным, но является достаточно классическим — как надевать штаны через ноги. Другие варианты, повторюсь, также существуют и некоторые даже имеют своих адептов.
Генератор значений может быть и без выделения ведущего класса (в т. ч. абстрактного), может быть любой генератор, задача которого выдавать серию абстрактных или не очень значений (uuid хоть на клиенте, sequence в СУБД и т. п.). Уникальность и консистентность обеспечивать совсем не обязательно средствами СУБД, более того, некоторые считают плохим тоном вообще выносить логику в СУБД — данные и индексы только там должны быть.
Скорее одну модель моделируемой сущности, разбитую на несколько объектов, связанных между собой по идентифицирующим свойствам.
Вот мне надо решить задачу, а стандарта нет.
Я говорю про тот случай, когда пытаются применить стандарт к тем задачам, к которым он не применим. Если стандарта нет, то и применять нечего.
Вот есть некоторый набор стандартов. Есть задача, к которой не применим ни один стандарт, так как часть подзадач выходит за их рамки. Вы предлагаете не делать по наиболее подходящему стандарту даже ту часть, к которой стандарт применим? И как решать другую часть?
второе понятие используется в отношении самого слова «конструкция»
Нельзя использовать понятие в отношении термина. Это — бессмысленное выражение. Мы используем термин для обозначения понятия, но не используем понятие в отношении термина.
Ок, я перефразирую. Фраза "Само сооружение или механизм с таким устройством" относится к слову "конструкция", а не к названиям объектов, которые можно обозначить этим словом.
Я хочу сказать, что вы привели определение из словаря. Определения в словарях относятся только к самому слову, а не к другим словам. Потому что для других слов в словарях есть свои определения. Относится — значит набор слов является определением (толкованием) только этого слова, и может применяться только если в выражении есть именно это слово.
Второе определение говорит, что словом "конструкция" можно обозначить сооружение или механизм. Первое — что им можно обозначить строение сооружения или механизма. Вот смысл понятия "строение" вы и анализируете, что в общем-то и правильно.
Давайте запишем само определение в более формальном виде:
К:
1) (С и ВРЧ) любого (Соор).
2) (Соор) имеющее (1)
Как видим, во втором определении есть ссылка на первое. В нем не вводится новая информация касательно смысла слова (как связи между другими понятиями), только информация касательно его использования в тексте.
Обобщенная конструкция обозначает множество объектов, связанных между собой связями, но не обозначает синтезированный на этом множестве объект.
Обобщенная конструкция может включать в себя множество элементов, состоящее из любого количества объектов. Это значит, что может быть пустое множество, множество, состоящее из одного объекта, множество, состоящее из счетного количества объектов…
Множество может состоять из множеств объектов.
Объекты могут быть любой природы.
Оффтоп. Похоже на описание массивов из PHP)
количество конструктивных элементов самолета
Приписать его самолету(о) нельзя, потому что разделить самолет на части можно множеством способов. Поэтому, это атрибут должен быть отнесен ко множеству объектов, но не к объекту.
Правильно. В любом массиве есть признак количества (свойство length, size или count). В программировании это заключение логично вытекает из самого устройства массивов как инструмента моделирования.
Кстати, интересно, почему нет термина «система объекта» по аналогии с термином «конструкцией объекта»?
Потому что это тавтология. Объект уже сам система. Конструкция это описание системы. Поэтому есть термин "конструкция системы".
Можно сказать, что физический, но, если заказчик скажет, что функция этого участка – перенос энергии на расстояние, то участок ЛЭП между опорами станет функциональным объектом, и смоделировать две разные конструкции одной ЛЭП не удастся.
Чего это не удастся? Есть такое понятие "контекст". В разных контекстах один термин может обозначать разные понятия. Если надо объединить термины в глобальную систему, то к термину добавляется контекст.
ЛЭП (Функ.) = энергия { энергетические характеристики и их связи }. ЛЭП (Физ.) = материалы {опоры, провода, крепления, и их размеры}.
Проблема с ООП программированием та же: конструкция в ООП моделируется при помощи агрегации объектов, фактически, связей «часть-целое» Я не могу представить себе в ООП объект, который может быть представлен в виде разных конструкций.
Раз вы его знаете плохо, то вполне логично, что представить это не можете. Это никак не влияет на возможности самого ООП.
Разные конструкции представляются разными типами. Объединяются через композицию в более общем типе. Или делается процедура, в которую передается требуемый контекст и данные, и она возвращает объект нужного типа.
Смотрите пример с электриком и строителем в комментах к прошлой статье. Это один из вариантов реализации.
Как в ООП смоделировать тот факт, что ЛЭП состоит из трасс и одновременно состоит из участков ЛЭП между опорами?
Трасса состоит из участков, поэтому тут все просто.
type ЛЭП
{
Трасса[] $трассы;
}
type Трасса
{
Участок[] $участки;
}
Сложнее описать то, что ЛЭП может быть представлена и как система передачи энергии и как набор физических объектов. Здесь вы в какой-то степени правы. Но это не невозможно. И вполне работает в реальных программах.
type КонструкцияЛЭП
{
}
type ЛЭП_Функ: КонструкцияЛЭП
{
int $длина;
int $напряжение;
}
type ЛЭП_Физ: КонструкцияЛЭП
{
Трасса[] $трассы;
}
type ЛЭП
{
КонструкцияЛЭП $конструкция; // ЛЭП_Функ или ЛЭП_Физ, задается при создании экземпляра
}
// либо
type ЛЭП
{
ЛЭП_Функ $функциональноеСтроение;
ЛЭП_Физ $физическоеСтроение;
}
// либо
type ЛЭП
{
ЛЭП_Функ создатьФункциональноеОписание($данные) {...}
ЛЭП_Физ создатьФизическоеОписание($данные) {...}
}
Можно еще пару вариантов придумать. Но часто работают просто с отдельными типами ЛЭП_Функ и ЛЭП_Физ, не объединяя в общий тип ЛЭП, потому что этот факт ничего особо не дает для выполнения программы. Просто описывают в комментариях или размещают рядом в одном пакете или пространстве имен.
В функциональных языках это описывается проще. Что-то типа:
ЛЭП = ЛЭП_Функ | ЛЭП_Физ
В моем определении объект – это нечто, что мы воспринимаем как неизменное, но, что на самом деле изменяется, поскольку в природе нет ничего неизменного.
Объект, это то, что может менять характеристики, оставаясь в нашем понимании тем же самым объектом. То есть, объект имеет поведение. Понятие объекта основано на изменяемости. Вернее, на выделении неизменяемого в информации. В пределе неизменяемым остается только наличие понятия, с которым связаны некоторые события и пространственно-временные характеристики.
В английском это называется identity. В терминах баз данных это первичный ключ объекта.
Это объекты-сущности, также есть объекты-значения. Объект-значение это данные, при изменении которых мы говорим о другом объекте. Например, числа, строки, даты. Объекты-сущности сохраняют свою уникальность при изменении свойств.
Правильно. В любом массиве есть признак количества (свойство length, size или count). В программировании это заключение логично вытекает из самого устройства массивов как инструмента моделирования.
Но я ни разу не видел, чтобы массивы одного типа были поименованы, сложены в БД. Их можно построить в виртуале, но сохранить их как? Как им присвоить ID?
Таблица это один большой массив. Строка в таблице это тоже массив. В некоторых БД можно хранить массив в ячейке.
Массив комментариев к статье, сложенный в БД выгядит так:
articles:
id title
1 Статья1
2 Статья2
comments:
id article_id text
11 1 Комментарий 1
12 1 Комментарий 2
13 2 Комментарий 3
14 2 Комментарий 4
article_id выступает как id массива комментариев к этой статье. При запросе с article_id = N вернется этот массив. Логически там можно рассматривать связь 1 к 1 между article и массивом комментариев к ней, у которого может быть свой id, который и будет в таблице comments, но обычно так никто не делает, потому что это только вносит избыточность.
article_id это id объекта, а не сам объект. Количество объектов в массиве присутствует всегда, иначе мы не могли бы работать с ними. Средняя скорость это статистические данные. Но да, ее можно присвоить массиву как отдельному объекту. Можно рассчитывать каждый раз на лету. Можно хранить эту статистику в article. Можно ввести связь 1:1, про которую я говорил, и хранить эту статистику в новой таблице.
Более подходящий пример это понятие "Список избранного" в интернет-магазинах. У пользователя может быть несколько списков избранного с разными названиями. У каждого списка есть id, который и используется как id массива товаров. Также у списка могут быть любые другие атрибуты — средняя цена товаров и прочее.
Это если говорить про базы данных. Если говорить про моделирование в оперативной памяти компьютера, то все еще проще. Количество элементов массива где-то хранится, значит таким же образом можно хранить любые другие связанные атрибуты.
Но речь изначально шла о том, куда отнести атрибут количества. Я и указал, в программировании такого вопроса не возникает.
Поэтому есть термин «конструкция системы».
Переводится это так: конструкция(к) системы(о)
Неважно, как это переводится, важно, что ваши определения не сходятся с существующими терминами.
Есть название "конструкция объекта", есть название "конструкция системы". "Объект" и "система" используются в одинаковом смысле, в отличии от "конструкции". Потому употребление их в одном выражении это тавтология (наверно, слово плеоназм больше подходит).
Чего это не удастся? Есть такое понятие «контекст». В разных контекстах один термин может обозначать разные понятия. Если надо объединить термины в глобальную систему, то к термину добавляется контекст.
ЛЭП (Функ.) = энергия { энергетические характеристики и их связи }. ЛЭП (Физ.) = материалы {опоры, провода, крепления, и их размеры
Речь шла про стандарт ИСО 15926, и коллизию, которая возникает при делении одного и того же функционального объекта на разные конструкции, состоящие из объектов одного типа (например, функциональные). ИСО 15926 не позволяет это сделать, насколько я понимаю.
Разные конструкции представляются разными типами. Объединяются через композицию в более общем типе. Или делается процедура, в которую передается требуемый контекст и данные, и она возвращает объект нужного типа.
Я уже отвечал, что при помощи ассемблера можно решить все задачи, которые мы имеем. Я говорю, что агрегация в ООП не позволяет нам выполнить множественность точек зрения на конструкции, потому что объект «конструкция» в языке пропущен и нам его приходится кодить вручную. Это значит, что ООП не предназначено для моделирования предметных областей. Про код — конечно, написать мы можем что угодно на любом языке.
Объявление составного типа в ООП это и есть задание конструкции.
Как это можно решить все задачи, если ООП не позволяет некоторые из них смоделировать? Раз можно решить, значит и модель подходящая. Если бы модель была неправильная, то задача бы не решалась.
Как сделать множественность конструкций я пример привел. Если у него есть недостатки и он по каким-то причинам не подходит для решения задачи, укажите их. Иначе будем считать, что множественность конструкций смоделировать можно.
Как это можно решить все задачи, если ООП не позволяет некоторые из них смоделировать?
Решить любую задачу можно в ассемблере. Вопрос: встроены ли те конструкции, которые нам нужны в язык ООП, или мы должны писать их сами? И, если мы должны писать их сами, зачем нам костыльные решения от ООП?
Затем, что с помощью этих "костыльных" решений мы можем эти конструкции написать? И потом вносить в них изменения соответственно изменившейся модели?
И почему все средства должны быть встроены в язык? Язык программирования в принципе создан, чтобы можно было описать те конструкции, которые нам нужны, самим. Это не сборник решений на все случаи жизни, он только предоставляет технические и логические средства.
Можно еще пару вариантов придумать. Но часто работают просто с отдельными типами ЛЭП_Функ и ЛЭП_Физ, не объединяя в общий тип ЛЭП, потому что этот факт ничего особо не дает для выполнения программы
Мне надо, чтобы это были объекты одного типа, потому что в предметной области — это предметы одного типа. Конструкции могут пересекаться, сходиться и снова расходиться. Если для этого надо костылить, я не против, надо просто понимать, что это костыли.
В этом примере ЛЭП_Функ и ЛЭП_Физ имеют один общий тип КонструкцияЛЭП. Про любые объекты этих типов можно будет сказать, что они имеют тип КонструкцияЛЭП. В условиях задачи "функциональное описание ЛЭП" и "физическое описание ЛЭП" являются конструкциями ЛЭП.
Что в вашем понимании костыли? Пока что я никаких расхождений с вашими определениями не замечаю.
Сама ЛЭП не может быть одного типа с какой-либо конструкцией, потому что в одной конструкции могут отсутствовать элементы другой конструкции, но в объекте они все есть.
Причин много: от того, что он сначала описывает тип объектов, а затем их создает, а не наоборот,
Как вы создадите объект, не описывая из чего он состоит?
заканчивая тем, что методы принадлежат объектам, что тоже неверно
Во-первых, у объектов могут быть методы. Действия, которые они совершают. Даже у неодушевленных. Во-вторых, это просто группировка методов по связи их с объектом. Это нужно для управления сложностью. Проще иметь 10 типов и по 10 процедур в каждом, чем иметь 100 процедур и группировать их мысленно (вот эти работают с этим типом, эти с этим, эти с тем). Отнесение методов к объектам просто отражает эту мысленную группировку. То есть, это тоже часть моделирования.
Костыль — это все, что пишется нами вручную.
Я рассмотрел лишь один аспект ООП, который нам не подходит — необходимость создавать конструкции вручную, в то время, как, вроде, языки постулируют такую возможность, зашитую в коде.
Я не понимаю, что вы хотите этим сказать. В любом языке моделирования мы расставляем стрелочки вручную. В языках программирования стрелочек нет, там связи обозначаются по-другому. Как вы себе представляете возможность, зашитую в коде? То есть, как это по-вашему должно выглядеть в языках программирования?
Это значит, что ООП должно признать, что стандартные методы написания кода не моделируют предметную область
Почему оно должно это признать, если это не так? Потому что в нем стрелочек нет?
И я спросил не про это, вы снова уходите от ответа. Я спросил, как по-вашему должна выглядеть эта возможность, зашитая в коде? Как должно выглядеть в примере с ЛЭП описание типов в текстовом виде, чтобы это не было в вашем понимании костылем? У вас есть ответы на эти вопросы?
Должна быть явно выделена отдельная сущность — конструкция так, что один объект имел бы множество конструкций.
Абстрактный класс с множеством наследников?
А мы не воссоздаём природу, мы её моделируем. И в природе ничего не называется, называется в нашем мозгу. Названия — суть абстракции.
Естественным мышлением вы называете оперирование подмножествами, типами, классами, предикатами и т. п.? Естественное мышление субъективно, ситуативно и, как правило, не формализовано. Попытки создать единую формальную онтологию для всего на свете или пускай какой-то одной предметной области — это уже искусственное мышление :) Как аналитику вам должно быть известно как трудно бывает вытащить из заказчика (внутренний или внешний — не суть), экспертов предметной области и т. д. даже точную формулировку задачи так, чтобы не был опущен ни один нюанс даже текущих процессов без всякого закладывания фундамента под будущее развитие. Любая формализация приводит к отклонениям от естественного мышления, поскольку загоняет его в рамки, ООП не исключение, но и не единственное исключение.
Мы моделируем предметную область на основании информации, полученной от экспертов предметной области с помощью средств, предоставляемых языком — это наша основная обязанность. ООП с элементами ФП — мэйнстрим сейчас.
Грубо, нравится вам и нам это или нет, но иных средств моделирования у нас нет. Бывает, что между экспертами и нами вклиниваетесь вы, аналитики, и моделируете с помощью доступных и удобных вам средств, а мы, программисты прикладные, переводим модель с вашего языка на наш. Но всё равно результат нашей работы — модель предметной области на каком-то ЯП, скорее всего ООП с элементами ФП. Ещё, конечно, инфраструктурный код, пользовательские и программные интерфейсы, но главное — бизнес-логика.
Должна быть явно выделена отдельная сущность — конструкция так, что один объект имел бы множество конструкций.
Хорошо, и как же мы опишем различные конструкции ЛЭП? Придумайте свой язык, в котором эта возможность уже есть. Вы можете привести конкретный текст, как это должно быть сделано в этом языке?
По описанию это похоже на любую программу с ООП и переопределением методов в производных типах. Напишите пожалуйста конкретный текст на вашем языке, чтобы можно было оценить отличия.
При этом. если при перекладке в код, я слышу термины, отличные от терминов предметной области, я понимаю, что мы натолкнулись на ограничения языка.
Совсем не обязательно, может быть просто разная терминология. Вы говорите "табуретка" имея в виду конкретную табуретку из множества табуреток, а мы говорим "экземпляр табуретки" или "инстанс класса Табуретка" имея в виду то же самое.
Почему в коде не может быть своих названий для тех понятий, которые есть в предметной области? А если ваше описание переведут на английский, вы тоже скажете, что мол язык у них неправильно описывает предметную область, говорят не тип а тайп?
Русский — это не формальный и не технический язык. Часть формализации берет на себя мозг, и во многих случаях мы ее даже не осознаем. В частности, это работа с контекстами. Если вы хотите описывать предметную область формально, вам нужны термины и выражения, которых может не быть в обычном русском. Понятие типов и экземпляров относится сюда же.
Система, описывающая другую систему, должна быть более широкой, чем описываемая. В пример можно привести сам русский язык. Сначала говорили собака, кошка, дерево. Когда язык стали изучать, появилось понятие "существительное".
Я не просил написать этот язык программирования, я просил просто описать типы текстом. Тогда не надо говорить, что программирование описывает что-то неправильно, если сами не знаете, как описать правильно. А вообще, раз уж это смежная область, с которой вы работаете, то неплохо было бы разобраться. Чтобы не вводить в заблуждение тех, кто работает с вами.
Объект, это то, что может менять характеристики, оставаясь в нашем понимании тем же самым объектом.
Главное — в нашем понимании, в понимании другого — это функция, а в понимании третьего — операции. Так что тут кто как хочет, так и понимает.
Нет, это не главное. То, что вы говорите, больше похоже на конструкции. Часть объекта и его поведения вполне можно рассматривать как функцию. Но в ней будут свои объекты, которым будут соответствовать свои термины.
Река — это объект в любом случае. Как минимум потому что это понятие имеет определенное название, которое его обозначает, и это название существительное. Неважно, в каком контексте мы используем слово "река", мы обозначаем им объект, который из чего-то состоит. Если он состоит из операций, значит в этом контексте мы рассматриваем этот объект как набор операций. Вернее, мы считаем, что в этом контексте данный набор операций можно считать одним объектом "река".
Объект — это то, что мы воспринимаем как неизменное, даже если его характеристики меняются. Поэтому если в описание реки "Волга" добавится еще одна операция, мы не станем считать, что это новая река.
Река — это объект в любом случае. Как минимум потому что это понятие имеет определенное название, которое его обозначает, и это название существительное.
В общем и в целом, нарицательные существительные в моделировании являются не объектами, а классами объектов, типами. Исключения — это решения лингвистических и подобных задач. В остальных случаях нарицательное существительное либо требует конкретизации (инстанцирования), чтобы рассматривать его как объект, либо не обладает идентичностью вообще, являясь значением.
Объект — это не то, что мы воспринимаем как неизменное, а то, что мы воспринимаем как обладающее протяженной во времени идентичностью, не смотря на любые изменения.
Да, я примерно это и имел в виду. Идентичность не меняется. Про типы я тоже не стал вводить лишнюю сложность, потому что пришлось бы снова упоминать экземпляры. У вас более правильное описание.
Объект — это не то, что мы воспринимаем как неизменное
Да именно! Кто-то воспринимает фонтан как статический объект, а кто-то как динамический. Объект один и тот же, но один воспринимает его как статику, а второй — как динамику. Поэтому нельзя сказать, статичен объект или нет. В каком-то контексте — статичен, в каком-то динамичен. Все зависит от субъекта, который выбирает ту или иную точку зрения на него. Поэтому я утверждаю, что в природе нет статических объектов. Есть лишь упрощение, в котором динамический объект рассматрвиается в рамках ограниченного контекста как статический.
Вам никто и не говорил, что все объекты статические, или что объектом считается что-то статичное. Лично я вам сразу сказал, что у объекта есть поведение. Не меняется то, что называется английским словом identity. И именно это мы связываем с объектом в целом.
Поскольку состав – это множество, то первое понятие переводится так: конструкция — это множество объектов, связанных между собой связями.
Не переводится. Вы дали интерпретацию понятию «система». Давно и плотно изучается теорией систем. Конструкция характерна именно «взаимным расположением частей», задавая форму. Например, языковая система — это множество взаимосвязанных грамматически, фонологических и иных элементов. Но это не конструкция, пример языковой конструкции — конкретная фраза. Машиностроение — система материалов, передач и т.п. Трактор — конструкция.
При этом, судя по определению, объекты должны быть рукотворным и неживыми.
Конструкция — это не столько конечное состояние, но и процесс (хорошо описано в конструктивной математике). Логично, что в этом процессе участвует субъект. Который может быть безруким, что ставит под сомнение рукотворность. В мире широко используется подход, когда одни конструкции производят другие конструкции. Аналогично о неживом, разве живое — не плод эволюционного конструирования?
Или, более очевидный пример: молекула водорода, с одной стороны, состоит из атомов (одна система), а, с другой стороны – из ядер и электронов (другая система).
Плохой пример, неправильная декомпозиция, нарушение Закона Деметры, нарушение SRP. Молекула состоит из атомов, атомы из субатомных частиц. Если некоторый потребитель должен смотреть на молекулу в субатомном ключе, то вы можете использовать, к примеру, паттерн «Адаптер». А вместе с паттерном «Композиция» можно хоть на всю планету смотреть в таком разрезе.
В ООП нельзя построить даже двух разных конструкций одного объекта. Как в ООП смоделировать тот факт, что ЛЭП состоит из трасс и одновременно состоит из участков ЛЭП между опорами?
ЛЭП — это реальный технический объект, произведенный машиностроительной отраслью. В ней есть понятие конструктивной структуры (определяющее существование деталей, узлов, агрегатов). Чем ЛЭП и является по факту. Что не мешает ему иметь функциональную, кадастровую, бухгалтерскую и массу других ролей. ООП — аналог конструктивной структуры, но, как и в машиностроении — это лишь малая часть дисциплины дизайна информационных систем. Вы не строите множества разных конструкций, а обеспечиваете множество различных интерпретаций. Через интерфейсы/контракты, аспекты, структурные/поведенческие шаблоны проектирования и многое другое. Ничто не мешает внедрить в объект ЛЭП любое поведение, и, к примеру, бухгалтерия увидит её как инвентаризуемый объектом с автоматическим расчетом амортизации.
Конструкция характерна именно «взаимным расположением частей», задавая форму
Форму чего?
Например, языковая система
Это третье определение термина конструкция, которое я не приводил в рамках данной статьи, потому что это понятие выходит за пределы нашего обсуждения:
Языковая конструкция — словесные, стилевые или языковые конструкции, профессиональный термин в области лингвистики.
Конструкция — это не столько конечное состояние, но и процесс
Да, у меня об этом много написано. Но многие считают, что это не так.
Аналогично о неживом, разве живое — не плод эволюционного конструирования?
Не знаю, я пользовался теми опросами, которые я произвел. Надо будет расширить определение конструкции, расширим. Это не принципиально, потому что в обобщенную конструкцию поместится все, а только она мне интересна, как самый общий случай конструкций.
Плохой пример, неправильная декомпозиция, нарушение Закона Деметры, нарушение SRP. Молекула состоит из атомов, атомы из субатомных частиц
Даже тут вы сделали предположение, которое оказалось вашим субъективным — многие считают, что атомы состоят из ядра и электронов, а уже ядро — из нуклонов. Но, даже не это интересно. В химической физике при решении уравнения Шредингера не используют модели атомов, потому что оболочки электронов становятся общими и атомы перестают быть атомами. А вы, по прежнему, считаете иначе. Сколько дисциплин, столько мнений. Нельзя сказать, какая конструкция верная, какая ложная.
Вариант, который я привел замечательно работает, как в привычной всем системе координат (расскажите химикам, что они больше не могу рисовать бензольное кольцо так, как делали это последнее столетие), так и предоставить через приведенный в качестве примера паттерн «адаптер» информацию о частицах для использования в уравнении Шредингера. До вас просто не доходит, что атом рассматривается не как физическая структура, а как подсистема, обладающая определенными характеристикам (см. периодическую систему элементов Менделеева). И пока вы говорите о «мнениях в разных дисциплинах», я оперирую базовыми философскими категориями, которые существуют и работают тысячелетиями в этих самых дисциплинах.
Атом — это и объект и система субатомных частиц
Верно, что в разном контексте мы пользуемся разными значениями одного термина «атом». В каких-то случаях мы имеем ввиду множество объектов, в каких-то — объект.
объект может быть субъектом
Не понятно, потому что субъект — это что-то одушевленное, наделенное сознанием и самоосознанием. Как объект — неживое становится живым самоосознающим?
Вы какое определение субъекта используете? Хотя бы из какой области знания?
Во многом опять же сказывается ваш малый опыт в ООД, поскольку согласно принципу SRP вы старались бы не подмешивать «интерфейс» одушевленности к композиционному, а рассматривали бы их по отдельности.
Вы же на ISO 15926 не однократно ссылаетесь, значит хорошо с ним знакомы. Там активно используется RDF, а он целиком построен на утверждениях субъект-предикат-объект. Далеко не для одушевленных субъектов.
ЛЭП — это реальный технический объект, произведенный машиностроительной отраслью. В ней есть понятие конструктивной структуры (определяющее существование деталей, узлов, агрегатов). Чем ЛЭП и является по факту. Что не мешает ему иметь функциональную, кадастровую, бухгалтерскую и массу других ролей. ООП — аналог конструктивной структуры, но, как и в машиностроении — это лишь малая часть дисциплины дизайна информационных систем. Вы не строите множества разных конструкций, а обеспечиваете множество различных интерпретаций. Через интерфейсы/контракты, аспекты, структурные/поведенческие шаблоны проектирования и многое другое. Ничто не мешает внедрить в объект ЛЭП любое поведение, и, к примеру, бухгалтерия увидит её как инвентаризуемый объектом с автоматическим расчетом амортизации.
Не совсем понятно, как же разделить ЛЭП на части указанным мной способом в рамках одной интерпретации?
Обязательно почитайте про парадигмы MVC/MVP/MVVM. У меня стойкое ощущение, что вы вообще не понимаете отличия между моделью (M) и представлением (V). И вместо классической структуры одна модель + множество представлений вы пытаетесь создать полимодельную систему. ЛЭП можно рассматривать как множество пролётов, но множество пролётов в общем случае не является ЛЭП и не может являться её физическим представлением.
я очень хорошо представляю себе паттерн MVC, в котором у нас многие пытаются строить модели
Как-то странно звучит. Паттерн описывает как модель взаимодействует с остальным приложением, но ничего не говорит о том, как её строить, максимум определяет её область ответственности, без выделения которой говорить о применимости паттерна нет смысла.
Если вы оперируете объектами, а не их атрибутами, то для их представления вполне достаточно ID объекта и его типа/класса. Классические инструменты вполне позволяют это делать, если не закапываться в дебри. Ваша схема из статьи про ЛЭП/трассы/провода/участки очень хорошо укладывается в типичную RDBMS (MySQL в моем случае). Все, что с префиксом "obj" — это таблицы для желтых элементов вашей схемы, с префиксом "ctx" — для синих:
Вот SQL-код для построения структуры и заполнения ее данными:
DROP TABLE IF EXISTS ctx_uch_lep_as_uch_tr, ctx_provod_as_uch_prov, ctx_uch_tr_as_uch_prov, ctx_lep_as_uch_tr;
DROP TABLE IF EXISTS obj_lep, obj_trassa, obj_provod, obj_uch_lep, obj_uch_trassa, obj_uch_provod;
— — Objects (реестры объектов)
— CREATE TABLE obj_lep (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'ЛЭП';
CREATE TABLE obj_trassa (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'Трасса';
CREATE TABLE obj_provod (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'Провод';
CREATE TABLE obj_uch_lep (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'Участок ЛЭП между опорами';
CREATE TABLE obj_uch_trassa (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'Участок трассы между опорами';
CREATE TABLE obj_uch_provod (
id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
PRIMARY KEY (id)
)
COMMENT = 'Участок провода между опорами';
— — Contexts (контексты/конструкции)
— CREATE TABLE ctx_lep_as_trassa (
lep INT(10) UNSIGNED NOT NULL,
trassa INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (lep, trassa),
CONSTRAINT ctx_lep_as_trassa_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id)
ON DELETE CASCADE,
CONSTRAINT ctx_lep_as_trassa_to_trassa FOREIGN KEY (lep) REFERENCES obj_trassa (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 1: ЛЭП как трассы';
CREATE TABLE ctx_lep_as_uch (
lep INT(10) UNSIGNED NOT NULL,
uch INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (lep, uch),
CONSTRAINT ctx_lep_as_uch_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id)
ON DELETE CASCADE,
CONSTRAINT ctx_lep_as_uch_to_uch FOREIGN KEY (uch) REFERENCES obj_uch_lep (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 2: ЛЭП как участки';
CREATE TABLE ctx_trassa_as_provod (
trassa INT(10) UNSIGNED NOT NULL,
provod INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (trassa, provod),
CONSTRAINT ctx_trassa_as_provod_to_trassa FOREIGN KEY (trassa) REFERENCES obj_trassa (id)
ON DELETE CASCADE,
CONSTRAINT ctx_trassa_as_provod_to_provod FOREIGN KEY (provod) REFERENCES obj_provod (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 3: трасса как провода';
CREATE TABLE ctx_trassa_as_uch_tr (
trassa INT(10) UNSIGNED NOT NULL,
uch_tr INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (trassa, uch_tr),
CONSTRAINT ctx_trassa_as_uch_tr_to_trassa FOREIGN KEY (trassa) REFERENCES obj_trassa (id)
ON DELETE CASCADE,
CONSTRAINT ctx_trassa_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 4: трасса как участки трассы';
CREATE TABLE ctx_uch_lep_as_uch_tr (
uch_lep INT(10) UNSIGNED NOT NULL,
uch_tr INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (uch_lep, uch_tr),
CONSTRAINT ctx_uch_lep_as_uch_tr_to_uch_lep FOREIGN KEY (uch_lep) REFERENCES obj_uch_lep (id)
ON DELETE CASCADE,
CONSTRAINT ctx_uch_lep_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 5: участок ЛЭП как участок трассы';
CREATE TABLE ctx_provod_as_uch_prov (
provod INT(10) UNSIGNED NOT NULL,
uch_prov INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (provod, uch_prov),
CONSTRAINT ctx_provod_as_uch_prov_to_provod FOREIGN KEY (provod) REFERENCES obj_provod (id)
ON DELETE CASCADE,
CONSTRAINT ctx_provod_as_uch_prov_to_uch_prov FOREIGN KEY (uch_prov) REFERENCES obj_uch_provod (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 6: провод как участок провода';
CREATE TABLE ctx_uch_tr_as_uch_prov (
uch_tr INT(10) UNSIGNED NOT NULL,
uch_prov INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (uch_tr, uch_prov),
CONSTRAINT ctx_uch_tr_as_uch_prov_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
ON DELETE CASCADE,
CONSTRAINT ctx_uch_tr_as_uch_prov_to_uch_prov FOREIGN KEY (uch_prov) REFERENCES obj_uch_provod (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 7: участок трассы как участок провода';
CREATE TABLE ctx_lep_as_uch_tr (
lep INT(10) UNSIGNED NOT NULL,
uch_tr INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (lep, uch_tr),
CONSTRAINT ctx_lep_as_uch_tr_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id)
ON DELETE CASCADE,
CONSTRAINT ctx_lep_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id)
ON DELETE CASCADE
)
COMMENT = 'Конструкция 8: ЛЭП как участок трассы';
— — Данные (объекты)
— INSERT INTO obj_lep VALUES (1);
INSERT INTO obj_trassa VALUES (1), (2);
INSERT INTO obj_provod VALUES (1), (2);
INSERT INTO obj_uch_lep VALUES (1), (2);
INSERT INTO obj_uch_trassa VALUES (1), (2), (3);
INSERT INTO obj_uch_provod VALUES (1), (2), (3);
— — Данные (связи в контекстах)
— INSERT INTO ctx_lep_as_trassa VALUES (1, 1), (1, 2);
INSERT INTO ctx_lep_as_uch VALUES (1, 1), (1, 2);
INSERT INTO ctx_trassa_as_provod VALUES (2, 1), (2, 2);
INSERT INTO ctx_trassa_as_uch_tr VALUES (2, 1), (2, 2);
INSERT INTO ctx_uch_lep_as_uch_tr VALUES (1, 2), (1, 3);
INSERT INTO ctx_provod_as_uch_prov VALUES (2, 1), (2, 2);
INSERT INTO ctx_uch_tr_as_uch_prov VALUES (2, 2), (2, 3);
INSERT INTO ctx_lep_as_uch_tr VALUES (1, 1), (1, 2), (1, 3);
Если же вы захотите еще оперировать и атрибутами объекта, то вы можете добавить любое кол-во различных атрибутов (или наборов атрибутов, если они связаны друг с другом по отношению к объекту, как, например, Имя/Отчество/Фамилия). Вот структура для сохранения «номера трассы», например:
id INT(10) UNSIGNED NOT NULL,
value varchar(255) NOT NULL,
PRIMARY KEY (id),
CONSTRAINT obj_trassa_attr_num_to_obj FOREIGN KEY (id) REFERENCES obj_trassa (id)
ON DELETE CASCADE
)
COMMENT = 'Номер трассы';
Вам нужна гибкость? Пожалуйста. Но заплатите за нее простотой.
Картинку лучше открывать отдельно в новой вкладке, будет более читабельно. Схема данных навеяна Anchor Modeling.
Код переформатировался в комменте :( Исправил. Оба фрагмента объединены:
DROP TABLE IF EXISTS obj_trassa_attr_num; DROP TABLE IF EXISTS ctx_lep_as_trassa, ctx_lep_as_uch, ctx_trassa_as_provod, ctx_trassa_as_uch_tr; DROP TABLE IF EXISTS ctx_uch_lep_as_uch_tr, ctx_provod_as_uch_prov, ctx_uch_tr_as_uch_prov, ctx_lep_as_uch_tr; DROP TABLE IF EXISTS obj_lep, obj_trassa, obj_provod, obj_uch_lep, obj_uch_trassa, obj_uch_provod; -- -- Objects (реестры объектов) -- CREATE TABLE obj_lep ( id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ) COMMENT = 'ЛЭП'; CREATE TABLE obj_trassa ( id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ) COMMENT = 'Трасса'; CREATE TABLE obj_provod ( id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ) COMMENT = 'Провод'; CREATE TABLE obj_uch_lep ( id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ) COMMENT = 'Участок ЛЭП между опорами'; CREATE TABLE obj_uch_trassa ( id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ) COMMENT = 'Участок трассы между опорами'; CREATE TABLE obj_uch_provod ( id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ) COMMENT = 'Участок провода между опорами'; -- -- Contexts (контексты/конструкции) -- CREATE TABLE ctx_lep_as_trassa ( lep INT(10) UNSIGNED NOT NULL, trassa INT(10) UNSIGNED NOT NULL, PRIMARY KEY (lep, trassa), CONSTRAINT ctx_lep_as_trassa_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id) ON DELETE CASCADE, CONSTRAINT ctx_lep_as_trassa_to_trassa FOREIGN KEY (lep) REFERENCES obj_trassa (id) ON DELETE CASCADE ) COMMENT = 'Конструкция 1: ЛЭП как трассы'; CREATE TABLE ctx_lep_as_uch ( lep INT(10) UNSIGNED NOT NULL, uch INT(10) UNSIGNED NOT NULL, PRIMARY KEY (lep, uch), CONSTRAINT ctx_lep_as_uch_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id) ON DELETE CASCADE, CONSTRAINT ctx_lep_as_uch_to_uch FOREIGN KEY (uch) REFERENCES obj_uch_lep (id) ON DELETE CASCADE ) COMMENT = 'Конструкция 2: ЛЭП как участки'; CREATE TABLE ctx_trassa_as_provod ( trassa INT(10) UNSIGNED NOT NULL, provod INT(10) UNSIGNED NOT NULL, PRIMARY KEY (trassa, provod), CONSTRAINT ctx_trassa_as_provod_to_trassa FOREIGN KEY (trassa) REFERENCES obj_trassa (id) ON DELETE CASCADE, CONSTRAINT ctx_trassa_as_provod_to_provod FOREIGN KEY (provod) REFERENCES obj_provod (id) ON DELETE CASCADE ) COMMENT = 'Конструкция 3: трасса как провода'; CREATE TABLE ctx_trassa_as_uch_tr ( trassa INT(10) UNSIGNED NOT NULL, uch_tr INT(10) UNSIGNED NOT NULL, PRIMARY KEY (trassa, uch_tr), CONSTRAINT ctx_trassa_as_uch_tr_to_trassa FOREIGN KEY (trassa) REFERENCES obj_trassa (id) ON DELETE CASCADE, CONSTRAINT ctx_trassa_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id) ON DELETE CASCADE ) COMMENT = 'Конструкция 4: трасса как участки трассы'; CREATE TABLE ctx_uch_lep_as_uch_tr ( uch_lep INT(10) UNSIGNED NOT NULL, uch_tr INT(10) UNSIGNED NOT NULL, PRIMARY KEY (uch_lep, uch_tr), CONSTRAINT ctx_uch_lep_as_uch_tr_to_uch_lep FOREIGN KEY (uch_lep) REFERENCES obj_uch_lep (id) ON DELETE CASCADE, CONSTRAINT ctx_uch_lep_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id) ON DELETE CASCADE ) COMMENT = 'Конструкция 5: участок ЛЭП как участок трассы'; CREATE TABLE ctx_provod_as_uch_prov ( provod INT(10) UNSIGNED NOT NULL, uch_prov INT(10) UNSIGNED NOT NULL, PRIMARY KEY (provod, uch_prov), CONSTRAINT ctx_provod_as_uch_prov_to_provod FOREIGN KEY (provod) REFERENCES obj_provod (id) ON DELETE CASCADE, CONSTRAINT ctx_provod_as_uch_prov_to_uch_prov FOREIGN KEY (uch_prov) REFERENCES obj_uch_provod (id) ON DELETE CASCADE ) COMMENT = 'Конструкция 6: провод как участок провода'; CREATE TABLE ctx_uch_tr_as_uch_prov ( uch_tr INT(10) UNSIGNED NOT NULL, uch_prov INT(10) UNSIGNED NOT NULL, PRIMARY KEY (uch_tr, uch_prov), CONSTRAINT ctx_uch_tr_as_uch_prov_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id) ON DELETE CASCADE, CONSTRAINT ctx_uch_tr_as_uch_prov_to_uch_prov FOREIGN KEY (uch_prov) REFERENCES obj_uch_provod (id) ON DELETE CASCADE ) COMMENT = 'Конструкция 7: участок трассы как участок провода'; CREATE TABLE ctx_lep_as_uch_tr ( lep INT(10) UNSIGNED NOT NULL, uch_tr INT(10) UNSIGNED NOT NULL, PRIMARY KEY (lep, uch_tr), CONSTRAINT ctx_lep_as_uch_tr_to_lep FOREIGN KEY (lep) REFERENCES obj_lep (id) ON DELETE CASCADE, CONSTRAINT ctx_lep_as_uch_tr_to_uch_tr FOREIGN KEY (uch_tr) REFERENCES obj_uch_trassa (id) ON DELETE CASCADE ) COMMENT = 'Конструкция 8: ЛЭП как участок трассы'; -- -- Данные (объекты) -- INSERT INTO obj_lep VALUES (1); INSERT INTO obj_trassa VALUES (1), (2); INSERT INTO obj_provod VALUES (1), (2); INSERT INTO obj_uch_lep VALUES (1), (2); INSERT INTO obj_uch_trassa VALUES (1), (2), (3); INSERT INTO obj_uch_provod VALUES (1), (2), (3); -- -- Данные (связи в контекстах) -- INSERT INTO ctx_lep_as_trassa VALUES (1, 1), (1, 2); INSERT INTO ctx_lep_as_uch VALUES (1, 1), (1, 2); INSERT INTO ctx_trassa_as_provod VALUES (2, 1), (2, 2); INSERT INTO ctx_trassa_as_uch_tr VALUES (2, 1), (2, 2); INSERT INTO ctx_uch_lep_as_uch_tr VALUES (1, 2), (1, 3); INSERT INTO ctx_provod_as_uch_prov VALUES (2, 1), (2, 2); INSERT INTO ctx_uch_tr_as_uch_prov VALUES (2, 2), (2, 3); INSERT INTO ctx_lep_as_uch_tr VALUES (1, 1), (1, 2), (1, 3); -- -- Атрибуты объектов -- CREATE TABLE obj_trassa_attr_num ( id INT(10) UNSIGNED NOT NULL, value varchar(255) NOT NULL , PRIMARY KEY (id), CONSTRAINT obj_trassa_attr_num_to_obj FOREIGN KEY (id) REFERENCES obj_trassa (id) ON DELETE CASCADE ) COMMENT = 'Номер трассы';
В применении к схеме из самой статьи (с желтыми и зелеными прямоугольниками) что является "структурой", "объектом", "элементом", "типом объектов", "атрибутом"?
Насколько я понял терминологию, объект — это нечто, существующее в реальности. Модель объекта — это представление реального объекта в рамках моделируемой предметной области. Типы объектов — это некоторая классификация реальных объектов по общим признакам. Объект реального мира может принадлежать к различным типам объектов в зависимости от применяемой классификации. Свойство (признак, атрибут) — некоторая значимая (имеет определенное значение) характеристика объекта. Элемент — часть объекта. Структура (конструкция) — множество различных элементов объекта в совокупности представляющая объект. Объект может быть разделен на элементы различными способами, каждому такому разделению соответствует своя конструкция.
У меня складывается ощущение что вы одновременно говорите за модель предметной области и за мета-модель, в которой "живет" модель предметной области. Если разделить данные на две группы: описание самих объектов (их атрибутов, конструкций и элементов) и описание мета-данных (типов объектов, атрибутов, классов объектов, типов конструкций и типов элементов), то у меня получается примерно вот такая структура:
DROP TABLE IF EXISTS struct_elem, elem_class, elem, struct_class, struct_obj, struct; DROP TABLE IF EXISTS obj_attr, attr_class, obj_class, attr, obj; DROP TABLE IF EXISTS meta_struct_elem, meta_elem, meta_struct; DROP TABLE IF EXISTS meta_classifier_attr, meta_classifier; DROP TABLE IF EXISTS meta_obj_attr, meta_attr, meta_obj; -- -- Мета данные для объектов. -- CREATE TABLE meta_obj ( id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ) COMMENT = 'Реестр типов объектов (деревья, люди, ...)'; CREATE TABLE meta_attr ( id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ) COMMENT = 'Реестр типов атрибутов (высота, имя, ...)'; CREATE TABLE meta_obj_attr ( obj INT(10) UNSIGNED NOT NULL, attr INT(10) UNSIGNED NOT NULL, PRIMARY KEY (obj, attr), CONSTRAINT meta_obj_attr_to_obj FOREIGN KEY (obj) REFERENCES meta_obj (id) ON DELETE CASCADE, CONSTRAINT meta_obj_attr_to_attr FOREIGN KEY (attr) REFERENCES meta_attr (id) ON DELETE CASCADE ) COMMENT = 'Привязка типов атрибутов к типам объектов (высота для деревьев, имена для людей)'; -- -- Мета данные для классификатора объектов. -- CREATE TABLE meta_classifier ( id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ) COMMENT = 'Реестр классов (способов объединения атрибутов объекта для различения экземпляров объектов по значениям атрибутов)'; CREATE TABLE meta_classifier_attr ( class INT(10) UNSIGNED NOT NULL, attr INT(10) UNSIGNED NOT NULL, PRIMARY KEY (class, attr), CONSTRAINT meta_classifier_attr_to_class FOREIGN KEY (class) REFERENCES meta_classifier (id) ON DELETE CASCADE, CONSTRAINT meta_classifier_attr_to_attr FOREIGN KEY (attr) REFERENCES meta_attr (id) ON DELETE CASCADE ) COMMENT = 'Привязка класса к атрибутам, его характеризующим (масса-высота-ширина или долгота-широта)'; -- -- Мета данные для классификатора конструкций. -- CREATE TABLE meta_struct ( id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ) COMMENT = 'Реестр типов конструкций'; CREATE TABLE meta_elem ( id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ) COMMENT = 'Реестр типов элементов конструкций'; CREATE TABLE meta_struct_elem ( struct INT(10) UNSIGNED NOT NULL, elem INT(10) UNSIGNED NOT NULL, PRIMARY KEY (struct, elem), CONSTRAINT meta_struct_elem_to_struct FOREIGN KEY (struct) REFERENCES meta_struct (id) ON DELETE CASCADE, CONSTRAINT meta_struct_elem_to_elem FOREIGN KEY (elem) REFERENCES meta_elem (id) ON DELETE CASCADE ) COMMENT = 'Привязка типов элементов к типам конструкций'; -- -- Предметная область (объекты и их свойства). -- CREATE TABLE obj ( id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ) COMMENT = 'Реестр экземпляров объектов (#1, #2, ...)'; CREATE TABLE obj_class ( obj INT(10) UNSIGNED NOT NULL, class INT(10) UNSIGNED NOT NULL, PRIMARY KEY (obj, class), CONSTRAINT obj_class_to_obj FOREIGN KEY (obj) REFERENCES obj (id) ON DELETE CASCADE, CONSTRAINT obj_class_to_class FOREIGN KEY (class) REFERENCES meta_obj (id) ON DELETE CASCADE ) COMMENT = 'Привязка экземпляров объектов к типам объектов (#1 - дерево, #2 - человек)'; CREATE TABLE attr ( id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, -- значением атрибута может быть что угодно, включая ссылки на другие объекты; для упрощения - просто некий текст -- каким образом он обрабатывается - решается на программном уровне, для хранилища главное - хранить значение value TEXT NULL, PRIMARY KEY (id) ) COMMENT = 'Реестр значений атрибутов (#1 - тополь, #2 - 3м)'; CREATE TABLE attr_class ( attr INT(10) UNSIGNED NOT NULL, class INT(10) UNSIGNED NOT NULL, PRIMARY KEY (attr, class), CONSTRAINT attr_class_to_attr FOREIGN KEY (attr) REFERENCES attr (id) ON DELETE CASCADE, CONSTRAINT attr_class_to_class FOREIGN KEY (class) REFERENCES meta_attr (id) ON DELETE CASCADE ) COMMENT = 'Привязка значений атрибутов к типам (классам) атрибутов (#1 - порода, #2 - высота)'; CREATE TABLE obj_attr ( obj INT(10) UNSIGNED NOT NULL, attr INT(10) UNSIGNED NOT NULL, PRIMARY KEY (obj, attr), CONSTRAINT obj_attr_to_obj FOREIGN KEY (obj) REFERENCES obj (id) ON DELETE CASCADE, CONSTRAINT obj_attr_to_attr FOREIGN KEY (attr) REFERENCES attr (id) ON DELETE CASCADE ) COMMENT = 'Привязка значений атрибутов к экземплярам объектов (порода объекта #1 - тополь'; -- -- Конструкции и элементы. -- CREATE TABLE struct ( id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) ) COMMENT = 'Реестр экземпляров конструкций'; CREATE TABLE struct_obj ( struct INT(10) UNSIGNED NOT NULL, obj INT(10) UNSIGNED NOT NULL, PRIMARY KEY (struct, obj), CONSTRAINT struct_obj_to_struct FOREIGN KEY (struct) REFERENCES struct (id) ON DELETE CASCADE, CONSTRAINT struct_obj_to_obj FOREIGN KEY (obj) REFERENCES obj (id) ON DELETE CASCADE ) COMMENT = 'Привязка экземпляров конструкций к экземплярам объектов'; CREATE TABLE struct_class ( struct INT(10) UNSIGNED NOT NULL, class INT(10) UNSIGNED NOT NULL, PRIMARY KEY (struct, class), CONSTRAINT struct_class_to_struct FOREIGN KEY (struct) REFERENCES struct (id) ON DELETE CASCADE, CONSTRAINT struct_class_to_class FOREIGN KEY (class) REFERENCES meta_struct (id) ON DELETE CASCADE ) COMMENT = 'Привязка экземпляров конструкций к типам конструкций'; CREATE TABLE elem ( id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, -- элемент конструкции сам является объектом obj INT(10) UNSIGNED NOT NULL, PRIMARY KEY (id), CONSTRAINT elem_to_obj FOREIGN KEY (obj) REFERENCES obj (id) ON DELETE CASCADE ) COMMENT = 'Реестр значений элементов экземпляров конструкций'; CREATE TABLE elem_class ( elem INT(10) UNSIGNED NOT NULL, class INT(10) UNSIGNED NOT NULL, PRIMARY KEY (elem, class), CONSTRAINT elem_class_to_elem FOREIGN KEY (elem) REFERENCES elem (id) ON DELETE CASCADE, CONSTRAINT elem_class_to_class FOREIGN KEY (class) REFERENCES meta_elem (id) ON DELETE CASCADE ) COMMENT = 'Привязка значений элементов к типам элементов'; CREATE TABLE struct_elem ( struct INT(10) UNSIGNED NOT NULL, elem INT(10) UNSIGNED NOT NULL, PRIMARY KEY (struct, elem), CONSTRAINT struct_elem_to_obj FOREIGN KEY (struct) REFERENCES struct (id) ON DELETE CASCADE, CONSTRAINT struct_elem_to_attr FOREIGN KEY (elem) REFERENCES elem (id) ON DELETE CASCADE ) COMMENT = 'Привязка значений элементов к экземплярам конструкций';
Сначала заполняются мета-данные, затем описание объектов (хотя объекты можно прописать и без мета-данных к ним). Эта структура позволяет корректно описывать предметную область, но консистентность данных обеспечивается тем, кто их заполняет (программа, человек).
кроме того, можно посмотреть статью https://www.ritba.ru/classvstype в тех частях, которые названы Пример моделирования космических кораблей и Иерархия моделей. Там я снова подчеркиваю разницу между объектом и данными, которые хранят информацию об объекте.
Кроме того, была переписка https://www.facebook.com/trinidata/posts/1490503601009079 в которой не делается разницы между датой и теми данными, что ее моделируют.
Сейчас я вынужден прекратить переписку, потому что следующая моя статья, которая вышла уже поле этой — лишь шаг на пути к конечному результату, который я надеюсь все-таки достичь.
Вы сделали первый шаг к созданию "параметризованной БД"
Следующий шаг — возможность динамически (т.е., не на этапе добавления таблиц в схему БД, а при наполнении таблиц) создавать не только атрибуты, но и сами сущности.
Хотя в большей степени это ваша проблема, поскольку вы по какой-то непонятной причине хотите нарастить языковой синтаксис непонятной спецификой. Тогда вам просто дорога в направлении DSL.
Если же не догадываетесь, то тогда советую взять какой-нибудь язык с возможностями DSL (Scala, F#, Groovy, Nemerle, etc.) и продолжить эксперименты, возможно там нащупаете удобный синтаксис.
Если же не догадываетесь, то тогда советую взять какой-нибудь язык с возможностями DSL (Scala, F#, Groovy, Nemerle, etc.) и продолжить эксперименты, возможно там нащупаете удобный синтаксис.
Еще Ruby и множество созданных с его использованием фреймворков (Rails, TrailBlazer) и просто отдельных библиотек (gem'ов в терминах Ruby).
Насчет TP вы немного слукавили — "множества" (set) в TP позволяли создавать множества элементов в количестве от 0 до 256, где каждый элемент — переменная размером в 1 байт с внутренним кодом от 0 до 255
Конечно, это множества, но уж очень ограниченные.
Система — это упорядоченная совокупность объектов (подсистем) и связей между ними, обладающая одним или более системным свойством.
Системное свойство — такое свойство системы, которое отсутствует у любой неполной комбинации подсистем данной системы.
Пример: самолёт это система, его системное свойство — «возможность совершить полёт с аэродрома А на аэродром Б». У крыльев, двигателей, фюзеляжа и т.п. по отдельности или в любой неполной комбинации такого свойства нет.
Антипример: капля воды. Это агрегат, но не система. Есть агрегатное свойство «поверхностное натяжение», которого нет у отдельной молекулы воды. Но если взять часть молекул воды исходной капли, у них поверхностное натяжение будет.
Пример: самолёт это система, его системное свойство — «возможность совершить полёт с аэродрома А на аэродром Б». У крыльев, двигателей, фюзеляжа и т.п. по отдельности или в любой неполной комбинации такого свойства нет.
Самолет(о) — это система, его системное свойство — «возможность совершить полёт с аэродрома А на аэродром Б»
Антипример: капля воды. Это агрегат, но не система.
Любой объект может быть представлен в виде системы. Например, капля воды состоит из поверхности и объема. Именно так и рассматривается вода при объяснении поверхностного натяжения. Два объекта: поверхность и объем — это разные объекты, образующие одну систему. Всегда найдется кто-то, кто увидит систему там, где ее никто не видел. Ну, или вода состоит из молекул воды, — тоже система.
С другой стороны, если рассмотреть каплю, состоящую из капель, то вроде новых свойств нет. Но кто знает? Вдруг, эта капля воды стала тем, что изменило равновесие чьих-то весов? Пример более понятный: мы рассматриваем функции, деля их на функции. Тут почему-то системная инженерия говорит нам о системе, состоящей из функций. Почему? Традиция. Точно так же делить воду на воду и видеть в этом агрегаты — тоже традиция.
В ООП нельзя построить даже двух разных конструкций одного объекта. Как в ООП смоделировать тот факт, что ЛЭП состоит из трасс и одновременно состоит из участков ЛЭП между опорами?
Для различных "одновременно" делается несколько классов, отражающих те свойства моделируемой системы, которые важны для конкретных наборов задач. Можно выстроить иерархию наследования от одного (возможно абстрактного), если существует некий набор свойств (в широком смысле слова), которые важны для всех задач, а можно и не выстраивать, обеспечивая идентичность натуральным или суррогатным идентификатором, а то и вовсе о ней не заботясь, если в рамках задач нет нужды понимать, что некое множество трасс является лишь другим аспектом некоего множества участков ЛЭП между опорами.
С другой стороны, даже моделирование одной реальной или вымышленной системы через несколько ортогональных или слабосвязанных классов, отражающих разные её аспекты для разных множеств задач лишь техническое средство контроля и управления сложностью моделирующей системы (программы), повышающее эффективность труда разработчиков при изменении требований. А в теории никто не мешает обойтись одним суперобъектом, отражающим все аспекты моделируемой системы. При достаточной простой модели этот подход будет даже эффективней в плане ROI и прочих метрик ресурсной эффективности, главное не упустить момент, когда суперобъект с несколькими ответственностями станет тормозом в развитии.
Формально говоря, всё правильно преподают — вот объект в реальности и делаем для решения задачи абстракцию в виде объекта ИС. Просто явно не упоминают или упоминают, но не заостряют внимание, или заостряют, но не вдалбливают, что абстракция, процесс и результат абстрагирования зависит от решаемой задачи, а, следовательно, если проектируемая система должна решать несколько слабосвязанных задач относительно одного объекта в реальности, то и абстракций (читай — объектов в ИС) должно быть несколько, выделяющими для разных задач разные существенные свойства моделируемой системы.
Похоже ваше "нахлебался" следует лишь из-за того, что вы овладели другой терминологией раньше и пытаетесь привязать к ней новую (пускай когда-то) для вас терминологию ООП. Чем плох экземпляр табуретки или процесса? Вот глянул в словаре: "Экземпляр — отдельный предмет из ряда подобных". Ровно то, что и имею в виду, когда пишу что-то вроде "contract = new Contract()" в коде — создаю новый отдельный, обладающий собственной идентичностью, собственным жизненным циклом, экземпляр договора в ряду множества остальных обладающих идентичной типовой конструкцией, но собственным наполнением. Что не так?
Правильней говорить "экземпляр класса слон", а не "экземпляр слона", но сокращаем, поскольку другой трактовки при разговоре контексте ООП не мыслим :)
"Экземпляр/инстанс/объект (класса) слона" в контексте ООП с наследованием на классах лишь сокращение для "отдельный объект из множества объектов, задаваемых классом слона", а "экземпляр/инстанс/объект (этого) класса" — отдельный объект из множества объектов, задаваемых (этим) классом. Выражение "экземпляр класса" без определенного в контексте конкретного класса (the instance of a class, а не the instance of the class) полный синоним слова "объект" в контексте ООП с наследованием на классах.
отдельный объект из множества объектов, задаваемых классом слона
На самом деле это должно звучать так: отдельный объект из множества слонов. А в русском языке экземпляр класса — это класс. То, что в ООП переопределили термины и не сказали этого никому, плохо
А в русском языке экземпляр класса — это класс
Экземпляр (словарь Ефремовой):
Отдельный представитель какой-л. породы, вида, разновидности и т.п. (о живых существах, растениях).
Представитель какой-л. группы или какого-л. разряда людей, характеризующихся определенными свойствами.
Разве представитель породы это порода? Или представитель группы это группа?
Экземпляр (словарь Ушакова):
Отдельный представитель какого-нибудь разряда предметов — Редкий экземпляр пальмы
Разве представитель разряда предметов это разряд предметов?
А разве группа не может быть представителем группы? Группа групп, например. Множество множеств. Класс классов. Может. И чем больше мы уходим в абстракт, тем более "может". В пределе "все" — есть "что-то", и каждое "что-то" состоит из других "что-то".
Речь-то шла не об иерархии, а о том, что экземпляр типа X — это представитель типа X, а не сам тип.
Так как вы употребляете выражение "экземпляр класса" из программирования, но значение слова "класс" используете из другой области, я буду использовать выражение "экземпляр типа".
"Экземпляр слона" и "экземпляр типа" это не равнозначные выражения. Потому что то, что вы называете "экземпляр слона", формально называется "экземпляр типа "Слон"".
"Экземпляр типа" это часть выражения "экземпляр слона" ("экземпляр типа "Слон""), и требует указания после него конкретного типа, в отличие от выражения "экземпляр слона", которое является законченным выражением. Поэтому между ними нельзя строить аналогии.
В некоторых случаях конкретный тип вводится до этого выражения и понятен из контекста. Или подразумевается любой возможный тип.
экземпляр типа «Слон»
Мне нравится такой термин. Это значит, что у нас есть экземпляр типа слон. Что это такое? это -слон! То есть, вместо терминов «экземпляр лона», «экземпляр процесса» я могу употреблять термин «слон» и термин «процесс». Бинго! О чем я и толкую: когда программист говорит экземляр слона, я перевожу это просто: слон. Когда он говорит инстанс процесса, то это — процесс! Так что все верно. Программисты зачем-то используют лишнее слово там, где его можно пропустить.
Его используют когда надо указать, что речь идет о конкретном представителе, а не о типе, обозначающем любого представителя. Но если понятно, то так и говорят — пользователь заходит в систему или регистрируем слона в списке животных.
Слово "слон" само по себе, как и любое другое слово, обозначает в русском языке не конкретного слона, а некоторое животное с хоботом, то есть тип животных. Поэтому нет, сказать просто "слон" нельзя, нужен контекст. И чтобы не описывать его каждый раз, используют слово, из которого контекст сразу ясен.
Кроме того, мы не создаем слонов или пользователей. Мы создаем объекты в памяти, это не реальные слоны, а их модели. Поэтому выражения "создать слона" или "работать со слоном" неправильно отражают ситуацию.
Кроме того, у конкретного слона и у конкретного пользователя есть общая черта — это конкретные объекты. И у понятия "конкретный объект" есть свое обозначение — "экземпляр". Так что слово не лишнее, было бы лишнее, не использовали бы.
В русском языке есть слово "тип", оно появилось еще до появления программирования, оно что-то обозначает, и это явно не множество. Если у вас в какой-то области кроме явно заданных через перечисление множеств ничего нет, значит у вас такая ограниченная область. В других областях явно перечислять объекты необязательно.
Любой термин означает тип, которому соответствуют многие объекты, а не какой-то конкретный объект, существующий в данный момент. Это основной способ, с помощью которого мы моделируем реальность средствами языка. Выделение и обобщение признаков это основной принцип работы мозга. Если вы исключаете это понятие из инструментов моделирования, то логично, что у вас возникают сложности. Что и заметно по количеству статей и вопросов в них.
Вы заранее ограничили себя в некоторых рамках по каким-то неизвестным причинам. Вы не сможете построить формальную теорию всего, если будете игнорировать часть этого всего.
Это точное определение термина тип в вашем понимании. Это не значит, что оно точное вообще. Это даже не значит, что оно правильное.
Прочитал еще раз ту часть, где вы говорите про модель моделей. Вначале все так и есть, описание типа в мышлении формируется на основе множества. Есть множество объектов, у них есть общие признаки. Но потом, после того, как описание типа сформировалось, тип становится самостоятельным понятием, и уже наоборот, не тип выводится из новых встреченных объектов, а объекты относятся к некоторому известному типу. Поэтому на основе типа можно моделировать (представлять, воображать) работу с будущими объектами (любая инструкция), или генерировать описание несуществующих объектов (как в книгах, где события вымышлены). На основе множеств вы так не сделаете.
«Правило, по которому любой объект может быть классифицирован, как элемент этого множества» это и есть описание типа. Определенный состав это одно из правил. При этом нам не надо иметь объекты в наличии и специально относить каждый ко множеству. Именно это и позволяет нам работать с моделями или макетами. Потому что они соответствуют описанию нашего типа.
Понятие системы и конструкции. Их место в проектировании информационных систем