Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Сильный искусственный интеллект и объектно-ориентированное программирование синтез парадигм
.pdf
ществляется через конкретную команду. Конкретная команда
связана с инициатором по типу композиции: инициатор создает
объект конкретной команды и без инициатора его бы не существовало. Команда же (базовая команда) связана с получателем
по типу композиции, так как она изначально создается «под
него» и для работы с ним.
Значимость паттерна в контексте разработки систем
сильного ИИ. Данный поведенческий паттерн актуально ис-
пользовать в контексте разработки систем сильного ИИ вполне
логичным образом: для преобразования, упаковки и передачи
информации. Однако необходимо, разумеется, абстрагировать
суть паттерна. А в абстрактном виде она, как уже постулировалось, заключается в наличии буфера между программными компонентами, передающими информацию некоторого типа другим
программным компонентам для ее последующей обработки
и воспроизведения некоторой реакции на эту информацию.
В контексте данного паттерна наиболее значимой абстрактной
характеристикой является специфика преобразования информации, сама ее идея: информация из, можно так выразиться, некоторых импульсов преобразуется в качественно иной вид – в нечто
очень отдаленно, но все же более подобное субъекту действия,
чем просто совокупность однонаправленных импульсов (абстрактные запросы, к примеру). Ведь объект – это уже нечто упорядоченное, обладающее некой формой, определенным содержанием,
специфической идентичностью и т. д. Напомним, что спецификой паттерна «Команда» является качественное преобразование
информации с ее воплощением в виде упорядоченной информационной структуры с потенциалом использования составляющих
блоков информации по усмотрению субъекта (информационной
структуры). Если абстрагироваться еще сильнее, то можно будет (примерно как в вышеописанной ситуации о TransferCoin)
говорить о некоем аккумулировании в единую информационную структуру разнородных, но по какому-либо критерию все
же связанных блоков данных. И, что крайне важно, эта структура должна будет являться по отношению ко всей совокупности
данных, ее составляющих, чем-то большим, чем-то качественно
191

новым, т. е. чем-то эмерджентным. Выглядит это, как будто
только что существовали просто некоторые блоки данных, а теперь мы уже имеем дело с вполне определенной сущностью,
с новым субъектом инфополя. А это напоминает гипотетический
процесс зарождения системы сильного ИИ.
Примеры, напоминающие реализацию подобного механизма,
предположительно наличествуют также и в сфере человеческой
психики и являются определенными и задокументированными
в некоторых психотерапевтических направлениях, в частности
в психоанализе. У одного из представителей кляйнианского психоанализа, У. Р. Д. Фейрбейрна, имеется теория формирования
психики, основанная на специфических отношениях младенца
с окружающим миром. В частности, он упоминает расщепление
целостной психики субъекта на три части, одной из которых является так им определенный «внутренний диверсант», который
представляет собой антилибидную часть «Я» [119]. «Внутренний
диверсант» представляет собой активно действующего психического субъекта, разумеется (в духе психоанализа), неосознаваемого. Так вот, что интересно, это точно так же, как и в слу чае
с абстрагированием сути паттерна «Команда»: происходит качественное преобразование изначально разрозненных блоков данных путем их оформления в сущность нового порядка, способную активно действовать в рамках доступного ей контекста.
Предполагаемый феномен внутреннего диверсанта приведен
просто в качестве примера, иллюстрирующего функционирование механизмов, которые свойственны абстрагированному паттерну «Команда».
Резюмируя данный паттерн, стоит отметить, что именно заложенное в его суть качественное преобразование данных с последующим созданием на их основе новой сущности, являющейся
чем-то большим, чем все данные вместе взятые, чем-то эмерджентным – именно этот аспект «Команды» и стоит отдельно позаимствовать для нужд разработки систем сильного ИИ по причине
его чрезвычайной значимости в контексте нашего исследования
и его самоорганизующей природы.
192

