Код как рассказ
02 апреля 2009


Читать хорошую книгу всегда приятно. Повествование в ней идет последовательно, плавно. Хороший автор старается подвести читателя к какой-то мысли и уже после того, как читатель все сам понимает, автор просто высказывает понятое вслух.


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


Для того, чтобы код стал хорошим его нужно писать как рассказ, как повесть, как роман… как интересную историю. У рассказа есть название и автор. В рассказе есть предисловие, содержание и заключение, а бывает, что нет. В рассказе есть сюжет.


Хороший код не похож на работу фокусника, иллюзию или советскую пропаганду. Он не вводит в заблуждение. Он информирует, а не дезинформирует.

Хороший код, как и рассказ, начинается с заглавной страницы — с названия модуля или файла. По названию сразу понятно, о чем пойдет речь внутри. Вначале хорошего кода написано кто, когда и зачем его написал.

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

У любого кода есть интерфейс. Интерфейс похож на краткое содержание глав рассказа. В хорошем коде интерфейс-содержание сразу виден и написан так, что прочтя его читать основной рассказ (реализацию) уже не обязательно.

Правда, 24 мая 1982 г.

Из книги Эдварда Тафти,
The Visual Display of Quantitative Information
(Cheshire, Connecticut, second edition, 2007), c. 76


Хороший код работает. Хороший код работает именно так, как написано в содержании (интерфейсе).


В хорошем коде могут быть шутки, но это не значить, что шутки делают код хорошим.


Если не лениться, то из плохого кода можно сделать хороший. Хороший код можно превратить в плохой, если постараться.

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

Martin Fowler,
Refactoring: Improving the Design of Existing Code



procedure coeff;
var
  h1,h2,hn1,hn2,hii,hi,hi1:double;
  ii,i1,i2,n1,n2,n3:integer;
begin
  h1:=x[2]-x[1];
  h2:=x[3]-x[2];
  n1:=n-1;
  n2:=n-2;
  hn1:=x[n]-x[n1];
  hn2:=x[n1]-x[n2];
  c[1]:=h1/3+1/sqr(h1)*(ro[1]+ro[2]);
  d[1]:=h1/6-1/h1*(1/h1+1/h2)*ro[2]-1/sqr(h1)*ro[1];
  e[1]:=ro[2]/(h1*h2);
  b[2]:=d[1];
  a[3]:=e[1];
  a[n]:=ro[n1]/(hn1*hn2);
  b[n]:=hn1/6-1/hn1*(1/hn1+1/hn2)*ro[n1]-ro[n]/sqr(hn1);
  c[n]:=hn1/3+1/sqr(hn1)*(ro[n1]+ro[n]);
  d[n1]:=b[n];
  e[n2]:=a[n];
  f[1]:=(y[2]-y[1])/h1-y1;
  f[n]:=yn-(y[n]-y[n1])/hn1;
  for i:=2 to n1 do
  begin
    II:=I-1;
    i1:=i+1;
    hii:=x[i]-x[ii];
    hi:=x[i1]-x[i];
    f[i]:=((y[i1]-y[i])/hi-(y[i]-y[ii])/hii);
  end;
 
  for i:=2 to n2 do
  begin
    ii:=i-1;
    i1:=i+1;
    i2:=i+2;
    hii:=x[i]-x[ii];
    hi:=x[i1]-x[i];
    hi1:=x[i2]-x[i1];
    d[i]:=hi/6-1/hi*((1/hii+1/hi)*ro[i]+(1/hi+1/hi1)*ro[i1]);
    b[i1]:=d[i];
  end;
  n3:=n-3;
 
  for i:=2 to n3 do
  begin
    i1:=i+1;
    i2:=i+2;
    hi:=x[i1]-x[i];
    hi1:=x[i2]-x[i1];
    e[i]:=ro[i1]/(hi*hi1);
    a[i2]:=e[i];
  end;
...
 
{************************************************************}
{                                                            }
{                             KSpline                        }
{                Copyright (c) 2009  KSoftWare               }
{                                                            }
{                                                            }
{  Разработчик: Николай Товеровский                          }
{  Модифицирован: 31 марта 2009                              }
{  Описание: Этот модуль предоставляет удобный               }
{            и безопасный доступ к методам                   }
{            модуля FSplineUnit, который позволяет           }
{            аппроксимировать функции сплайном.              }
{************************************************************}
unit KSpline;
 
interface
uses
  SysUtils, KArrayTypes, KArrayRoutines;
 
type
 
 {TSplineController — основной класс, инкапсулирующий работу с
  модулем FSplineUnit.}
  TSplineController = class
  private
    function GetApproximatingArray: TDoublePointArray;
    function GetSecondDerivativeArray: TDoublePointArray;
    function GetFirstDerivativeArray: TDoublePointArray;
    function GetInputArray: TDoublePointArray;      
  protected
   {Этот метод позволяет извлекать данные из глобальных массивов FSplineUnit.}
    function GetDataFromGlobalArrays(const GlobalXArray: array of Double;
      const GlobalYArray: array of Double): TDoublePointArray;
  public
   {Применить сплайн к функции.
 
    На вход подается массив и жесткость сплайна.
    Чем выше жесткость, тем более гладкой получится кривая.
 
    В результате получится набор массивов, которые доступны через
    свойства такие как ApproximatingArray (см. ниже).
 
    Заметьте, что жесткость можно задавать для каждой точки отдельно,
    но эта возможность скрыта внутри.}
    procedure ApplySpline(const InputArray: TDoublePointArray;
      Rigidity: Double = 50000);
 
   {Через эти свойства можно получить доступ к результатам работы
    аппроксимации (см. ApplySpline).}
    property InputArray: TDoublePointArray read GetInputArray;
    property ApproximatingArray: TDoublePointArray read GetApproximatingArray;
    property FirstDerivativeArray: TDoublePointArray read GetFirstDerivativeArray;
    property SecondDerivativeArray: TDoublePointArray read GetSecondDerivativeArray;
  end;

(В коде справа использованы висячие комментарии.)


Писать хороший код — хорошо. Писать плохой код — плохо.


Николай Товеровский
При использовании материалов ссылка на ksoftware.ru обязательна.

См. также