Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2006.01.15;
Скачать: [xml.tar.bz2];

Вниз

Хитроумный код - ваше отношение   Найти похожие ветки 

 
Джо ©   (2005-12-18 04:43) [0]

Вот, рылся в старых исходниках и нарыл нечто такое (даю выкристализованный каркас, общую идею):
 TSomeContainer = class
 public
   function Add (AValue: Integer): TSomeContainer;
   function Process: TSomeContainer;
 end;

implementation

function TSomeContainer.Add(AValue: Integer): TSomeContainer;
begin
 ///
 /// Storing value in internal list
 ///

 Result := Self
end;

function TSomeContainer.Process: TSomeContainer;
begin
 ///
 /// some usefull code
 ///

 Result := Self;
end;


Использовался, в том числе, так:
procedure TForm1.Button1Click(Sender: TObject);
begin
 with TSomeContainer.Create.
   Add(1).
   Add(2).
   Add(3).
   Add(100).
   Process do Free;
end;


Честно говоря, уже не помню, чем был вызван этот выпендреж :) То ли обрадовался тому, что можно сэкономить на операторных скобках, то ли просто именно "выпендрился".

Вопрос, собственно, значится в теме.


 
Джо ©   (2005-12-18 04:53) [1]

Сорри, в примере использования, например, так:


 TSomeContainer.Create.
   Add(1).
   Add(2).
   Add(3).
   Add(100).
   Process.Free;


 
Юрий Зотов ©   (2005-12-18 05:11) [2]

Выпендреж, конечно. Мало того, что код запутывает, так еще и небезопасно. Возникает в Add исключение - и привет, утечка памяти. Стандартный код прозрачнее и надежнее, да к тому же еще и машинный код немного короче (за счет замены функций процедурами).

with TSomeContainer.Create do
try
 Add(1);
 Add(2);
 Add(3);
 Add(100);
 Process
finally
 Free
end;


 
Джо ©   (2005-12-18 05:19) [3]

Да с данным случаем согласен, конечно, что ненужный выпендреж.
Вообще, хотелось бы с народом обсудить (с практической точки зрения и, желательно, с примерами из собственной практики) случаи, когда (по тем или иным причинам) приходилось писать "хитроумный" код.
Сразу скажу, что в последнее время стараюсь преследовать любые проявления этакой хитроумности. Но вот ведь - иногда тянет :)


 
Юрий Зотов ©   (2005-12-18 05:46) [4]

> Джо ©   (18.12.05 05:19) [3]

> с примерами из собственной практики) случаи, когда (по тем или иным
> причинам) приходилось писать "хитроумный" код.

Раньше бывало. Обычно тогда, когда, пытаясь сэкономить объем исходника, вводишь в код функции несвойственные ей по смыслу действия. Вместо того, чтобы разделить все действия на логически цельные куски и для каждого написать свою функцию. Например - одна функция выполняет расчет, вторая отображает его на экране - но не все в куче.

Потом, вдоволь навозившись с отладкой, понял, что структурное программирование (и, тем более, ООП) вовсе не дураки придумали и вовсе не от нечего делать. Сейчас такого уже не допускаю, даже уже автопилот на этот счет срабатывает.


 
Lamer@fools.ua ©   (2005-12-18 11:01) [5]

>>Джо ©   (18.12.05 04:53) [1]

Это, кстати, не совсем выпендрёж. Иногда такое полезно. Пример: многие методы класса StringBuilder (.NET) возвращают сам экземпляр.

И вообще, если уж мудрить, то тогда писать так:

TSomeContainer.Create.Add(1).Add(2).Add(3).Add(100).Process.Free;

А если грамотно мудрить, то так:
with TSomeContainer.Create do
 try
   Add(1).Add(2).Add(3).Add(100).Process;
 finally
   Free;
 end;


А если уж совсем грамотно и не мудрить, то добавить/изменить такой метод Add:
procedure TSomeContainer.Add(const AValue: array of Integer);
И писать потом как-то так:
with TSomeContainer.Create do
 try
   Add([1, 2, 3, 100]);
   Process;
 finally
   Free;
 end;


 
Lamer@fools.ua ©   (2005-12-18 11:02) [6]

И вообще, если уж мудрить, то тогда писать так:

TSomeContainer.Create.Add(1).Add(2).Add(3).Add(100).Process.Free;


Ой, точнее так:
with TSomeContainer.Create do
 Add(1).Add(2).Add(3).Add(100).Process.Free;


 
Карелин Артем ©   (2005-12-18 11:13) [7]

А как вы относитесь к такому коду:
//есть published свойства класса, идея забить на их имена, типы и грузить/сохранять их из произвольных источников
procedure TMyClass.GetFromForm(Form: TForm);
var
 PropList: pPropList;
 J, I: Integer;
begin
 J := GetPropList(Self, PropList);
 for I := 0 to J - 1 do
  begin
   try
    SetPropValue(Self,PropList^[I]^.Name,(Form.FindComponent("ed"+PropList^[I]^.Name) as TEdit).Text);
   except
   end;
  end;
 FreeMem(PropList, sizeof(tPropList));
end;

function TMyClass.GetPropNames: string;
var
 PropList: pPropList;
 J, I: Integer;
begin
 J := GetPropList(Self, PropList);
 for I := 0 to J - 1 do
  begin
   if PropList^[I]^.PropType^.Kind<>tkMethod then
   Result:=Result+(PropList^[I]^.Name)+#13#10;
  end;
 FreeMem(PropList, sizeof(tPropList));
end;

procedure TMyClass.LoadFromDataset(DataSet: TDataSet);
var
 PropList: pPropList;
 J, I: Integer;
 s:string;