12.6. Поведенческий паттерн «Интерпретатор»
Идентификатор. Интерпретатор (Interpreter).
Классические элементы. Абстрактное выражение, терми-
нальное выражение, нетерминальное выражение, контекст.
Назначение. Как указывается в Design patterns, «Интерпретатор» «для заданного языка определяет представление его грамматики, а также интерпретатор предложений этого языка» [114,
с. 236]. Собственно говоря, определение паттерна «Интерпретатор», которое приводится выше, несколько вырвано из контекста.
На самом деле имеется в виду практический буквальный конструктор для анализа данных, дальнейшего их преобразования
и синтеза в виде решения некоторой формализованной задачи,
основанной на этих данных. Этот конструктор предназначен
осуществлять разбор некоторой задачи на составляющие, что
позволяет ему «понять» задачу, преобразовать ее в необходимый для решения вид и затем непосредственно решить.
Проблема. Классическое определение подходящей для «Интерпретатора» проблемы описано в Design patterns и звучит так:
«Если некоторая задача встречается достаточно часто, то имеет
смысл представить ее конкретные проявления в виде предложений на простом языке» [114, с. 237]. Т. е. у нас имеется некоторая
задача, состоящая из определенного конечного количества составляющих – подзадач. Количество возможных подзадач не
должно быть большим, иначе данный паттерн не подойдет для
применения в контексте. Также мы имеем возможность формализовать задачу, т. е. преобразовать ее в простые формы какихлибо символов (неважно, каких именно: английский алфавит,
римские цифры или скаляры алгебры логики), которых также
небольшое количество. Смысл преобразования задачи в том, что
после трансформации она может быть легко решена, т. е. в процессе преобразования мы должны максимально упростить, проанализировать, разложить на составляющие данную нам задачу.
Задачи, которые решать сложно, также вряд ли подойдут для
реализации паттерна «Интерпретатор».
Концептуальное решение. В контексте решения вышеописанной проблемы подразумевается некоторый, логично будет
193

так сказать, решатель. Этот решатель представляет собой, как уже
постулировалось выше, конструктор. Вышеописанные классические элементы паттерна «Решатель» способны, в зависимости
от текущего состояния контекста, выполнять различные задачи.
В частности, терминальное выражение являет собой ПК, ответственный за атомарные единицы какого-либо языка, т. е. за те
конструкции языка, которые далее уже неразложимы на составляющие (символы, к примеру). Нетерминальное выражение,
в свою очередь, представляет собой ПК, который ответственен
за правила построения синтаксических конструкций из терминальных символов (тех, за которые ответственен предыдущий
компонент), т. е. он ответственен за правила конкретного языка.
Контекст представляет собой ПК, который ответственен за общую информацию о происходящем в процессе интерпретации
в каждый конкретный момент. Ну и абстрактное выражение
является программным компонентом, который определяет некий
общий интерфейс, в частности специфику самого метода интерпретирования. Понятно, что в данном контексте должен использоваться рекурсивный алгоритм. Конструктором же, в сущ ности,
данный паттерн является по той причине, что итогом всего целостного процесса интерпретации является абстрактное синтаксическое дерево. Абстрактное же синтаксическое дерево (AST)
представляет собой специфический способ фиксирования и репрезентации иерархически распределенной информации на каком-либо конкретном языке.
Предполагаемые результаты и преимущества. Предполагается, что реализация паттерна «Интерпретатор» позволяет автоматизировать интерпретирование грамматических конструкций
простого языка. Также будет достаточно несложно при применении паттерна добавить некоторые новые правила или же терминалы, т. е. мы получим масштабируемость системы в качестве
преимущества. Разбор каких-либо задач, сопоставление строк,
определение специфики и особенностей выражений на конкретном языке – за все данные операции может быть ответственен
паттерн «Интерпретатор».
Гипотетический пример реализации паттерна. Проще
всего осмыслить примерную реализацию данного паттерна, как
194

