Введение

использование в распределенной объектной коммуникации

Скелетное программирование — это стиль компьютерного программирования, основанный на простых высокоуровневых программных структурах и так называемом фиктивном коде. Программные скелеты напоминают псевдокод, но позволяют выполнять разбор, компиляцию и тестирование кода. Фиктивный код вставляется в скелет программы для имитации обработки и предотвращения сообщений об ошибках компиляции. Это может включать пустые объявления функций или функции, которые возвращают корректный результат только для простого тестового случая, когда ожидаемый ответ кода известен. Скелетное программирование облегчает подход к проектированию сверху вниз, при котором разрабатывается и кодируется частично функциональная система с полными высокоуровневыми структурами, а затем эта система постепенно расширяется для удовлетворения требованиям проекта. Программные скелеты также иногда используются для высокоуровневых описаний алгоритмов. Скелет программы также может использоваться в качестве шаблона, отражающего синтаксис и структуры, обычно используемые в широком классе задач. Скелетные программы используются в шаблоне проектирования «шаблонный метод», применяемом в объектно-ориентированном программировании. В объектно-ориентированном программировании фиктивный код соответствует абстрактному методу, заглушке метода или имитирующему объекту. В терминологии Java Remote Method Invocation (Java RMI) заглушка взаимодействует на стороне клиента со скелетом на стороне сервера. Скелет класса — это схема класса, используемая в разработке программного обеспечения. Он содержит описание ролей класса и описывает назначение переменных и методов, но не реализует их. Класс впоследствии реализуется на основе скелета. Скелет также может быть известен как интерфейс или абстрактный класс в языках, следующих полиморфной парадигме.

Предыстория

Современное программное обеспечение часто бывает сложным по множеству причин. Это может означать, что разработать его не может один программист, или что другие модули и компоненты необходимо импортировать отдельно. Сами программы также могут быть слишком сложными, некоторые из них имеют несколько методов, одновременно обращающихся к одной переменной, или даже генерируют пиксели для дисплеев. Шаблонный код (или каркас кода) используется, чтобы помочь программистам разрабатывать код с минимальным количеством ошибок на этапе компиляции. Шаблонный код наиболее часто встречается в параллельном программировании, но также применяется и в других ситуациях, например, в документации к языкам программирования. Это помогает упростить основную функциональность потенциально сложного метода. Его также можно использовать, чтобы небольшая функция в составе более крупной программы временно работала без полной реализации. Такой подход к программированию проще, чем написание полноценной функции, поскольку шаблонные функции не обязаны включать основную функциональность и вместо этого могут быть жестко запрограммированы для использования в процессе разработки. Обычно они содержат синтаксически верный код для определения метода, а также комментарии, поясняющие работу программы. Не всегда необходимо называть фрагмент кода шаблонным, чтобы он таковым являлся.

Связь с псевдокодом

Псевдокод чаще всего используется при разработке структуры нового программного обеспечения. Это описание на простом английском языке конкретной функции в рамках более крупной системы, или даже представление целой программы. Псевдокод похож на каркасное программирование, однако отличается тем, что псевдокод является прежде всего неформальным методом программирования. Заглушки кода также очень похожи на это, где код используется просто как временное решение или для обозначения предполагаемого наличия метода в классе или интерфейсе. Компьютерные программисты чрезвычайно зависимы от псевдокода, настолько, что это оказывает измеримое влияние на их мировосприятие. Объектно-ориентированные языки ориентированы на иерархическую структуру реализации, а не на простой подход сверху вниз, характерный для других языков. «Объекты» хранят в себе данные и переменные, что позволяет обычно писать более эффективную программу. Эти объекты имеют отдельные функции, которые могут обращаться к внутренним переменным, известным как методы. Каждый метод определяется в одном и том же формате, с указанием имени метода и синтаксиса, который будет использоваться в интегрированной среде разработки, четко видимых в начале блока. Благодаря акценту Java на области видимости, типам данных и наследованию, этот синтаксис особенно полезен для начинающих, если не для всех программистов. За этим следует подробное описание работы метода, с указанием возможных ошибок. Python использует аналогичный подход для документирования встроенных методов, однако отражает отсутствие в языке строгой привязки к области видимости и типам данных. Эта документация содержит синтаксис каждого метода, а также краткое описание и пример типичного использования метода или функции. Каркасный код, представленный в примере, позволяет программистам быстро понять назначение функции.

Определение класса

Классы, написанные сторонними разработчиками, в основном как часть библиотек, также демонстрируют свои возможности программирования в виде скелетного кода. Это помогает новым пользователям библиотеки понять, как работают функции и методы. P5.js использует этот формат на своей странице документации, чтобы объяснить предполагаемое использование определенных встроенных функций. Это отличается от документации по языку программирования, которая использует скелетный код для отображения параметров, а не всех возможных вариантов применения метода. Интерфейсы естественного языка (Natural Language Interfaces, NLI) чаще всего встречаются в ситуациях, когда программисты пытаются принять ввод, обычно описываемый в разговорной речи (без использования специфической терминологии языка программирования), и использовать его для создания программы или метода. В реализации этого подхода используется небольшой фрагмент скелетного кода, чтобы показать, как функция работает в фоновом режиме. Другие формы NLI используют различные типы ввода, от речи пользователей на разных языках до управления жестами, для достижения схожих результатов. Поскольку языки программирования разрабатываются и пишутся преимущественно на английском языке, людям, говорящим на других языках, бывает сложно разрабатывать новое программное обеспечение. NLI использовались в некоторых исследованиях для помощи таким пользователям. В одном из исследований показано, что классы на Java можно создавать с помощью NLI. Это избавляет от необходимости изучения синтаксических правил, однако приводит к тому, что класс создается с использованием базового набора скелетного кода.

