Модераторы: Се ля ви
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Каков нормальный объем процедуры? Delphi 
:(
    Опции темы
TXC
  Дата 9.6.2007, 01:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 6.5.2007

Репутация: нет
Всего: нет



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

Так например:
Код

procedure TfmDeleteRecords.sbDeleteRecordsClick(Sender: TObject);
var i : Integer;
begin
  {------------------------------------}
  { Якщо видаляємо записи користувачів }
  {------------------------------------}
  if fmDeleteRecords.cbChangeDB.Text='База користувачів' then
  begin
    for i:=1 to fmMain.sgUser.RowCount-1 do
    begin
      { Шукаємо I параметр. }
      if (leUserName.Text<>'') then
        { Якщо є такий I_параметр - ставимо мітку }
        if (pos(leUserName.Text, fmMain.sgUser.Cells[0, i])>0) then
          fmMain.sgUser.RowHeights[i]:=-ABS(fmMain.sgUser.RowHeights[i]);

      { Шукаємо II параметр. }
      if (leUserGroup.Text<>'') then
      begin
        { Якщо є такий II_параметр і I_параметр не шукали - ставимо мітку }
        if (pos(leUserGroup.Text, fmMain.sgUser.Cells[1, i])>0)
            and (leUserName.Text='') then
          fmMain.sgUser.RowHeights[i]:=-ABS(fmMain.sgUser.RowHeights[i]);
        { Якщо немає такого II_параметру, а попередній пошук знайшов - знімаємо мітку }
        if (pos(leUserGroup.Text, fmMain.sgUser.Cells[1, i])=0)
            and (fmMain.sgUser.RowHeights[i]<0) then
          fmMain.sgUser.RowHeights[i]:=ABS(fmMain.sgUser.RowHeights[i]);
      end;

      { Шукаємо III параметр. }
      if (leUserPassword.Text<>'') then
      begin
        { Якщо є такий III_параметр і I-II_параметри не шукали - ставимо мітку }
        if (pos(leUserPassword.Text, fmMain.sgUser.Cells[2, i])>0)
            and (leUserName.Text='')
            and (leUserGroup.Text='') then
          fmMain.sgUser.RowHeights[i]:=-ABS(fmMain.sgUser.RowHeights[i]);
        { Якщо немає такого III_параметру, а попередні пошуки знайшли - знімаємо мітку }
        if (pos(leUserPassword.Text, fmMain.sgUser.Cells[2,i])=0)
            and (fmMain.sgUser.RowHeights[i]<0) then
          fmMain.sgUser.RowHeights[i]:=ABS(fmMain.sgUser.RowHeights[i]);
      end;
    end;
  end;

  {------------------------------}
  { Якщо видаляємо записи питань }
  {------------------------------}
  if fmDeleteRecords.cbChangeDB.Text='База питань' then
  begin
    for i:=1 to fmMain.sgQuestion.RowCount-1 do
    begin
      { Шукаємо I параметр. }
      if (leQuestionName.Text<>'') then
        { Якщо є такий I_параметр - ставимо мітку }
        if (pos(leQuestionName.Text, fmMain.sgQuestion.Cells[0, i])>0) then
          fmMain.sgQuestion.RowHeights[i]:=-ABS(fmMain.sgQuestion.RowHeights[i]);

      { Шукаємо II параметр. }
      if (leQuestionTheme.Text<>'') and (leQuestionTheme.Enabled=True) then
      begin
        { Вибираємо метод оцінки < = > }
        { Якщо є такий II_параметр і I_параметр не шукали - ставимо мітку }
        if ((cbQuestionTheme.Text='<')
            and (fmMain.sgQuestion.Cells[1, i]<leQuestionTheme.Text)
            and (leQuestionName.Text=''))
            OR
            ((cbQuestionTheme.Text='=')
            and (fmMain.sgQuestion.Cells[1, i]=leQuestionTheme.Text)
            and (leQuestionName.Text=''))
            OR
            ((cbQuestionTheme.Text='>')
            and (fmMain.sgQuestion.Cells[1, i]>leQuestionTheme.Text)
            and (leQuestionName.Text=''))
              then
          fmMain.sgQuestion.RowHeights[i]:=-ABS(fmMain.sgQuestion.RowHeights[i]);
        { Якщо немає такого II_параметру, а попередній пошук знайшов - знімаємо мітку }
        if ((cbQuestionTheme.Text='<')
            and (fmMain.sgQuestion.Cells[1, i]>=leQuestionTheme.Text)
            and (fmMain.sgQuestion.RowHeights[i]<0))
            OR
            ((cbQuestionTheme.Text='=')
            and (fmMain.sgQuestion.Cells[1, i]=leQuestionTheme.Text)
            and (fmMain.sgQuestion.RowHeights[i]<0))
            OR
            ((cbQuestionTheme.Text='>')
            and (fmMain.sgQuestion.Cells[1, i]<=leQuestionTheme.Text)
            and (fmMain.sgQuestion.RowHeights[i]<0))
              then
          fmMain.sgQuestion.RowHeights[i]:=ABS(fmMain.sgQuestion.RowHeights[i]);
      end;

      { Шукаємо III параметр. }
      if (leQuestionRightAnswer.Text<>'') and (leQuestionRightAnswer.Enabled=True) then
      begin
        { Вибираємо метод оцінки < = > }
        { Якщо є такий III_параметр і I-II_параметр не шукали - ставимо мітку }
        if ((cbQuestionRightAnswer.Text='<')
            and (fmMain.sgQuestion.Cells[2, i]<leQuestionRightAnswer.Text)
            and (leQuestionName.Text='')
            and (leQuestionTheme.Enabled=False))
            OR
            ((cbQuestionRightAnswer.Text='=')
            and (fmMain.sgQuestion.Cells[2, i]=leQuestionRightAnswer.Text)
            and (leQuestionName.Text='')
            and (leQuestionTheme.Enabled=False))
            OR
            ((cbQuestionRightAnswer.Text='>')
            and (fmMain.sgQuestion.Cells[2, i]>leQuestionRightAnswer.Text)
            and (leQuestionName.Text='')
            and (leQuestionTheme.Enabled=False))
              then
          fmMain.sgQuestion.RowHeights[i]:=-ABS(fmMain.sgQuestion.RowHeights[i]);
        { Якщо немає такого III_параметру, а попередній пошук знайшов - знімаємо мітку }
        if ((cbQuestionRightAnswer.Text='<')
            and (fmMain.sgQuestion.Cells[2, i]>=leQuestionRightAnswer.Text)
            and (fmMain.sgQuestion.RowHeights[i]<0))
            OR
            ((cbQuestionRightAnswer.Text='=')
            and (fmMain.sgQuestion.Cells[2, i]=leQuestionRightAnswer.Text)
            and (fmMain.sgQuestion.RowHeights[i]<0))
            OR
            ((cbQuestionRightAnswer.Text='>')
            and (fmMain.sgQuestion.Cells[2, i]<=leQuestionRightAnswer.Text)
            and (fmMain.sgQuestion.RowHeights[i]<0))
              then
          fmMain.sgQuestion.RowHeights[i]:=ABS(fmMain.sgQuestion.RowHeights[i]);
      end;

      { Шукаємо IV параметр. }
      if (leQuestionPrice.Text<>'') and (leQuestionPrice.Enabled=True) then
      begin
        { Вибираємо метод оцінки < = > }
        { Якщо є такий IV_параметр і I-III_параметр не шукали - ставимо мітку }
        if ((cbQuestionPrice.Text='<')
            and (fmMain.sgQuestion.Cells[3, i]<leQuestionPrice.Text)
            and (leQuestionName.Text='')
            and (leQuestionTheme.Enabled=False)
            and (leQuestionRightAnswer.Enabled=False))
            OR
            ((cbQuestionPrice.Text='=')
            and (fmMain.sgQuestion.Cells[3, i]=leQuestionPrice.Text)
            and (leQuestionName.Text='')
            and (leQuestionTheme.Enabled=False)
            and (leQuestionRightAnswer.Enabled=False))
            OR
            ((cbQuestionPrice.Text='>')
            and (fmMain.sgQuestion.Cells[3, i]>leQuestionPrice.Text)
            and (leQuestionName.Text='')
            and (leQuestionTheme.Enabled=False)
            and (leQuestionRightAnswer.Enabled=False))
              then
          fmMain.sgQuestion.RowHeights[i]:=-ABS(fmMain.sgQuestion.RowHeights[i]);
        { Якщо немає такого IV_параметру, а попередній пошук знайшов - знімаємо мітку }
        if ((cbQuestionPrice.Text='<')
            and (fmMain.sgQuestion.Cells[3, i]>=leQuestionPrice.Text)
            and (fmMain.sgQuestion.RowHeights[i]<0))
            OR
            ((cbQuestionPrice.Text='=')
            and (fmMain.sgQuestion.Cells[3, i]=leQuestionPrice.Text)
            and (fmMain.sgQuestion.RowHeights[i]<0))
            OR
            ((cbQuestionPrice.Text='>')
            and (fmMain.sgQuestion.Cells[3, i]<=leQuestionPrice.Text)
            and (fmMain.sgQuestion.RowHeights[i]<0))
              then
          fmMain.sgQuestion.RowHeights[i]:=ABS(fmMain.sgQuestion.RowHeights[i]);
      end;
    end;
  end;

  {---------------------------}
  { Якщо видаляємо записи тем }
  {---------------------------}
  if fmDeleteRecords.cbChangeDB.Text='База тем' then
  begin
    for i:=1 to fmMain.sgTheme.RowCount-1 do
    begin
      { Шукаємо I параметр. }
      if (leThemeNumber.Text<>'') and (leThemeNumber.Enabled=True) then
      begin
        { Вибираємо метод оцінки < = > }
        { Якщо є такий I_параметр - ставимо мітку }
        if ((cbThemeNumber.Text='<')
            and (fmMain.sgTheme.Cells[0, i]<leThemeNumber.Text))
            OR
            ((cbThemeNumber.Text='=')
            and (fmMain.sgTheme.Cells[0, i]=leThemeNumber.Text))
            OR
            ((cbThemeNumber.Text='>')
            and (fmMain.sgTheme.Cells[0, i]>leThemeNumber.Text))
              then
          fmMain.sgTheme.RowHeights[i]:=-ABS(fmMain.sgTheme.RowHeights[i]);
      end;

      { Шукаємо II параметр. }
      if (leThemeName.Text<>'') then
      begin
        { Якщо є такий II_параметр і I_параметр не шукали - ставимо мітку }
        if (pos(leThemeName.Text, fmMain.sgTheme.Cells[1, i])>0)
            and (leThemeNumber.Text='') then
          fmMain.sgTheme.RowHeights[i]:=-ABS(fmMain.sgTheme.RowHeights[i]);
        { Якщо немає такого II_параметру, а попередній пошук знайшов - знімаємо мітку }
        if (pos(leThemeName.Text, fmMain.sgTheme.Cells[1, i])=0)
            and (fmMain.sgTheme.RowHeights[i]<0) then
          fmMain.sgTheme.RowHeights[i]:=ABS(fmMain.sgTheme.RowHeights[i]);
      end;

      { Шукаємо III параметр. }
      if (leThemePrice.Text<>'') and (leThemePrice.Enabled=True) then
      begin
        { Вибираємо метод оцінки < = > }
        { Якщо є такий III_параметр, і I-II_параметри не шукали - ставимо мітку }
        if ((cbThemePrice.Text='<')
            and (fmMain.sgTheme.Cells[2, i]<leThemePrice.Text)
            and (leThemeNumber.Text='')
            and (leThemeName.Text=''))
            OR
            ((cbThemePrice.Text='=')
            and (fmMain.sgTheme.Cells[2, i]=leThemePrice.Text)
            and (leThemeNumber.Text='')
            and (leThemeName.Text=''))
            OR
            ((cbThemePrice.Text='>')
            and (fmMain.sgTheme.Cells[2, i]>leThemePrice.Text)
            and (leThemeNumber.Text='')
            and (leThemeName.Text=''))
              then
          fmMain.sgTheme.RowHeights[i]:=-ABS(fmMain.sgTheme.RowHeights[i]);
        { Якщо немає такого III_параметру, а попередні пошуки знайшли - знімаємо мітку }
        if ((cbThemePrice.Text='<')
            and (fmMain.sgTheme.Cells[2,i]>=leThemePrice.Text)
            and (fmMain.sgTheme.RowHeights[i]<0))
            OR
            ((cbThemePrice.Text='=')
            and (fmMain.sgTheme.Cells[2,i]<>leThemePrice.Text)
            and (fmMain.sgTheme.RowHeights[i]<0))
            OR
            ((cbThemePrice.Text='>')
            and (fmMain.sgTheme.Cells[2,i]<=leThemePrice.Text)
            and (fmMain.sgTheme.RowHeights[i]<0))
              then
          fmMain.sgTheme.RowHeights[i]:=ABS(fmMain.sgTheme.RowHeights[i]);
      end;
    end;
  end;

  fmMain.sbSaveTable.Click;
  fmMain.sbOpenDB.Click;
end;


Эта процедура занимает 250 строк (включая комментарии).
Это нормальная практика для программиста вообще и для Delphi-программиста в частности? Так и должно быть?

З.Ы.: Не было времени переводить комментарии на русский, потому извиняйте.
Также некоторые условия не оптимизированы. По-этому не швыряться тапками =) (Знаю Pascal 1 год, Delphi - 1/2 года).
PM MAIL WWW   Вверх
Ulysses4j
Дата 9.6.2007, 01:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 304
Регистрация: 6.6.2007
Где: Ростов-на-Дону

