— Как?
— Очень просто! Прапорщик дает задание: «Сегодня будем копать от забора и до обеда»
В этой статье я начну рассказ о путаницах, которые регулярно встречаются, и которые кочуют в информационные модели без всякого критического анализа.
В прошлой статье я дал определения типу и атрибуту. Напомню их:
- Тип – это выделение кучки (подмножества) из кучи (множества) и наделение объектов этой кучки уникальным именем — существительным.
- Атрибут разделяет кучу (множество) на кучки (подмножества) и наделяет объекты этих кучек разными прилагательными.
Это было определение типа и определение атрибута на основе анализа – мы делили кучу на части. Фактически, это было построение типа при помощи анализа. Теперь я покажу, как можно строить типы и атрибуты на основе синтеза.
Можно взять множество лодок, множество надувных матрацев, множество гидросамолетов, соединить их в одно множество и получить множество плавательных средств. Так множество плавсредств будет получено путем синтеза нескольких множеств.
Ранее я утверждал, что тип «объект» невыводим. Под выводимостью понимается выделение подмножества из надмножества. Однако, тип «объект» можно синтезировать. Для этого должен быть эксперт, который определяет, относится ли новый объект учета к типу объектов, или нет. Таким способом тип «объект» может быть синтезирован. Синтез может быть сделан следующими способами:
- перечислением всех объектов учета, относящихся к этому типу
- перечислением всех типов объектов учета, которые относятся к этому типу.
Точно так же можно поступить с атрибутом. Можно взять несколько кучек, присвоить им значения, объединить вместе и назвать это все атрибутом.
Обобщим на любые операции над множествами:
- Тип – общее свойство у объектов множества и общее имя для этих объектов. При этом идентификация состава множества возможна любым удобным способом.
- Атрибут – это множество подмножеств, каждому подмножеству которого соответствует уникальное значение атрибута.
Вы можете сказать, что оперировать кучками – слишком примитивно. Ведь мы умеем работать с такими абстракциями как графы, логики, алгебры. Однако, введение новых абстракций без глубокого понимания того, что за этим стоит, быстро приводит к тому, что мы начинаем путаться. При этом математики, применяя свои инструменты, не совершают логических ошибок, потому что, с одной стороны, придерживаются жесткой дисциплины рассуждений, которую им прививает изучение основ математики, а с другой стороны, создавая модели для решения конкретных задач, они не обременяют себя стыковкой этих моделей между собой. Мы же, строя модели разных предметных областей, зачастую не владеем необходимым математическим аппаратом, например, не знаем, что такое мера Жордана, или что такое шкалирование, но при этом решаем сложнейшие задачи стыковок разных моделей. Например, вы легко можете столкнуться с моделями, в одной из которых цвет выражен длиной волны, в другой – частотой колебания электромагнитных волн, а в третьей – словами типа «красный». Или может случиться, что «Колли» в одном модели – это атрибут класса «собаки», в другой – это отдельный класс объектов. Конечно, вы можете построить преобразование из одной модели в другую. Но как вы это сделаете, и что за этим стоит?
Чтобы не путаться можно использовать простой метод — опираться на то, что мы все умеем делать на генетическом уровне: делить кучки на части, складывать кучки вместе. Поэтому мой рассказ про типы и атрибуты, хоть и казался столь наивным, преследовал очень важную цель: продемонстрировать, как можно строить модели, опираясь на эту основу. Я старался ввести понятия тип и атрибут так, как ввели бы их математики, но на понятном для прикладника языке.
Чтобы понять, о каких путаницах я говорю, надо задать простые вопросы:
- Почему в результате умножения 3-х яблок и 4-х корзин, получается 12 яблок, а не 12 корзин, или 12 яблоко-корзин?
- Почему 3 Ампера, умноженные на 4 Вольта дают 12 Ватт, а не 12 Ампер, или 12 Вольт?
- Почему 3 метра, умноженные на 4 метра, дают 12 квадратных метров?
- Почему Паскаль заходит в бар и видит, что там 100000 Паскалей?
- Почему модели линейного преобразования пространства и линейного преобразования базиса выглядят совершенно одинаково: в виде матрицы? Хотя физический смысл этих действий совершенно разный?
Ответ прост: математика – это не более чем инструмент моделирования. Но вот вопрос: чего? Объекта учета, типа объектов учета, класса, которому принадлежит объект учета, или модели объекта учета? Используя числа, формулы, графы и прочее, вы легко можете запутаться и не дать точного ответа на этот простой вопрос. Когда на одном полотне оказываются модели объектов учета, модели типов и модели моделей, работа с этим полотном потребует большой внимательности. Мой опыт подсказывает, что ошибки в таком случае гарантированы.
Начнем с модели объекта учета. Объект учета – это то, что выделено субъектом в качестве части реального мира, но еще не классифицировано и не названо, например, четырехмерный пространственно-временной объем. Далее этот объект учета проходит этап моделирования в сознании субъекта при помощи метамодели. Метамодель – это представление человека о том, как производить моделирование. Например, для всех нас общим является представление о том, что есть объекты, есть действия, совершаемые объектами, есть типы объектов, типы совершаемых ими действий и свойства. Эта метамодель была подмечена и хорошо описана Аристотелем. Только один вопрос у него остался без ответа: если есть атрибут «высота» у деревьев, и есть атрибут «высота» у зданий, то это один и тот же атрибут, или это разные атрибуты? Мы не знаем, что думал Аристотель на эту тему, но зато знаем, что мы думаем на этот счет: все зависит от точки зрения субъекта и решаемых задач — это может быть один атрибут, а могут быть разные атрибуты.
Метамодель, которую подметил Аристотель, и на основе которой работает наше сознание, имеет суровые ограничения. Это связано с тем, что язык при помощи которого мы выражаем наши модели, балансирует на грани между полнотой и краткостью. Если язык будет полон, то высказывания на этом языке будут настолько тяжелыми, что в реальном мире человек не выживет. Если язык будет краток, то это будет узкий специализированный контекстный язык неприменимый ко всем случаям жизни. Универсальный язык находится между этими крайностями, поэтому он и не полон, и не краток.
Математики столкнулись с ограничениями метамодели, на основе которой мы строим модели в нашем сознании и попытались выработать свою метамодель, лишенную этих недостатков. Эта метамодель состоит из объектов и множеств. Достоинство этой метамодели в том, что она позволяет строить непротиворечивые и расширяемые модели. Недостаток — в том, что модели, построенные с помощью этой метамодели, плохо переводятся на обычный человеческий язык и довольно громоздки.
Если бы существовал стандарт моделирования, построенный на множествах и объектах, то с помощью этого стандарта можно было бы строить модели, в которых типы моделировались бы множествами, атрибуты – множествами множеств, а сама модель была бы неограниченно расширяемой. Но до сих пор такого стандарта не существует. Возможно, дело в том, что модели, построенные на этой метамодели, были бы достаточно пухлые в объеме, поскольку для каждого значения атрибута в модели пришлось бы заводить отдельный класс объектов. Возможно, что на пути к созданию такого стандарта нас сдерживает привычка мыслить типами и атрибутами. Так или иначе, такого стандарта еще нет и это плохо. Плохо с точки зрения теории моделирования.
На практике существующие стандарты моделирования пытаются усидеть на двух стульях сразу, одновременно моделируя типы, множества и атрибуты.
Так для моделирования типов в ООП используются «классы». Они моделируются набором встроенных в них атрибутов. Также можно указать имя объектов данного типа. Но ничего более для описания типа в ООП не предусмотрено.
Для моделирования атрибутов в ООП создаются атрибуты этих «классов». Если в ООП надо смоделировать атрибуты, общие для нескольких типов объектов, для этого придется создать пустой «надкласс», «наследники» которого будут моделировать эти типы объектов. Понятно, что без множественного наследия при этом не обойтись.
Допустим, что в ООП все же необходимо смоделировать другие свойства типа, например, указать уникальные особенности объектов данного типа. Для этого можно схитрить. Можно создать «класс», объектами которого будут типы, то есть, создать «класс» типов, «экземплярами» которого являются типы объектов. Таким образом, в модели одновременно появятся два объекта, моделирующие один тип: «класс» объектов и, связанный с ним «экземпляр» «класса» типов. При этом в ООП нет штатных механизмов, которые позволили бы сохранять целостность этой модели. Теперь целостность модели будет зависеть от аккуратности программиста.
Если надо смоделировать множество, то в ООП используются различные способы: списки, коллекции и проч. Но это моделирование лишь состава множества. Само множество штатными методами смоделировать в ООП невозможно, как и операции над множествами. Для создания модели множества придется создавать «класс» множеств, «экземпляр» которого будет моделировать множество. Тогда коллекция и этот, связанный с ней объект, будет вместе моделировать один объект — множество. И опять целостность модели в руках программиста.
Путаница типов и объектов
Программисты часто думают, что моделирование типа объектов и моделирование объекта – это одно и то же. Например, класс в ООП почему-то упорно именуют объектом, например, чашкой, а не типом объектов, а объект почему-то упорно называют «экземпляром этой чашки», а не «чашкой». Из-за этого рождаются стандарты с уже заложенными в них коллизиями.
Вы когда-нибудь слышали, что процесс можно моделировать при помощи направленного графа? Вот пример. Вы знаете, что направленный граф может иметь циклы, а может не иметь. Понятно, что, если речь идет о последовательности операций, то граф, моделирующий последовательность операций, не может иметь циклов, поскольку время всегда движется вперед и не может двигаться назад. Граф, удовлетворяющий этому требованию, называется сетевой график. Но модель, построенная в нотации BPMN, может содержать циклы. Следовательно, можно сделать логический вывод, что в нотации BPMN мы моделируем не последовательность операций, а что-то другое. Лично мне это кажется очевидным, но программистов, которые это понимают, единицы. Многочисленные примеры этому можно найти в обсуждениях моих статей.
Путаница типов и множеств
Другая путаница возникает из-за того, что программисты часто не делается разницы между типами объектов и множествами объектов. Например, есть мнение, что класс в ООП – это модель множества. Но увы, — это модель типа объектов, но не модель множества. Из-за этой путаницы, когда надо смоделировать множество элементов конструкции, состоящее из объектов и связей между ними, программисты пасуют. Им трудно представить себе, как в одно множество могут попасть объекты разного типа.
Это были примеры путаниц распространенных, но далее круга программистов не выходящих. Есть и такие, которые распространены гораздо шире. В следующих статьях попробуем поговорить о них.
Комментарии (14)
sand14
29.06.2017 19:24+1Например, есть мнение, что класс в ООП – это модель множества. Но увы, — это модель типа объектов, но не модель множества.
А ведь, пожалуй, это пример нарушения принципа Single Responsibility.
Класс это — тип объектов. Но некоторые особенности класса (например, возможность определения статического поля, доступного для объектов — экземпляров класса) позволяют, пусть и с ограничениями, использовать его для моделирования множества объектов.
Налицо смешение в одной сущности двух обязанностей.
И если в базовой конструкции ООП допускается эта ошибка, становится понятным, почему, несмотря на то, что в мире ООП много говорят о базовых принципах — SOLID, на практике не соблюдают эти принципы:
с одной стороны, в фундаментальных конструкциях есть изъяны (что уже само по себе!),
с другой — несмотря на то, что эти изъяны можно обойти, само их наличие провоцирует прикладных программистов нарушать базовые принципы (если на более серьезном уровне можно нарушать, то и на прикладном уровне можно).michael_vostrikov
01.07.2017 14:46-1Например, есть мнение, что класс в ООП – это модель множества.
Это мнение только автора статьи.
Но некоторые особенности класса (например, возможность определения статического поля, доступного для объектов — экземпляров класса) позволяют, использовать его для моделирования множества объектов.
Как вы с помощью статических полей смоделируете множество? Можно сделать отдельный класс для коллекций (тип "Коллекция"), тогда один объект этого типа будет моделью какого-то конкретного множества, а массив внутри него моделью состава множества.
maxstroy
01.07.2017 17:06+1Мнение о том, что класс в ООП — это модель множества, не мое.
Я лишь пересказываю те мнения, которые я встречаю.
mayorovp
06.07.2017 12:35Например, класс в ООП почему-то упорно именуют объектом, например, чашкой, а не типом объектов, а объект почему-то упорно называют «экземпляром этой чашки», а не «чашкой».
Не надо пропускать слова, тогда и не будет путаницы. Класс чашек именуется "класс Чашка", а не просто "Чашка". Сами объекты (чашки) именуются "экземплярами класса Чашка".
maxstroy
06.07.2017 16:32-1Экземпляры класса чашка по определению русского языка — есть классы чашек, а не чашки.
knstqq
> Почему в результате умножения 3-х яблок и 4-х корзин, получается 12 яблок, а не 12 корзин, или 12 яблоко-корзин?
не надо людей путать корзинами. здесь правило общее, а не какое-то исключение.
Умножаются 4 (корзины) на 3 (яблока-в-корзине) получается 12 корзина * яблоко / корзина = 12 яблок
А не яблоко-корзины
NLO
НЛО прилетело и опубликовало эту надпись здесь
maxstroy
Все это будет, но через статью. Сначала разберемся с простыми кейсами: типами и классами, затем с существительными и глаголами, и лишь потом про числа.
yukon39
Эх. Раскладываем единицы измерения:
Ампер * Вольт = А*Дж/Кл = А*(Н*м)/(А*сек) = Н*м/сек = ((кг*м/сек^2)*м)/сек = кг*м^2/сек^3
NLO
НЛО прилетело и опубликовало эту надпись здесь
yukon39
За что обожаю систему СИ, так это за множество возможных интерпретаций казалось бы давно знакомых понятий.
maxstroy
Верно. Но в школе нам объясняли именно так: яблоки умножались на корзины.