begin
 J := GetPropList(Self, PropList);
 for I := 0 to J - 1 do
  begin
   try
    s:=PropList^[I]^.Name;
    if Assigned(DataSet.FieldByName(s)) then
     SetPropValue(Self,s,DataSet.FieldByName(s).AsString);
   except
   end;
  end;
 FreeMem(PropList, sizeof(tPropList));
end;

procedure TMyClass.SaveToStoredProc(StoredProc: TADOStoredProc);
var
 PropList: pPropList;
 J, I: Integer;
 Params:TParameters;
 Param:TParameter;
 s:string;
begin
StoredProc.Parameters.Refresh;
Params:=StoredProc.Parameters;
J := GetPropList(Self, PropList);
for I := 0 to J - 1 do
 begin
  try
   s:=PropList^[I]^.Name;
   Param:=Params.FindParam(s);
   if Param<>nil then
    if (Param.Direction=pdInput) or (Param.Direction=pdInputOutput) then
     Param.Value:=GetPropValue(Self,PropList^[I]^.Name);
  except
  end;
 end;
try
 StoredProc.Connection.BeginTrans;
 StoredProc.ExecProc;
 StoredProc.Connection.CommitTrans;
except
 StoredProc.Connection.RollbackTrans;
end;
FreeMem(PropList, sizeof(tPropList));
end;

procedure TMyClass.ShowOnForm(Form:TForm);
var
 PropList: pPropList;
 J, I: Integer;
begin
 J := GetPropList(Self, PropList);
 for I := 0 to J - 1 do
  begin
   try
     (Form.FindComponent("ed"+PropList^[I]^.Name) as TEdit).Text:=GetPropValue(Self,PropList^[I]^.Name);
   except
   end;
  end;
 FreeMem(PropList, sizeof(tPropList));
end;

procedure TMyClass.UpdateDataset(DataSet: TDataSet);
var
 PropList: pPropList;
 J, I: Integer;
begin
 DataSet.Edit;
 J := GetPropList(Self, PropList);
 for I := 0 to J - 1 do
  begin
   try
    if Assigned(DataSet.FieldByName(PropList^[I]^.Name)) then
     DataSet.FieldByName(PropList^[I]^.Name).AsString:=GetPropValue(Self,PropList^[I]^.Name);
   except
   end;
  end;
 FreeMem(PropList, sizeof(tPropList));
 DataSet.Post;
end;


 
Суслик ©   (2005-12-18 11:25) [8]

я так думаю - не вороши прошлое - работает и ок. Если код самому не нравится, то не делай таких ошибок в будущем, в новых проектах.

я бы так делать не стал.

Если по сабжу, то запутанность кода иногда имеет смысл.
Пример. Я не силен в асме. Поэтому если есть требовательные ко времени выполнения задачи, то приходится изголяться, тем самым, есно, запутывая код. Другой вопрос, что данные места имхо в обязательном порядке должны сопровождаться подробным комментарием с разъяснением: а) причин запутанности, б) последствий запутанности (например, сравнительные характеристики времени выполнения до и после) и в) методов модификации
кода.

Рассмотрим а, б и в подробнее.

а: Здесь надо указать те метивы, которые привели к такому коду. Пример. Если пишешь объектную модель, в которой есть 3 класса (допустим) и по 100000 объектов каждого класса, то иногда выгоднее разработать свой манагер памяти. Иногда очень выгодно. Надо обязательно написать, что "штатный манагер памяти универсален и хорош, но в данному случае справляется не очень хорошо, имено из-за большого количества объектов".

Данная часть комментария поможет вспомить, зачем вообще нужно такое неочевидное решение.

б: Если продолжить пример и п. а, то тут нужно написать следующее: "уничтожение объектной модели со штатным манагером занимало 1.2 сек, с новым 0.1". Даннй кусок поможет в будущем меньше думать над вопросом - а может ну его на фиг, вернуть все в рамки стандартного подхода. При таких мыслях ты можешь подумать, что экономия в 1.1 сек для тебя вообще говоря ничего особо не значит, а вот ухудшение читабельности кода несет потенциальные угрозы. Или наоборот - вау, я этим экономлю 1.1 сек, да, для меня в текущей ситуации это важно и возвращаться к стандарту я не буду.

в: Тут нужно описать тонкости. Рассмотрим опять же пример и п. а. Например в твоем случае может быть такое, что весь твой манагер памяти ориентирован на то, что в объектах нет полей с управляемым временем жизни (дл. строки, интерфейсы и пр.). Надо сказать, что если таковые появятся, то манагером пользоваться нельзя или нужно доделать тут и тут.


 
Lamer@fools.ua ©   (2005-12-18 11:47) [9]

>>Карелин Артем ©   (18.12.05 11:13) [7]

>А как вы относитесь к такому коду: [skipped]
Плохо. С ленью нужно бороться, и писать проверки вместо пустых except/end"ов.


 
Lamer@fools.ua ©   (2005-12-18 11:48) [10]

P.S. к [9].

К тому же except должен по возможности ловить только ожидаемые исключения, а не все подряд.



Страницы: 1 вся ветка

Форум: "Потрепаться";
Текущий архив: 2006.01.15;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.013 c
9-1122904615
Novouralsk
2005-08-01 17:56
2006.01.15
Псевдо анимация


14-1135158514
grisme
2005-12-21 12:48
2006.01.15
ШАХМАТЫ


2-1135628629
Danja
2005-12-26 23:23
2006.01.15
Pen.Color


14-1135003361
GRAND25
2005-12-19 17:42
2006.01.15
Эстонцы тоже хочуть газу!


6-1128509833
Profik
2005-10-05 14:57
2006.01.15
MailSlot





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский