Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.01.15;
Скачать: CL | DM;

Вниз

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

 
Джо ©   (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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.04 c
3-1132305106
Anny
2005-11-18 12:11
2006.01.15
Прога считывания и обработки штрих кода...


14-1134921013
Nic
2005-12-18 18:50
2006.01.15
Какие ассоциации у Вас...


3-1132433132
Sword
2005-11-19 23:45
2006.01.15
Interbase не добавляет поле с пустой записью


3-1132100889
Silver...
2005-11-16 03:28
2006.01.15
TRIGGER ... Access


2-1135611497
kotbazilio
2005-12-26 18:38
2006.01.15
Удалить запись из таблицы