ни странно, на конкретном примере использования возможностей функционального программирования. Мы выберем для демонстрации какой-нибудь эзотерический язык программирования,
допустим MiniStringFuck. Данный эзотерический язык программирования, или сокращенно эсоланг, является дочерним языком
по отношению к довольно известному эсолангу Brainfuck. Мы
выбрали его по причине его наибольшей простоты. Основу грамматики данного языка составляют всего два символа (попадающие под юрисдикцию терминального выражения, если реализовывать паттерн в рамках ООП), но, несмотря на это, на нем можно
написать любой текст. В качестве некоего хранилища выступает
всего одна ячейка памяти (в данном случае попадающая под
юрисдикцию контекста), которую допустимо представить в ви-
де переменной с числовым значением 0. Правила синтаксиса
(попадающие под юрисдикцию нетерминального выражения)
следующие: при попадании на входную ленту или, можно перефразировать, в поле зрения интерпретатора символа плюс (+)
значение ячейки памяти увеличивается на 1, а при попадании
в поле зрения интерпретатора символа точки (обычная точка)
значение выносится на выходную ленту. Контекст следит за
тем, чтобы значение ячейки памяти не становилось больше 256.
В противном случае он сбрасывает значение ячейки на 0. Абстрактное выражение в данном случае может быть ответственным за конечное преобразование данных после их попадания на
выходную ленту.
Таким образом, простейший интерпретатор будет выглядеть
как функция, которая получает на вход строку, состоящую из
последовательно расположенных плюсов и точек. В функциональной области видимости определяется переменная и инициализируется числовым значением 0. Также определяется некоторая выходная лента, которая представлена какой-либо удобной
структурой данных, например массивом или строкой (разумеется, что строка в данном случае предпочтительнее, но тогда необходимо сразу преобразовывать данные после каждой встреченной во входной строке точки). Далее запускается цикл, который
последовательно считывает каждое значение входной строки
195

и реализует логику в зависимости от того, представлено оно
точкой или плюсом. В случае плюса значение переменной, которая хранит наши данные, увеличивается на 1, а в случае точки
значение переменной добавляется на выходную ленту после (возможно) предварительного преобразования. Цикл заканчивается
тогда, когда закончилась строка. После завершения цикла функция осуществляет возврат значения, которое представлено (как
правило) каким-либо текстом. Вот и вся реализация паттерна
«Интерпретатор» в стиле функционального программирования.
В контексте же макромира примеры интерпретации текстов
окружают нас уже практически в любой момент.
Осмысление структуры паттерна. В контексте структуры
данного паттерна наличествует несколько разновидностей взаимосвязи между ПК. Терминальное выражение и нетерминаль-
ное выражение связаны с абстрактным выражением отноше-
ниями наследования, так как они оба являются его подклассами
и абстрактное выражение определяет их общий функционал,
в частности (в контексте классической реализации) абстрактный метод Interpret. Так как контекст содержит в себе общие
данные о ходе интерпретации и является глобальной точкой доступа, он не связан напрямую с остальными элементами. Он
связан с дополнительным элементом паттерна, который также
выделяют в отдельный компонент, а именно – с клиентом. Однако
мы, по уже сложившейся в контексте нашего исследования традиции, посчитали, что в данном конкретном случае дополнительное обособление клиента в отдельный ПК и/или элемент
паттерна – операция излишняя, так как какой-либо пользователь
всегда подразумевается у любого системного процесса. Мы считаем, что целесообразно обособлять клиента в отдельный компонент лишь в том случае, если на него в контексте паттерна
возложены какие-либо функции (в общем смысле слова) помимо
осуществления «заказа».
Значимость паттерна в контексте разработки систем
сильного ИИ. В процессе разработки систем сильного ИИ пове-
денческий паттерн, который, по сути, отвечает за целостное восприятие (не за ощущения, а именно за восприятие), несомненно,
196

