Category: философия

Бритоголовый и С1-97

Business Objects: Re-Engineering for Re-Use, или кому не хватает ООП

По наводке [info]ailev ознакомился с книжкой Криса Партриджа “Business Objects: Re-Engineering for Re-Use”. Прекрасное чтение после какого-нибудь руководства по “мейнстримному” объектно-ориентированному проектированию с использованием UML, а главное – в любимом мной жанре “прикладной философии”.

Как и полагается в книгах такого типа, где предлагается какой-то фундаментально новый подход, не обошлось без вступления в духе “вы все пидоры, а я Д’Артаньян”. Утверждается, что “стандартный” подход к проектированию информационных систем, который автор назвал “сущностным” (entity), несмотря на все заявления его авторов, не позволяет строить сколь-либо сложные модели реальных систем, и не позволяет прямо соотнести возникающие сущности с реальностью. Это подтверждается примером из статьи Стива Кука и Джона Дениэлса “Object-Oriented Methods and the Great Object Myth”, в котором “миф” о том, что мир состоит из объектов и операций (взаимно-однозначно соответствующих объектам и операциям в модели) разрушается простым примером – когда мы пьем чай, мы не вызываем операцию “пить”, принадлежащую объекту “чашка” – и вообще, представить это простое действие с помощью “объектно-ориентированной” модели очень сложно.

Для нового, единственно верного и всячески правильного подхода к проектированию предлагается сменить парадигму – то есть смотреть на мир, не как на состоящий из сущностей (entity, это общепринятый термин, например, в так называемой ER-модели) или субстанций (substance, это более высокий уровень абстракции и общепринятый философский термин), а составленный из более сложных для представления “объектов”. То, что называется “объектами” в учебниках по ООП – это, в терминологии книги, “сущности” либо “субстанции”. Картина мира, использующая “сущности”, неявно существует и в “бумажных” информационных системах. Взаимно-однозначное соответствие между терминами из теории реляционных БД, “бумажных” картотек и “сущностной” парадигмы – не просто совпадение, а подтверждение единой картины мира, представляемой тремя способами.

В любой предметной области можно выделить четыре “рода” вещей (kinds of things) – конкретные вещи (”белый ВАЗ-2101 с проколотыми колесами, ржавеющий в моем дворе”), типы вещей (”все автомобили «Жигули»”), отношения между вещами (”Иван Иваныч – владелец белого ВАЗ-2101 и далее по тексту”) и изменения, происходящие с этими вещами (вышеупомянутым “Жигулям” выбили стекло, вытащили все сиденья и насрали внутри). Оказывается, что модель мира, состоящего из “сущностей” или “субстанций” не вполне адекватно позволяет описывать все это. Например, “сущности” убивает классический пример из все той же греческой философии – “корабль Тесея”. Жители Афин поставили корабль, на котором Тесей вернулся с Крита, победив Минотавра, на “вечную стоянку” – как крейсер “Аврора”. При этом они его постоянно ремонтировали (как крейсер “Аврора”), и наконец, настал момент, когда все досочки и гвоздики были поменяны (ну точно “Аврора”). Можно, конечно, ввести дополнительную сущность – например, ПТС, где отражать все замены номерных агрегатов – но древние греки до этого не дошли, и более-менее приемлемо парадокс разрешил Аристотель, рассматривая “субстанции” – грубо говоря то, что остается от предмета, если его лишить всех свойств. “Субстанция” нематериальна, и с точки зрения Аристотеля, сохраняется даже при замене всех “материальных” частей.

Так или иначе, но современное ООП предлагает смотреть на мир, как на множество объектов-субстанций, которые имеют изменяющиеся со временем свойства. В аристотелевскую картину мира укладывается и понятие наследования вместе с “общими” категориями объектов – как существование более общих, “вторичных” субстанций и свойств – но не все гладко с отношениями – для них приходится вводить дополнительные свойства объектов (например, у автомобиля есть свойство “владелец”) – и с изменениями – фактически предложенное Аристотелем решение предлагает учитывать изменения, как какие-то новые “частицы” в картине мира.

Если непонятно про Аристотеля – то вот более “жизненный” пример. Используемая в проектировании баз данных модель “сущность-связь” (entity-relationship, или ER-модель) возникает как раз при использовании “сущностей” или “субстанций”. Отношения (или “связи”) в ней предлагается представлять в виде дополнительных атрибутов объектов или же (в случае отношения “многие-ко-многим”) – строить “фиктивную” таблицу, представляющую отношения. Эти решения точно так же вводят в картину мира новые “элементарные частицы”, которые существуют наравне с “настоящими”, но ничего “реального” не представляют.

В книге предлагается принятую в современном ООП аристотелевскую модель последовательно перестраивать, приводя ее к “истинно объектному”, по мнению автора, виду – в отличие от понимания “объектов” в современном ООП. Как один из “промежуточных” шагов рассматривается “логическая” модель. Вместо атрибутов предлагается рассматривать принадлежность к классам (не в смысле “обычного” ООП) – например, вышеупомянутые “Жигули” Ивана Ивановича можно отнести к классам “автомобили”, “все белое”, “все ржавое” и так далее. Для того, чтобы представлять отношения, в картине мира появляются “кортежи” (tuple), которые, как и индивидуальные предметы, могут входить в какие-то классы. Например, пара <Иван Иваныч, ржавые Жигули> входит в класс, который можно назвать “владеет” – равно как и пара <Иван Иваныч, участок в 6 соток за 101 километром>. Точно так же можно представлять отношения из многих элементов – например, “Иван Иваныч выписал любимому внуку доверенность на “Жигули”" можно представить тройкой <Иван Иваныч, любимый внук, Жигули>, входящей в класс “кто-то выписал кому-то доверенность на что-то”. Всякий же объект оказывается представителем универсальной категории “логических объектов”.

Важное новшество в этой модели – возможность рассматривать “классы объектов” с позиции теории множеств. “Класс” – это множество объектов, которое само может являться подмножеством другого класса. Примером такого взаимоотношения между классами можно назвать цвета – класс “все раскрашенное” содержит классы “все белое” и “все красное” как подмножества. Это позволяет рассматривать иерархии классов, более точно отражающие реальный мир, чем в случае других моделей. Некоторой сложностью в главе про логическую модель оказывается понимание автором теории множеств. Например, если множество “всех красных” объектов – это объекты A и B, а “всех белых” – Y и Z, то описанный выше класс “всего раскрашенного” будет содержать не два описанных класса, а четыре объекта A, B, Y и Z. При этом автор использует термин “member of” – то есть описывает множество {{A, B}, {Y, Z}} вместо {A, B, Y, Z}.

Кстати, с помощью логической модели можно проектировать реляционные базы данных. Да, они получаются сложнее, чем в книжке “PHP и MySQL для чайников” – но понимание того, что таблица БД – это список кортежей, входящих в какое-то отношение (поэтому БД и “реляционная”), а не “записей об объектах”, позволяет представлять многие вещи куда эффективнее. Фактически это обобщение принципов, заложенных в ER-модель на отношения с количеством членов, большим двух.

Логическая модель снимает сложности с отношениями, но проблема представления изменений остается. Для ее решения предлагается ввести “четвертое измерение” – время, и вместо локализованных во времени “логических объектов” рассматривать объекты на протяжении всего их жизненного цикла. Фактически, это замена значения функции на саму функцию или ее график, то есть некоторую кривую – очень плодотворная идея в математике и, как ни странно, в науке о представлении окружающего мира. Эту модель автор называет “объектной” – в очередной раз вворачивая модное слово и совершенно смущая читателя – особенно того, который обнаружил в главе о “субстанциальной” модели все понятия современного ООП.

Кстати, в книге очень сложная и непривычная на первый взгляд терминология. Например, “объектами” называют совсем не то, что понимается под словом “объект” в книжках “по UML”, а с первого раза понять слово “substance” вообще невозможно. Про странное понимание терминов теории множеств я уже упоминал. Оно только запутывает читателя, хорошо знакомого с этими терминами.

После последовательного построения “объектной” (в терминологии автора) модели она применяется к нескольким примерам, разумеется, весьма успешно. Построенная методология преобразования “сущностных” моделей в “объектные” называется красивыми словами REV-ENG™ (да-да, именно со значком trade mark), предлагается автором в качестве абсолютно универсальной и везде-везде применимой. Насчет абсолютной ее применимости не знаю – хотя очень похожий метод лежит в основе стандарта обмена данными ISO 15926, и по утверждениям все того же [info]ailev, это “наше все” и вообще, будущее человечества. Во всяком случае, книжка круто “расширяет сознание” и заставляет по-новому взглянуть на привычные вещи.