Параллельное программирование

Параллельное программирование — это одновременное выполнение нескольких функций, чаще всего используемое для повышения производительности. Как правило, это самые сложные типы программ для разработки из-за их сложности и тесной взаимосвязи с используемым аппаратным обеспечением. Многие разработчики пытались создавать программы с такой базовой функциональностью, однако результаты были неоднозначными. В параллельном программировании используются алгоритмические каркасы (скелетные фреймворки) для абстрактного описания используемых методов с целью последующей разработки. Эти каркасы не ограничиваются одним типом, и каждый из них имеет различные цели, направленные на повышение эффективности программы разработчика. Их можно классифицировать на три основных типа: параллелизм данных, параллелизм задач и гранулярность.

Параллельные данные

Эти алгоритмы используются для разработки программ, работающих с большими объемами данных, обычно для выявления связей между данными для последующего использования. Алгоритмы параллельной обработки данных включают в себя ‘maps’, ‘forks’ и ‘reduces’ или ‘scans’. ‘Maps’ – наиболее часто используемые алгоритмы параллельной обработки данных, и обычно подразумевают выполнение одной операции над большим набором данных. Для повышения эффективности, к нескольким наборам данных эта операция применяется одновременно, а затем данные объединяются в конце. ‘Forks’ аналогичны ‘maps’, но используют другую операцию для определенных типов данных. Это называется множественным параллелизмом данных. ‘Reduces’ или ‘scans’ используются для применения префиксов к набору данных, после чего к данным применяется операция. Они отличаются от ‘maps’ тем, что в процессе выполнения метода формируют набор промежуточных результатов.

Параллельная задача

Эти операции, как следует из их названия, работают с задачами. Каждый тип алгоритма в этой категории отличается изменением поведения при переходе между задачами. Алгоритмы параллельной обработки задач включают в себя ‘sequentials’, ‘farms’, ‘pipes’, ‘if’, ‘for’ и ‘while’. ‘Sequential’ завершает и прекращает работу вложенного набора скелетных алгоритмов. Методы и программы, составляющие скелеты, включаются в качестве завершающих элементов программы перед её закрытием. ‘Farms’ (фермы) представляют собой группу задач, рабочий процесс или структуру «мастер-ведомый». Они выполняют задачи, реплицируя их на несколько потоков и запуская параллельно. Это распределяет нагрузку между потоками, эффективно создавая отношения «мастер-ведомый». ‘Pipes’ (конвейеры) – это более традиционные формы алгоритмов, где каждый метод или функция выполняется последовательно, в том порядке, в котором их написал программист. Параллелизм достигается за счет одновременного вычисления различных задач над набором данных, обычно входными, для повышения производительности и скорости. Каждое одновременное вычисление называется стадией. Алгоритм-конвейер может быть вложенным, когда один конвейер находится внутри другого, каждый из которых разделяет ответственность для увеличения скорости и количества стадий. ‘If’ (если) обеспечивает условное разделение задач в программе, разделяя набор скелетного кода на две основные секции. Программе предоставляется условное выражение, определяющее алгоритм для выполнения. ‘For’ (для) выполняет задачу заданное программистом количество раз, обеспечивая более эффективный код. Количество выполнений кода является предопределенным значением, которое нельзя изменить во время выполнения. Задача должна быть выполнена указанное количество раз. ‘While’ (пока) – это алгоритм, очень похожий на алгоритм ‘for’, где задача также выполняется несколько раз. Однако в алгоритмах ‘while’ программа вычисляет задачу несколько раз, пока не будет выполнено условное выражение. Это означает, что алгоритм ‘while’ может выполнять свою задачу разное количество раз при каждом запуске.

Скелеты резолюции

Эти скелеты сильно отличаются от типичных скелетов, обнаруженных выше. Алгоритмы "решения" (Resolution) используют комбинацию методов для решения заданной проблемы. Заданная алгоритму проблема может представлять собой "семейство проблем". Существует два основных типа этих скелетов: "разделяй и властвуй" (divide and conquer) или "метод ветвей и границ" (branch and bound). "Разделяй и властвуй" использует скелет "карта" в качестве основы, комбинируя его со скелетом "цикл" (while) для решения проблемы. В алгоритмах "карта" функции к данным применяются одновременно. В алгоритме "разделяй и властвуй" к набору данных применяется функция с использованием скелета "карта", однако это может выполняться рекурсивно с использованием алгоритма "цикл". "Цикл" прекращается только тогда, когда проблема решена полностью. "Метод ветвей и границ" – это алгоритм, который также использует алгоритмы "карта", однако вместо применения алгоритма "цикл" для одновременного выполнения задач, этот алгоритм разделяет задачи на ветви. Каждая ветвь имеет определенную цель или "границу" (bound), при достижении которой условное выражение приводит к её остановке.