важен. В случае с данным паттерном, если представить его в виде некоторой системы ПК, которая ответственна за восприятие,
его терминальным выражением будут как раз ощущения и вообще все блоки воспринимаемой им информации. Они будут
представлены в виде определенных полей данных, которые затем, в ходе взаимодействия системы со свойственной ей средой,
будут упорядочиваться согласно выявленным системой закономерностям. Эти закономерности затем будут попадать под юрисдикцию нетерминального выражения. Контекст же тут будет
выступать в качестве некоего критерия успешности процесса
интерпретирования данных со стороны системы. Т. е. некоторые элементы паттерна «Интерпретатор» должны сами реализовываться системой в процессе ее развития и совершенствования,
потому что только самой системе «виднее», какие именно закономерности полей данных важны непосредственно для нее. Таким образом, мы полагаем, что из структуры данного паттерна
для нужд построения систем сильного ИИ было бы уместно позаимствовать такое образование, как абстрактное выражение,
которое будет определять возможности взаимодействия системы со средой, задавать в целом тот потенциал интерпретирования данных, на который по минимальным параметрам должна
быть способна система. Для определения же успешности/неуспешности интерпретирования данных считаем необходимым
позаимствовать принцип функционирования элемента контекст,
который будет определять, насколько какая-либо конкретная
интерпретация полей данных помогла системе успешно функционировать. Резюмируя паттерн, стоит отдельно заметить, что
процессы ощущения и восприятия окружающей среды со стороны сильного ИИ – это одни из немногих составляющих системы, которые придется определить хоть сколько-то конкретно,
хотя бы для начала процесса запуска системы.
12.7. Поведенческий паттерн «Стратегия»
Идентификатор. Стратегия (Strategy).
Классические элементы. Стратегия, конкретная стратегия,
контекст.
197

Назначение. Как указывается в Design patterns, назначение
паттерна «Стратегия» – «инкапсуляция алгоритма в объект. Основными участниками паттерна являются объекты-стратегии,
инкапсулирующие различные алгоритмы, и контекст, в котором
они работают» [114, с. 56]. Данный паттерн предназначен для
эффективного реагирования на динамически изменяющуюся ситуацию путем выбора одного из различных вариантов этого реагирования. Изменение образа действия программной системы
в runtime вместе с соответствующим ситуации выбором одного
из числа многих варианта этого образа действия и составляет
предназначение паттерна «Стратегия».
Проблема. По сути, проблема в данном случае определяется
двояко, т. е. можно сказать, что мы имеем дело сразу с двумя
проблемами, а если копнуть глубже, то окажется, что с целым
комплексом. В описании проблемы мы в данном случае допустим себе некоторый уровень конкретики, так как речь все же
про паттерн «Стратегия», а это про менеджмент алгоритмов.
Во-первых, у нас в наличии имеется довольно сложная система,
состоящая из большого количества вариантов действий в зависимости от ситуации. Визуально и в упрощенном виде это легче
всего представить, как некоторый большой и запутанный оператор ветвления (if/else) с вложенными различными условиями.
С такой системой самой по себе очень сложно и трудоемко работать и довольно неудобно добавлять в нее новую функциональность. Система, что очевидно, является единой в том смысле,
что буквально представлена всего одним программным компонентом. Сразу становится заметно, что в подобной ситуации
происходит нарушение принципа сильной связности и принципа SOLID – единственной ответственности. Система-компонент
представляет собой god-object в чистом виде. И с этим, конечно
же, необходимо уже на данном этапе что-то делать, т. е. осуществлять глубокий рефакторинг программной системы, а то
и просто переделать с нуля. Второй момент: на каждой из ветвей
оператора ветвления в рамках нашей системы заложен некоторый цикл. Пусть это будет, для примера, цикл поиска нужного
значения в какой-либо структуре данных. Причем, следуя логике
198