PS Несмотря на то, что я поставил тег “программирование”, в книге нет ни единой строчки кода ни на одном из языков программирования. Читать можно всем без исключения, хотя очень желательно понимание существующих методов работы с разнообразными данными – хотя бы в рамках UML и того, что называется “теорией баз данных”.

Запись опубликована в блоге Шуры Люберецкого. Вы можете оставлять свои комментарии там, используя свое имя пользователя из ЖЖ (вход по OpenID).

Бритоголовый и С1-97

Необычное программирование

Этнограф сидит напротив шамана и думает: “Бедный, невежественный дикарь! Неужели он правда считает, что в мире духов действительно существует такой же Енисей, такая же тайга и такие же олени? Вот примитивная какая религия!”
Шаман сидит напротив этнографа и думает: “Вот блин, как же мне объяснить этому доброму, но бедному и невежественному дикарю, что сакральный топос отличается от профанного субстанциально, а не экзистенциально? О! Скажу-ка я ему, что в мире духов существует такой же Енисей, такая же тайга и такие же олени – авось хоть что-то поймет”.

Обещал написать запись о программировании с некими извращенными “философскими основаниями”. Сначала мне показалось, что все будет сложно – но получилось “сразу и на одном дыхании”, так что читайте, не отрываясь от предыдущей записи.

Для начала стоит кратенько изложить необходимую философию, потому что она может показаться ну очень необычной – все-таки в большинстве “кратких изложений” истории философии до этого не доходят. Опираться будем на “Логико-философский трактат” Л. Витгенштейна – но обойдемся мы всего лишь некоторыми утверждениями из него и некоторыми комментариями.

Есть некое хорошо известное высказывание – “вся европейская философия – это комментарии к Платону и Аристотелю”. У него есть менее известное “добавление” – “до Витгенштейна”. Платон и Аристотель предполагали первичным существование вещей – Витгенштейн же утверждает следующее:

<…>
1.1. Мир есть совокупность фактов, а не вещей.
1.11. Мир определен фактами и тем, что это все факты.
1.12. Потому что совокупность всех фактов определяет как все то, что имеет место, так и все то, что не имеет места.
<…>
2. То, что имеет место, что является фактом, – это существование атомарных фактов.
2.01. Атомарный факт есть соединение объектов (вещей, предметов).
<…>
2.012. В логике нет ничего случайного: если предмет может входить в атомарный факт, то возможность этого атомарного факта должна предрешаться уже в предмете.
<…>
2.013. Каждая вещь существует как бы в пространстве возможных атомарных фактов. Это пространство я могу мыслить пустым, но не могу мыслить предмет без пространства.
<…>
2.0141. Возможность вхождения объекта в атомарные факты есть его форма.

Комментаторы Витгенштейна обычно понимают это следующим образом: первичными являются не предметы, а “факты” – то есть утверждения о предметах. Каждый предмет определяется совокупностью всех фактов, в которые он может входить.

Какое отношение это может иметь к программированию? Действительно, “обычное”, то есть в современных реалиях – объектно-ориентированное программирование, изначально оперирует предметами. Но в том же “Логико-философском трактате” содержится очень интересная мысль о том, что “естественный язык” может ограничивать способности к познанию. В нашем случае “естественным” языком будет что-нибудь вроде C++ или Java – и они, разумеется, ограничивают нас тем, что требуют описывать объекты, а не факты.

Витгенштейн в качестве выхода из такой ситуации предлагал создание “универсального языка”, похожего на исчисление предикатов. Мы не будем этим заниматься, а попробуем увидеть нечто подобное на простых примерах. Для начала – вспомним про задачку о формулах.

Один из способов решения этой задачки – небольшое количество кода на Lisp, позволяющее описать, скажем, формулу, связывающую температуру по Цельсию и Фаренгейту 9C = 5(F – 32) следующим образом:

(define (celsius-fahrenheit-converter c f)
   (let ((u (make-connector))
         (v (make-connector))
         (w (make-connector))
         (x (make-connector))
         (y (make-connector)))
     (multiplier c w u)
     (multiplier v x u)
     (adder v y f)
     (constant 9 w)
     (constant 5 x)
     (constant 32 y)
     'ok))

Выражения с multiplier, adder и constant описывают следующие взаимоотношения между переменными:

c * w = u
v * x = u
v + y = f
w = 9
x = 5
y = 32

Если упростить эти формулы, то получим уравнение 9c = 5(f – 32) – как раз то, что мы хотели получить. При этом наше описание оказывается (благодаря определениям “простейших” примитивов) таким, что может вычислять выражение в “обе стороны” (про использование этой “системы” читайте в SICP по ссылке). Возможно, этот пример окажется не совсем корректным – все-таки мы начинаем с определения “объектов” в выражении присваивания (let), но он довольно прост для понимания. Кстати, попробуйте реализовать что-то подобное “объектно-ориентированным” способом – окажется, что явно выделить “объекты” в этой задаче не совсем просто, а часть из них будет явно излишней.

Давайте пойдем дальше. А именно, попробуем сделать игру в жанре “текстовый квест”. В качестве “движка” выберем Inform 7, позволяющий компилировать вот такие описания:

"Hello Deductible" by "I.F. Author"

The story headline is "An Interactive Example".

The Living Room is a room. "A comfortably furnished living room."
The Kitchen is north of the Living Room.
The Front Door is south of the Living Room.
The Front Door is a door. The Front Door is closed and locked.

The insurance salesman is a man in the Living Room. "An insurance salesman in a tacky polyester suit. He seems eager to speak to you." Understand "man" as the insurance salesman.

A briefcase is carried by the insurance salesman. The description is "A slightly worn, black briefcase." Understand "case" as the briefcase.

The insurance paperwork is in the briefcase. The description is "Page after page of small legalese." Understand "papers" or "documents" or "forms" as the paperwork.

Instead of listening to the insurance salesman for the first time:
say "The salesman bores you with a discussion of life insurance policies. From his briefcase he pulls some paperwork which he hands to you."; move the insurance paperwork to the player.

Система программирования не знает заранее смысл терминов “insurance salesman”, “briefcase” и “paperwork” – но способна анализировать грамматику “упрощенного” английского языка и исходя из этого анализа – делать выводы о том, что в этом описании является объектами и что с этими объектами можно сделать – то есть строит описание объектов из описания их отношений.

Фактически, мы уже вплотную подошли к так называемым “экспертным системам” и “искуственному интеллекту”. Вообще, очень популярным в этих системах был язык Lisp, позволявший сравнительно просто (смотри выше ссылку на SICP) описывать новые синтаксические конструкции и в зависимости от библиотеки “становиться чем угодно”. Lisp превращается и в объектно-ориентированный язык с помощью, например, Common Lisp Object System, и в гораздо более интересные вещи. Например, существует проект Cyc (”цик”, от encyclopedia), ставящий своей целью описать “все” знания. Основным языком программирования в Cyc является CycL – фактически, “очень ограниченный” диалект Lisp.

Например, фраза “Билл Клинтон – президент США” может быть записана следующим образом (с помощью предиката Is A – “является”):

(#$isa #$BillClinton #$UnitedStatesPresident)

А вот другой стандартный предикат – Generalises, “обобщает”:

(#$genls #$Tree-ThePlant #$Plant)

“Всякое дерево является растением”.

На CycL описываются, кроме того, некоторые правила логического вывода – которые позволяют использовать эти “знания” и даже отвечать на какие-то вопросы (”Существуют ли негры-президенты США?”). Для того, чтобы построить онтологию (упертый из философии термин, который в “науке” об искуственном интеллекте означает доступную базу знаний), необходимо определить входящие в нее объекты – и они определяются исключительно теми отношениями-фактами, в которые входят. Правда, очень похоже на идеи, высказанные Витгенштейном?

Сразу скажу, что скорее всего, создатели упомянутых программных систем даже не задумывались о том, что придуманные ими языки программирования “реализуют” какие-то философские концепции. Более того, может показаться, что эти “концепции” тут притянуты за уши. В свое оправдание скажу, что любая философская система – это “то, как люди мыслят” – причем, как можно увидеть, “способ мышления” не универсален. Можно начинать “от объектов”, как древнегреческие философы, можно – “от фактов”, в обоих случаях получим некую более-менее адекватную “картину мира”. В зависимости от поставленной задачи представление “мира” в компьютерной программе может быть разным, и “объектно-ориентированное” – далеко не единственное.

Запись опубликована в блоге Шуры Люберецкого. Вы можете оставлять свои комментарии там, используя свое имя пользователя из ЖЖ (вход по OpenID).