Репутация: нет
Всего: 10



Код я не читал, но 250 мне кажется очень много. Часто можно услышать фразу Дейкстры о том, что код метода должен помещаться на экране. Это очень оптимистично, конечно, но стоит к этому стремиться, мне кажется. Некоторые исследования на эту тему приведены в замечательной книжке Стива МакКоннелла "Совершенный код" (п. 7.4), которую можно достать в сети. У него всего сходится к тому, что лучше бы ограничивать длину метода 200-ми строками.


--------------------
Communication is critical to the job of a programmer.
C. Jazdzewski. Fatherly Advice To New Programmers
PM MAIL WWW   Вверх
4d5a
Дата 14.6.2007, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 10.6.2007

Репутация: нет
Всего: 1



У меня обычно методы растягиваются по двум причинам 1) Метод задумывался чтобы решить одну задачу, потом универсализовывался для решения нескольких схожих
2) Когда решение сваливается в разбор разных частных случаев (иногда это необходимо для оптимизации) 
В основном получается меньше 250 строк
Многие считают что задачу надо дифференцировать до предела что бы легче решалась. Мне лично иногда хочется что бы все решение было целостное и заключалось в одном методе.
(сейчас работаю над: http://csys.webhost.ru ) 
Вот САМОЕ длинное что смог найти в написанном за последние 2 месяца 


процедура (delphi) для dll'ки кодирования данных, Этот метод растягивает/сжимает буфер побайтно, advanced мажорирование типа.

Код

{
coment to zoom byte
      FZ_EMPT  = 5601;  // Easy metod,use first char in zn_ sub array
      FZ_NFRQ  = 5602;  // if (zn<0) Take into frq param
      FZ_EDNZ  = 5603;  // _EMP use  n_z ;;; if (zn<0 & if n1- Int n1/zn > 0.5 ) size +1

ie 2 charackteristics consider
 aligment and fill method
}
function ZoomBufByte(inD:TBuf;var outD:TBuf;zn :integer;
        FLAG:integer=FZ_EMPT;n_z:integer=0):integer;
var m,c,k,i,n1,n2,j,inc_inx:integer;
    tmp,tmp1:TBuf;
    s:longint;
    t3:byte;
begin
 result:=-1;
 n1:=Length(inD);
 inc_inx:=0;
 if ((FLAG=FZ_EDNZ)and(n_z<abs(zn))) then inc_inx:=n_z;
 if ( (n1<1)or(zn=0) ) then exit ;
 if (zn>0) then
  begin
   n2:=n1*zn;
   SetLength(outD,n2);
   for i:=0 to n1-1 do
    for j:=0 to zn-1 do
     outD[i*zn+j]:=inD[i];
  end else
  begin
   zn:=abs(zn);
   if (zn>n1) then
    begin
     n2:=1;
     SetLength(outD,1);
     outD[0]:=InD[0];
     exit;
    end;
   n2:=n1 div zn;
   if (FLAG=FZ_EDNZ) then
     if ((n1 mod zn)>(zn div 2)) then Inc(n2);
   SetLength(outD,n2);
   i:=0;j:=0;
   if (FLAG=FZ_NFRQ) then
    begin
       SetLength(tmp,zn); SetLength(tmp1,zn);
       while (j<n2) do
       begin
         c:=0;
         for k:=0 to zn-1 do tmp1[k]:=0;
         for k:=0 to zn-1 do
          begin
           s:=InD[i+k];
           for m:=0 to c-1 do
             if (tmp[m]=s) then
              begin Inc(tmp1[m]); s:=-1; end;
           if (s>=0) then
             begin tmp[c]:=s; Inc(tmp1[c]); Inc(c); end;
          end;
         s:=0;
         for k:=0 to c-1 do
          if (tmp1[k]>s) then
                begin
                 s:=tmp1[k];
                 m:=tmp[k];
                end;
         OutD[j]:=m;
         i:=i+zn;
         Inc(j);
       end;
    end  else
   if (FLAG=FZ_NRSA) then
    begin
      if (n_z<0) then
      begin
       while (j<n2) do
       begin
        s:=0; i:=j*zn;
        for k:=0 to zn-1 do
         s:=s+inD[i+k];
        t3:=round(s/zn);
        m:=0;
        for k:=0 to zn-1 do
         if ( abs(t3-InD[i+k])<abs(t3-InD[i+m]) ) then  m:=k;
        OutD[j]:=InD[i+m];
        Inc(j);
       end;
      end else
      while (j<n2) do
       begin
        s:=0; i:=j*zn;
        for k:=0 to zn-1 do
         s:=s+inD[i+k];
        outD[j]:=round(s/zn);
        Inc(j);
       end;
    end else
   if (FLAG=FZ_NRSE) then
    begin
     SetLength(tmp,zn);
     if (n_z=0) then
      while (j<n2) do
       begin
        for k:=0 to zn-1 do
         tmp[k]:=InD[i+k];
        for k:=0 to zn-1 do
         begin
         s:=1;
         for m:=1 to zn-k-1 do
          if (tmp[m-1]>tmp[m]) then
           begin t3:=tmp[m-1]; tmp[m-1]:=tmp[m]; tmp[m]:=t3; s:=0;end;
         if (s>0) then break;
         end;
        outD[j]:=tmp[zn div 2];
        inc(i,zn);
        inc(j);
       end;
    end else
   if (FLAG=FZ_EMPT) then
    begin
     while (j<n2) do
      begin
        outD[j]:=inD[i];
        i:=i+zn+inc_inx;
        Inc(j);
      end
    end else
   if (FLAG=FZ_EDNZ) then
    begin
     i:=inc_inx;
     while (i<n1) do
      begin
        outD[j]:=inD[i];
        i:=i+zn;
        Inc(j);
      end;
     if (j=(n2-1)) then
       outD[j]:=inD[n1-1];
    end;
  end;
 result:=n2;
end;


Добавлено через 6 минут и 38 секунд
Считаю что 250 конечно многовато но если надо ...
насчет "нормальная практика" открой исходники делфы и посмотри - В основном методы менее 100 строк но есть и приличненькие. А вообщето главное в методе чтобы он 1) Выполнял свою задачу и ТОЛЬКО! 2) Делала это как можно более оптимально 3) Код  был симпатичным хотябы (не буду говорить о красоте)

Добавлено через 9 минут и 43 секунды
у можно в двух словах задачу TfmDeleteRecords.sbDeleteRecordsClick ?

Добавлено через 10 минут и 47 секунд
replace:
LastMsg[1]:='А'

smile
PM MAIL   Вверх
Alexeis
Дата 14.6.2007, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 1
Всего: 459



Цитата(4d5a @  14.6.2007,  11:29 Найти цитируемый пост)
Метод задумывался чтобы решить одну задачу, потом универсализовывался для решения нескольких схожих

  Для таких вещей принято создавать несколько методов для каждой из подзадач и вызывать их из этого метода.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
TXC
Дата 17.6.2007, 00:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 13
Регистрация: 6.5.2007

Репутация: нет
Всего: нет



4d5a

Цитата(4d5a @  14.6.2007,  11:29 Найти цитируемый пост)
у можно в двух словах задачу TfmDeleteRecords.sbDeleteRecordsClick ?

Удаляет запись по определенным характеристикам определенных полей.
PM MAIL WWW   Вверх
4d5a
Дата 18.6.2007, 05:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 10.6.2007

Репутация: нет
Всего: 1



Alexeis, в некоторых случаях не так все просто smile как может показаться
PM MAIL   Вверх
Earnest
Дата 18.6.2007, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: нет
Всего: 183



Цитата(4d5a @  18.6.2007,  06:04 Найти цитируемый пост)
Alexeis, в некоторых случаях не так все просто  как может показаться 

Практика показывает, что путем некоторого напряжения мозгов метод всегда можно сократить до приемлимой величины. МакКоннел, на которого уже ссылались, предлагает свою метрику для оценки приемлимости длины метода. И это не число строк кода, а число неких точек принятия решения. Которых в идеале не должно быть больше 10 или, в крайнем случае, 20.
Длинные методы может и легко писать, но сложно поддерживать: это главный аргумент против них.
Если функция, как ей и положено, выполняет ровно одну задачу, ее несложно разбить и сократить. А если она выполняет не одну задачу - нужно переделывать дизайн.


--------------------
...
PM   Вверх
mes
Дата 19.6.2007, 09:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: нет
Всего: 250



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

  
Код

{------------------------------------}
  { Якщо видаляємо записи користувачів }
  {------------------------------------}
  if fmDeleteRecords.cbChangeDB.Text='База користувачів' then ... {1 submethod}
  {---------------------------}
  { Якщо видаляємо записи тем }
  {---------------------------}
  if fmDeleteRecords.cbChangeDB.Text='База тем' then .. {2 submethod}
  {------------------------------}
  { Якщо видаляємо записи питань }
  {------------------------------}
  if fmDeleteRecords.cbChangeDB.Text='База питань' then  ...{3 submethod}
  
  ...



--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила раздела "Философия программирования":
Се ля ви

Форум "Философия программирования" предназначен для обсуждения вопросов, так или иначе связанных с философскими аспектами разработки ПО:

• вопросы перспективного развития методов написания ПО;

• изменяющиеся языки и методологии программирования;


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Се ля ви.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Философия программирования | Следующая тема »


 




[ Время генерации скрипта: 0.1373 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.