нашего (конечно, утрированного) примера системы, представим,
что один и тот же цикл, работающий с различными данными
в зависимости от ветви оператора, буквально каждый раз с нуля
прописан в каждой ветви. Здесь, помимо откровенной бесполезности и неэкономичности подобного решения, также нарушается
и один из организационных принципов ООП – DRY, т. е. «Не повторяйся». Этот принцип свидетельствует в числе прочего
о том, что одну и ту же логику в рамках одной и той же системы
нельзя определять дважды, напротив, ее необходимо преобразовывать в такой вид, который позволит ее многократно использовать (например, вынести в отдельную функцию). И соответственно, данный приведенный фактор также существенно затрудняет
не только внесение в систему изменений, но и просто ее обслуживание. Пусть мы попробовали бы все же вынести неэффективно и неудобно повторяющуюся логику в какой-либо отдельный
ПК, а затем попробовали бы передать в нее также и контекст.
Здесь уже все зависит от конкретной системы. С системой, которая работает со сложными контекстами, такое будет совершенно неудобно осуществлять по причине слишком большого количества аргументов, необходимых для описания контекста. Мы же
хотели бы, в идеале, эффективно функционирующую систему,
масштабируемую, реализующую свое поведение в зависимости
от контекста, податливую к необходимым изменениям и удобную в обслуживании. И вот тут на помощь приходит паттерн
«Стратегия».
Концептуальное решение. С точки зрения функционального программирования решение, подразумеваемое «Стратегией»,
также реализуемо. Однако все же удобнее реализация при помощи
методологии ООП. Итак, мы определяем несколько ПК. Стратегия (элемент паттерна) будет далее определять некий общий
интерфейс для всех конкретных стратегий. Контекст же, также представленный отдельным программным компонентом, будет определять специфику актуальной для системы ситуации
и хранить у себя ссылки на все доступные конкретные стратегии. При возникновении какой-либо ситуации в рамках системы
ПК, оформленный в виде контекста, определяет специфику
199

этой ситуации и далее делегирует ответственность одной из доступных ему конкретных стратегий, представленных ПК, инкапсулирующими в себе некоторый алгоритм, специально подобранный для эффективного функционирования именно при
контексте, аналогичном актуальному. Соответственно, система
разделена на несколько ПК, в каждом из которых инкапсулирована логика, необходимая для осуществления строго конкретной
деятельности (логика не будет повторяться, если она одинакова).
С подобной системой удобно работать: она легко принимает добавления нового функционала (новых конкретных стратегий)
путем простого создания подклассов класса стратегия.
Предполагаемые результаты и преимущества. В рамках
реализации поведенческого паттерна «Стратегия» за счет инкапсуляции логики в ПК мы способны избежать применения
сложных и запутанных операторов ветвления. Также среди преимуществ использования данного паттерна имеются высокая
эластичность системы в плане масштабируемости и расширяемости, удобство взаимодействия с ней и достаточно легкая ее
поддержка.
Гипотетический пример реализации паттерна. Довольно
показательным примером, иллюстрирующим практическую значимость данного паттерна, являются различные системы подборки, коих в наше время великое множество. Для примера:
приложение, которое подбирает оптимальную программу тренировки в зависимости от актуальных потребностей пользователя. Приложение принимает некоторые входные данные, касающиеся антропометрических особенностей пользователя (рост,
вес, далее – опционально), его возраст и предпочитаемый им вариант тренировок. Вариант можно выбрать из предоставляемых,
которых всего наличествует три: тренировка «на массу», тренировка «на силу» и тренировка «на сушку». У системы в ее базе
данных (к которой, скорее всего, имеет доступ контекст) имеется
определенное количество различных упражнений. При введении
пользователем всех тех данных, которые запрашивает приложение, и выборе одного из трех вариантов тренировки контекст
осуществляет фильтрацию базы данных (в данном случае под
200
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
