Pull to refresh

Ролевое информационное моделирование в программировании

Reading time6 min
Views2.4K
Предисловие

Данная статья была опубликована в журнале «Образовательные технологии» за 2010 год. Поскольку, на мой взгляд, обучение программированию не менее важно, чем само программирование, я решил адаптировать её и для Хабра. В ней я постарался дать ответ на вопрос «Зачем?». Надеюсь, она будет полезна не только начинающим программистам, но и уже маститым гуру. Если я смог вас заинтересовать, прошу пожаловать под кат.

Краткая диспозиция

Итак, определим для начала, что такое ролевое информационное моделирование. Под ролевым информационным моделированием (РИМ) будем понимать такое информационное моделирование, при котором постановка задачи на разработку модели и/или ее последующий анализ осуществляется с точек зрения людей, выступающих в различных социальных ролях. Такая методология требует от разработчиков умения определять проблемы и ставить задачи, выделять главные и второстепенные свойства объектов, необходимые для построения моделей, уметь решать поставленные задачи с использованием различных инструментов, в том числе и программных средств, прогнозировать и оценивать результаты своей работы.

Источник проблемы

При программировании мы зачастую выступаем в одной роли — разработчик, и процесс изучения любого языка программирования строится исходя из этой позиции. При таком подходе некоторые конструкции языка (например, комментарии) на первый взгляд кажутся избыточными и не требующими должного внимания. Методика РИМ позволяет по-новому раскрыть назначение отдельных инструментов языка программирования, подчеркнуть их важность для грамотного решения поставленной задачи. Выдающийся голландский учёный Эдсгер В. Дейкстра отметил: «Глубоко ошибается тот, кто думает, что изделиями программистов являются программы, которые они пишут. Программист обязан создавать заслуживающие доверия решения и представлять их в форме убедительных доводов, а текст написанной программы является лишь сопроводительным материалом, к которому эти доказательства применимы».
Проиллюстрируем вышесказанное примером. Пусть необходимо написать программу вычисления двойного факториала для нечётного числа n, используя рекурсию. Напомним, что двойной факториал является произведением всех натуральных чисел той же чётности, что и n, до n включительно.
Одним из вариантов решения этой задачи будет следующая программа на языке Pascal (естественно, я знаю, что программа не будет работать для n > 21, однако, не нарушая общности, её можно использовать в качестве примера):
program oddfactorial;
uses crt;
var n: integer;
function F(n: integer): longint;
begin
	if n = 1 then F:= 1
	else 
	if n = 3 then F:= 3
	else F:= n*F(n-2);
end;
begin
	ClrScr;
	repeat
		Readln(n);
	until odd(n);
	Write(F(n));
	Readln;
end.


Диагностика

С точки зрения разработчика данная программа полностью решает поставленную задачу, однако, если мы проанализируем решение с позиции пользователя, то предложенный вариант будет нуждаться в доработке.
Действительно, если мы откомпилируем программу и запустим её на выполнение, то для пользователя процесс работы с ней будет похож на общение с «чёрным ящиком»: программа на входе считывает числа до тех пор, пока не будет введено нечётное и на выходе выдаёт вычисленный ответ. Естественно, что ввод и вывод программы должны содержать инструкции для пользователя:
program oddfactorial;
uses crt;
var n: integer;
function F(n: integer): longint;
begin
	if n = 1 then F:= 1
	else 
	if n = 3 then F:= 3
	else F:= n*F(n-2);
end;
begin
	ClrScr;
	repeat
		Write('Введите, пожалуйста, нечётное число для вычисления двойного факториала: ');
		Readln(n);
	until odd(n);
	Write('Двойной факториал для числа ',n,' равен ');
	Write(F(n));
	Readln;
end.

Таким образом, роль пользователя помогает нам акцентировать внимание на грамотном оформлении ввода и вывода данных, что не всегда бывает очевидно.

Нет предела совершенству

Теперь рассмотрим третью роль — сторонний разработчик. Необходимость такой роли вызвана тем, что крупные проекты требуют координированных действий большого числа разработчиков. Для стороннего разработчика важнейшим требованием к программе является её понятность, достичь которую можно соблюдением нескольких стилей программирования, неочевидных для молодых программистов.
Концепция одного стиля заключается в использовании понятных имён переменных. Согласно венгерской нотации, например, в имени переменной должна содержаться информация о ней, прежде всего о ее типе: имя переменной pszLicFileContents говорит о том, что она указатель (p), на строку фиксированного размера (sz), в названии переменной pbContent закодирован ее тип LPBYTE, переменная bVerified имеет тип bool.
Однако строгая типизация не всегда может быть эффективно заменена искусственными средствами, и поддержание этих искусственных средств не всегда оправдывает затраченные усилия. Современные подходы предлагают называть переменные исключительно по смыслу: SelectedIndexInTable, OpenedFileName.
Оформление исходного кода программы также позволяет повысить её ясность. Язык программирования Pascal допускает перечисление операторов программы в одну строчку с разделителями «;» и «.», однако очевидно, что такая запись непонятна и сложна для восприятия. В указанных нами примерах блоки определения переменных, циклы, операторы ввода и вывода оформлены отступами. Существуют языки программирования, например, Python, которые не допускают запуска программы без правильного оформления кода.
Кроме того, значительно повысить ясность кода помогают комментарии. Рекомендуется подробно комментировать каждый объект и все публичные методы объекта программы или модуля, а также переменные, если таковые есть, плюс обязательны комментарии для внутренних методов и переменных, а также внутри функций необходимо комментировать особо сложные и важные моменты. Существует подход, предлагающий прежде чем писать функцию, описывать ее поведение подробно в комментарии:
{Функция getlines считывает введенные с клавиатуры строки, записывает их в массив str и возвращает количество считанных строк}
function getlines(var str: array of string): integer;
var
	i: integer; {Счетчик строк}
begin
	i:= 0; {Инициализация счетчика}
{Пока не достигнут конец файла считываем следующую строку и увеличиваем счетчик}
	while not eof (input) do
	begin
		Readln(str[i]);
		inc(i);
	end;
{Возвращаем количество считанных строк}
	getlines:= i;
end;

Необходимо отметить, что у сторонников комментирования исходного кода есть противники, утверждающие, что комментарии подспудно подталкивают разработчика писать непонятный код (ведь в комментариях есть разъяснение). Это утверждение представляется достаточно разумным, однако, поскольку уровень подготовки разработчиков различен, оптимальным выходом из сложившейся дилеммы будет симбиоз понятного кода и комментариев для наиболее сложных участков программы.
Следуя перечисленным выше подходам, текст программы из предложенного нами примера должен быть модифицирован следующим образом:
program oddfactorial;
uses crt;
var n: integer;
{Функция DoubleFactorial считает двойной факториал от переданного ей числа n}
function DoubleFactorial(n: integer): longint;
begin
{Первые два условия взяты из определения двойного факториала}
	if n = 1 then DoubleFactorial:= 1
	else 
	if n = 3 then DoubleFactorial:= 3
{Рекурсивный вызов функции}
	else DoubleFactorial:= n*DoubleFactorial(n-2);
end;
begin
	ClrScr;
	repeat
		Write('Введите, пожалуйста, нечётное число для вычисления двойного факториала');
                Readln(n);
	until odd(n); {Ввод чисел продолжается до тех пор, пока не будет введено нечётное число}
	Write('Двойной факториал для числа ',n,' равен ');
	Write(DoubleFactorial(n));
	Readln;
end.

Таким образом, использование ролевого информационного моделирования при обучении программированию позволяет выявить возможные проблемы уже на этапе разработки модели решения задачи, шире взглянуть на возможности конструкций языка программирования, акцентировать внимание разработчиков на грамотном оформлении кода программы и заботе о пользователе.

P.S.

Естественно, большинство из читающих Хабр скажет, что всё это было известно и без меня. Я тоже так думал, пока не попал на проверку олимпиадных задач городского этапа. Меня поразила небрежность в оформлении кода большинства участников — программы работали по принципу чёрного ящика. Только по имени файла и номеру задачи удавалось определить, что же нужно подать на вход: файл, последовательность цифр или букв. Я понимаю, что для олимпиадных заданий, прежде всего, важны скорость работы и правильность, но когда принцип «работает и ладно» берёт вверх и в обыденном программировании, то тут впору задуматься.
Мы ведь ругаем программы с плохим интерфейсом, неудобным дизайном диалогов и т.д. А это, на мой взгляд, результат технократического подхода к разработке, мол, «все юзеры тупы по определению».
В своей статье я постарался кратко изложить принципы РИМ, которые учат смотреть на свой продукт под разными углами. Надеюсь, для кого-то они будут полезны.
Tags:
Hubs:
+2
Comments2

Articles