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

Вниз

Освобождение ресурса в finally   Найти похожие ветки 

 
Arinyshka   (2008-04-23 12:17) [0]

Не подскажете еще один момент:
Есть процедура, выглядит примерно так

procedure TSetPayFrm.BtnAddImageClick(Sender: TObject);
var  TempBitmap:TBitmap;
begin
if not(opendialog1.Execute) then  exit;
try
 TempBitmap  := TBitmap.Create;
 TempBitmap.LoadFromFile(OpenDialog1.FileName);
finally
TempBitmap.Free;
end;
end;

На освобождение  TempBitmap.Free; выдает варнинг
[Warning] uSetPaymentMain.pas(313): Variable "TempBitmap" might not have been initialized
Не смертельно, но непонятно... почему варнинг? При изменениии условия и включении всей конструкции в один блок begin..end ситуация не менялась.


 
Рамиль ©   (2008-04-23 12:18) [1]

TempBitmap  := TBitmap.Create;
try
TempBitmap.LoadFromFile(OpenDialog1.FileName);
finally
TempBitmap.Free;
end;


 
Arinyshka   (2008-04-23 12:21) [2]

упс :) чувствую себя дура дурой :) Ну конечно! спасибо :)))))


 
Ega23 ©   (2008-04-23 12:21) [3]


> Не смертельно, но непонятно... почему варнинг?


Потому что если в конструкторе произойдёт исключение, то TempBitmap будет равен nil. А после ты попадаешь на finally, где вызываешь free.
Create нужно выносить за блок try..finally


 
{RASkov} ©   (2008-04-23 12:22) [4]

> но непонятно... почему варнинг?

Потому как создание объекта в защищенной секции, а уничтожение принудительное в финале.... поэтому компилятор и говорит, что объект может и не создасться и в финале будет АВ.
Решение в [1]... т.е. создание вынести из защитного блока...


 
{RASkov} ©   (2008-04-23 12:22) [5]

:)


 
{RASkov} ©   (2008-04-23 12:23) [6]

> Потому что если в конструкторе произойдёт исключение, то
> TempBitmap будет равен nil. А после ты попадаешь на finally,
> где вызываешь free.

Если в конструкторе будет ошибка то в секцию финал мы не попадем вовсе...


 
{RASkov} ©   (2008-04-23 12:24) [7]

> [6] {RASkov} ©   (23.04.08 12:23)

.... это если использовать код из [1]


 
Palladin ©   (2008-04-23 12:25) [8]


> Ega23 ©   (23.04.08 12:21) [3]
> то TempBitmap будет равен nil. А после ты попадаешь на finally,
>  где вызываешь free.


ха... если бы он был равен Nil.. он не равен Nil, Nil для Free несмертелен, TempBitmap будет неинициализирован то бишь мусор, а вот это для Free уже критично


 
Ega23 ©   (2008-04-23 12:30) [9]


> Если в конструкторе будет ошибка то в секцию финал мы не
> попадем вовсе...
>


Да ну????


unit Unit2;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

type

 TMyObj = class
 public
   constructor Create(const RaiseException : Boolean = False);
   procedure DoWork;
 end;

 TForm2 = class(TForm)
   Button1: TButton;
   Label1: TLabel;
   Button2: TButton;
   procedure Button1Click(Sender: TObject);
   procedure Button2Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form2: TForm2;

implementation

{$R *.dfm}

{ TMyObj }

constructor TMyObj.Create(const RaiseException: Boolean);
begin
 if RaiseException then
   raise Exception.Create("TMyObj.Create");
end;

procedure TMyObj.DoWork;
begin
 ShowMessage("TMyObj.DoWork");
end;

procedure TForm2.Button1Click(Sender: TObject);
var
 obj : TMyObj;
begin
 Label1.Caption := "";
 obj := TMyObj.Create(True);
 try
   obj.DoWork;
 finally
   Label1.Caption := "попали в finally";
   obj.Free;
 end;
end;

procedure TForm2.Button2Click(Sender: TObject);
var
 obj : TMyObj;
begin
 Label1.Caption := "";

 try
   obj := TMyObj.Create(True);
   obj.DoWork;
 finally
   Label1.Caption := "попали в finally";
   obj.Free;
 end;

end;

end.


 
Ega23 ©   (2008-04-23 12:32) [10]


> ха... если бы он был равен Nil.. он не равен Nil, Nil для
> Free несмертелен, TempBitmap будет неинициализирован то
> бишь мусор, а вот это для Free уже критично
>


Согласен, неточно выразился.


 
Рамиль ©   (2008-04-23 12:34) [11]


> Ega23 ©   (23.04.08 12:32) [10]

Сам попался? :)


 
Anatoly Podgoretsky ©   (2008-04-23 12:36) [12]

> Arinyshka  (23.04.2008 12:17:00)  [0]

Правильно говорит, код из Вредных Заветов

Создание должно быть до try


 
Ega23 ©   (2008-04-23 12:36) [13]


> Сам попался? :)


С некоторых пор, если есть вероятность того, что в конструкторе raise встретится, предпочитаю сначала nil приравнять...  :)


 
Anatoly Podgoretsky ©   (2008-04-23 12:38) [14]


> Потому что если в конструкторе произойдёт исключение, то
> TempBitmap будет равен nil.

Это ты погорячился, переменная то локальная, а субъект не является субъектом с регулируемым сроком жизни.


 
{RASkov} ©   (2008-04-23 12:42) [15]

> [9] Ega23 ©   (23.04.08 12:30)

А вот такой вариант:
function CrBut: TButton;
begin
 Result:=TButton.Create(nil);
 Result.Tag:=Random(15);
 Result.Caption:=IntToStr(Result.Tag);
 if Result.Tag<7 then begin
  raise Exception.Create("Error in constructor");
  Result.Free;
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var B: TButton;
begin
 Randomize;
 B:=CrBut;
 try
  B.Parent:=Self;
  B.Caption:=B.Caption+" Ok";
  ShowMessage("B Ok");
 finally
  B.Free;
  ShowMessage("Finally");
 end;
end;


 
ANB   (2008-04-23 12:44) [16]


> TempBitmap  := TBitmap.Create;
> try
> TempBitmap.LoadFromFile(OpenDialog1.FileName);
> finally
> TempBitmap.Free;
> end;

TempBitmap  := nil;
try
 TempBitmap  := TBitmap.Create;
 TempBitmap.LoadFromFile(OpenDialog1.FileName);
finally
 TempBitmap.Free;
end;

Это классика. Позволяет избежать дублирования финалли, если объектов много, при этом все корректно отработает.


 
{RASkov} ©   (2008-04-23 12:47) [17]

> [9] Ega23 ©   (23.04.08 12:30)
> Button2Click

В этом случае мы попадаем в финал так как коструктор тоже в защитном блоке...


 
Leonid Troyanovsky ©   (2008-04-23 13:12) [18]


> ANB   (23.04.08 12:44) [16]

> Это классика.

Это заблуждение.

Исключения конструктора следует передавать обработчику
следующего уровня.
А защищать ресурсы в этом случае не нужно - деструктор
вызовется автоматом.

--
Regards, LVT.


 
{RASkov} ©   (2008-04-23 13:15) [19]

> [16] ANB   (23.04.08 12:44)
> TempBitmap  := nil;
> try
> TempBitmap  := TBitmap.Create;
> TempBitmap.LoadFromFile(OpenDialog1.FileName);
> finally
> TempBitmap.Free;
> end;
>
> Это классика.

А по мне, мне кажется [1] более роднее и вернее.... [16] и выглядит как-то подозрительно...
А если после возникновения ошибки в конструкторе, он(конструктор) вернет не рыбу не мясо... т.е. не nil и не объект...
Я правда трудно себе это представляю, но.... в финале АВ :)


 
Плохиш ©   (2008-04-23 13:19) [20]


> А если после возникновения ошибки в конструкторе, он(конструктор)
> вернет не рыбу не мясо... т.е. не nil и не объект...

При возникновении исключения в конструкторе, операция присваивания не будет выполнена.


 
{RASkov} ©   (2008-04-23 13:20) [21]

> [20] Плохиш ©   (23.04.08 13:19)
> При возникновении исключения в конструкторе, операция присваивания
> не будет выполнена.

:)
Ну да... тоже верно... Но все равно [1] мне кажется вернее...


 
ANB   (2008-04-23 13:40) [22]

http://softwarer.ru/memory.html

Читать сомневающимся до полного просветления.
Пользуюсь этим способом практически везде, даже если нужен только один объект, т.к. заранее не знаешь, обойдешься одним или нет. И ни разу не ловил из-за этого АВ.


 
Palladin ©   (2008-04-23 13:53) [23]

Автор Александр Просторов, всемирно известный классик кодирования. всем пасть ниц

Тема многократного использования идентификатора объекта не раскрыта


 
Arinyshka   (2008-04-23 15:09) [24]

Уффф... ну и дискуссия :)
А вот я еще один объект завожу... освобождаю по form.Close.

unit u;
interface

type
 TSetPayFrm = class(TMGSprForm)
 
var
SetPayFrm  : TSetPayFrm;
ListImage:TStringList;

implementation

procedure TSetPayFrm.InitImageList;
var MyStream: TStream; TempBitmap:TBitmap;
begin

try
ListImage:=TStringList.Create;

except
ListImage.Free;

end;

procedure TSetPayFrm.TbCloseClick(Sender: TObject);
begin
Close;
end;

procedure TSetPayFrm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ListImage.Free;
Action := caFree;
end;

end.

Проблема в том, что он мне нужен и в других юнитах, на протяжении работы приложения. Поэтому в процедурке, создающей его, finaly меня не устраивает.
Но в случае except у меня 2 освобождения... Где я неправа?


 
Рамиль ©   (2008-04-23 15:15) [25]

Не надо загонять в try создание объекта. Если возникла ошибка при его создании, то вызывать деструктор лишено какого либо смысла.


 
Palladin ©   (2008-04-23 15:18) [26]

ListImage:=TStringList.Create; идет на верх над try
в finally пишем FreeAndNil(ListImage) ну или
ListImage.Free;
ListImage:=Nil;

в объявлении Var пишем
ListImage:TStringList=Nil;


 
Восхищенный   (2008-04-23 15:26) [27]

Какая интересная дискуссия. И что интересно - ни одного повтора.


 
Arinyshka   (2008-04-23 15:48) [28]


> ListImage:=TStringList.Create; идет на верх над try
> в finally пишем FreeAndNil(ListImage) ну или
> ListImage.Free;
> ListImage:=Nil;

Подождите... разве я не потеряю значения nil? Я инициализировала и освободила?


 
Arinyshka   (2008-04-23 15:50) [29]

ой, имела в виду список свой.


 
Andy BitOff ©   (2008-04-23 16:09) [30]

В Init в except FreeAndNil(ListImage), а ListImage:=TStringList.Create вынести над try. Далее по коду, если надо обратиться к ListImage делаешь проверку не Nil ли он.


 
ANB   (2008-04-23 16:31) [31]


> Palladin ©   (23.04.08 13:53) [23]
> Автор Александр Просторов, всемирно известный классик кодирования.
>  всем пасть ниц
>
> Тема многократного использования идентификатора объекта
> не раскрыта

На SQL.ru сходи - познакомся.


 
Anatoly Podgoretsky ©   (2008-04-23 16:32) [32]

> Arinyshka  (23.04.2008 15:09:24)  [24]

> Проблема в том, что он мне нужен и в других юнитах, на протяжении работы приложения

В таком случае никаких переменных, переместить в класс, а доступ через контролируемое свойство Gettet/Setter и даже создавать извне не надо, Gettet/Setter с этим сами справятся. Никаких проблем с достоверность указателя не будет, всегда истинное.


 
Loginov Dmitry ©   (2008-04-23 22:43) [33]

http://matrix.kladovka.net.ru/index.php?page=tryfinally


 
Игорь Шевченко ©   (2008-04-23 23:02) [34]

ANB   (23.04.08 13:40) [22]


> Читать сомневающимся до полного просветления.


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


 
Игорь Шевченко ©   (2008-04-23 23:04) [35]

ANB   (23.04.08 16:31) [31]

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


 
ANB   (2008-04-24 10:31) [36]

Игорь Шевченко ©   (23.04.08 23:04) [35]

В случае с одним объектом, конечно, доп.строки являются лишними.
Это я по привычке пишу, чтобы потом не переделывать, если в процедуре понядобятся еще объекты.
Однако рассмотрим код :

Obj1  := nil;
Obj2  := nil;
Obj3  := nil;
Obj4  := nil;
Obj5  := nil;
try
 Obj1  := TObj.Create;
 Obj2  := TObj.Create;
 Obj3  := TObj.Create;
 Obj4  := TObj.Create;
 Obj5  := TObj.Create;
 ...
 работа с объектами и куча другого кода
finally
 FreeAndNil(Obj1);
 FreeAndNil(Obj2);
 FreeAndNil(Obj3);
 FreeAndNil(Obj4);
 FreeAndNil(Obj5);
end;

Как без начального зануливания переменных под объекты это написать и корректно и читабельно ?

ЗЫ. Большуюя часть тактов процессора нынче съедают не наши приложения а рисование рюшечек операционки. Да и рюшечек наших приложений частенько тоже.


 
Ega23 ©   (2008-04-24 10:35) [37]


> ANB   (24.04.08 10:31) [36]


Зачем создание внутрь try тащить???


 
ЮЮ ©   (2008-04-24 10:51) [38]

> Зачем создание внутрь try тащить???

Затем, что ошибка может настичь и на Obj5  := TObj.Create; где же тогда освобождать Obj1 &#133 Obj5

P/s/ Нафига только такими объектами пользоваться, которые ломаются уже в конструкторе. :)
В реальной жизни так печься только о TFileStream-e приходилось


 
Ega23 ©   (2008-04-24 10:58) [39]


> Затем, что ошибка может настичь и на Obj5  := TObj.Create;
>  где же тогда освобождать Obj1 … Obj5


А в таком случае надо по-хорошему так:

Obj1 := TObj.Create;
try
 Obj2 := TObj.Create;
 try
   Obj3 := TObj.Create;
   try
      .......
   finally
     Obj3.Free;
   end;
 finally
   Obj2.Free;
 end;
finally
 Obj1.Free;
end;


 
{RASkov} ©   (2008-04-24 10:59) [40]

> [36] ANB   (24.04.08 10:31)
> это написать и корректно и читабельно ?

Obj1  := TObj.Create;
 try
  Obj2  := TObj.Create;
  try
  Obj3  := TObj.Create;
   try
   Obj4  := TObj.Create;
    try
     Obj5  := TObj.Create;
     try
...
работа с объектами и куча другого кода
     finally
      FreeAndNil(Obj5);
     end;
    finally
     FreeAndNil(Obj4);
    end;
   finally
    FreeAndNil(Obj3);
   end;
  finally
   FreeAndNil(Obj2);
  end;
 finally
  FreeAndNil(Obj1);
 end;

или при уверенности, что в конструкторе не будет ошибок, то:
Obj1  := TObj.Create;
Obj2  := TObj.Create;
Obj3  := TObj.Create;
Obj4  := TObj.Create;
Obj5  := TObj.Create;
try
...
работа с объектами и куча другого кода
finally
FreeAndNil(Obj1);
FreeAndNil(Obj2);
FreeAndNil(Obj3);
FreeAndNil(Obj4);
FreeAndNil(Obj5);
end;
Но если честно, то у меня такого в коде никогда еще не встречалось :)


 
ZENsan ©   (2008-04-24 11:16) [41]

Удалено модератором


 
Arinyshka   (2008-04-24 11:28) [42]

А мне велено почитать про секцию  finalization. Может, так действительно проще?
инициализировать и освободить в соотв секциях...
Из советов мне понятен вариант с проверкой:
f Assigned(Obj1) then
  Obj1.Free;
i
тогда я никого не попытаюсь освободить дважды


 
ZENsan ©   (2008-04-24 11:31) [43]

Да делай именно так Аринишка - стандартный подход. Можно конечно и в секциях - так лучше если ты используеш этот код очень часто (не будешь каждый раз создавать и удалять объект..)


 
{RASkov} ©   (2008-04-24 11:33) [44]

> [42] Arinyshka   (24.04.08 11:28)
> f Assigned(Obj1) then
>  Obj1.Free;i
> тогда я никого не попытаюсь освободить дважды

Не факт. Смотри:
Obj1:=TObj.Create;
f Assigned(Obj1) then Obj1.Free;
f Assigned(Obj1) then Obj1.Free;

И тут АВ на второй строке.
Правильно так:
Obj1:=TObj.Create;
f Assigned(Obj1) then begin Obj1.Free; Obj1:=nil; end;
f Assigned(Obj1) then begin Obj1.Free; Obj1:=nil; end; //не будет АВ
ну или Freeandnil()...


 
ZENsan ©   (2008-04-24 11:34) [45]

Ну ето понятноъъъ Но мы же вроде про один блок Try Finally...

Там тогда просто надо:

If Assigned(Obj1) then
 FreaAndNil(Obj1);


 
{RASkov} ©   (2008-04-24 11:39) [46]

> [45] ZENsan ©   (24.04.08 11:34)

А смысл? не вижу...(
Но если еще и коструктор(ы) в защитный блок затащить, так еще и хинтов/варнингов от компилятора "слушать"...) Зачем?
И еще.... и даже с одним блоком финали мы не лишены возможности два раза освободить объект :)


 
ZENsan ©   (2008-04-24 11:43) [47]

Там обйектам нил присваивался перед блоком Трай.. Какие варнинги..
А если мы конструкторы в незащищённый блок поставим... то смотри:


Obj1 := TObj1.Create();{сработал, память выделилась}
Obj2 := TObj2.Create();{исключение}
try
 ...
finally
 ...
end;


Memory leak..


 
{RASkov} ©   (2008-04-24 11:48) [48]

> [47] ZENsan ©   (24.04.08 11:43)
> Там обйектам нил присваивался перед блоком Трай.. Какие варнинги..

Такой код появляется скорее из-за лени программиста нежели из-за профессианализма)
И для других может выглядеть запутанно :(


 
ANB   (2008-04-24 11:51) [49]


> Ega23 ©   (24.04.08 10:58) [39]
>
> > Затем, что ошибка может настичь и на Obj5  := TObj.Create;
>
> >  где же тогда освобождать Obj1 … Obj5
>
>
> А в таком случае надо по-хорошему так:
>
> Obj1 := TObj.Create;
> try
>  Obj2 := TObj.Create;
>  try
>    Obj3 := TObj.Create;
>    try
>       .......
>    finally
>      Obj3.Free;
>    end;
>  finally
>    Obj2.Free;
>  end;
> finally
>  Obj1.Free;
> end;
> <Цитата>

Извращение и плохо читаемо.


 
ZENsan ©   (2008-04-24 11:51) [50]

Не факт. Смотри:
Obj1:=TObj.Create;
if Assigned(Obj1) then Obj1.Free;
if Assigned(Obj1) then Obj1.Free;

Ну а такой код-то от чего появился вдруг?

if Assigned(Obj1) then Obj1.Free;
if Assigned(Obj1) then Obj1.Free;

Конечно тут ошибка будет


 
ZENsan ©   (2008-04-24 11:52) [51]

Полностйу соглаес с АНБ


 
ANB   (2008-04-24 11:52) [52]


>
> {RASkov} ©   (24.04.08 11:39) [46]
> > [45] ZENsan ©   (24.04.08 11:34)
>
> А смысл? не вижу...(
> Но если еще и коструктор(ы) в защитный блок затащить, так
> еще и хинтов/варнингов от компилятора "слушать"...) Зачем?
>
> И еще.... и даже с одним блоком финали мы не лишены возможности
> два раза освободить объект :)

Ни хинтов не варнингов при таком способе нету.


 
ANB   (2008-04-24 11:53) [53]


> Arinyshka   (24.04.08 11:28) [42]
> А мне велено почитать про секцию  finalization. Может, так
> действительно проще?
> инициализировать и освободить в соотв секциях...
> Из советов мне понятен вариант с проверкой:
> if Assigned(Obj1) then>   Obj1.Free;i
> тогда я никого не попытаюсь освободить дважды


Выделенное - совершенно лишний код. Фрее и так внутри проверяет, что ссылка на объект не равна NIL.


 
ZENsan ©   (2008-04-24 11:55) [54]

Мой способ вообще был нормальный:

Obj1 := nil;
Obj2 := nil;
try
 Obj1 := TObj1.Create;
 Obj2 := TObj2.Create;
 ...
finally
 if Assigned(Obj1) then
   FreeAndNil(Obj1);
 if Assigned(Obj2) then
   FreeAndNil(Obj2);
end;


 
ЮЮ ©   (2008-04-24 11:55) [55]

> Ну а такой код-то от чего появился вдруг?

Он появился от того, что появилась проверка if Assigned(Obj1) которая абсолютно ничего не дает.
Что с не, что без неё Obj1.Free сработает абсолютно одинаково.


 
ZENsan ©   (2008-04-24 11:56) [56]

Если исключение будет в сосздании второго объекта...????

Тогда ваша прого просто улетит...


 
ZENsan ©   (2008-04-24 11:57) [57]

"Не факт. Смотри:
Obj1:=TObj.Create;
if Assigned(Obj1) then Obj1.Free;
if Assigned(Obj1) then Obj1.Free;" - ето не мой код...


 
ANB   (2008-04-24 11:58) [58]


> ZENsan ©   (24.04.08 11:55) [54]
> Мой способ вообще был нормальный:
>
> Obj1 := nil;
> Obj2 := nil;
> try
>  Obj1 := TObj1.Create;
>  Obj2 := TObj2.Create;
>  ...
> finally
>  if Assigned(Obj1) then
>    FreeAndNil(Obj1);
>  if Assigned(Obj2) then
>    FreeAndNil(Obj2);
> end;

А я не тебе и писал :).
Тем более твой код - почти такой же как и мой. Кистате, я года 3 назад так же писал, пока Саша Просторов не предложил мне взглянуть на реализацию Фрии :).


 
ZENsan ©   (2008-04-24 11:59) [59]

А я не тебе ;)


 
ZENsan ©   (2008-04-24 12:01) [60]

Ну ка ну ка чё там за фишка про Фрии..
Если вызывать Obj1.Free, когда Obj1 = nil или неинициализирован (локальная переменная в процедуре функции) - то будет исключение 100%...


 
{RASkov} ©   (2008-04-24 12:03) [61]

> [60] ZENsan ©   (24.04.08 12:01)

Проверь:
var B: TObject;
begin
 B:=nil;
 B.Free;
end;


нет никаких АВ :)


 
{RASkov} ©   (2008-04-24 12:09) [62]

> [60] ZENsan ©   (24.04.08 12:01)
> nil или неинициализирован

Дело в том, что это разные вещи и приравнивание переменной Obj1 к nil - тажа самая инициализация по сути.


 
ZENsan ©   (2008-04-24 12:10) [63]

Согласен... Фрии - class procedure.
Но нил я присваиваю именно птоому что объекты когда они локальные в процедурах и функциях могут иметь рандом значения из стека. Поэтому без Obj1 := nil; лучше не жить...

А про фрии, никогда не знал - не полагался никогда на это. предпочитаю 7 раз отмерить - один раз отрезать.


 
ZENsan ©   (2008-04-24 12:11) [64]

Параметры функций/процедур не инициализируются автоматически в Делфи


 
Плохиш ©   (2008-04-24 12:18) [65]


> ZENsan ©   (24.04.08 12:11) [64]
> Параметры функций/процедур не инициализируются автоматически
> в Делфи

Чем дальше в лес, тем толще партизаны...

PS. "Параметры функций/процедур" обычно передаются в эти функции/процедуры, если конечно для них не заданы значения по умолчанию.

PPS. А основы используемого языка программирования всё-таки почитай.


 
ZENsan ©   (2008-04-24 12:19) [66]

Спасибо за справочку {RASkov}, тоесть теперй код такой должен быть:


Obj1 := nil;
Obj2 := nil;
try
Obj1 := TObj1.Create;
Obj2 := TObj2.Create;
...
finally
 FreeAndNil(Obj1);
 FreeAndNil(Obj2);
end;


Ну ваще красота... но я всё же ставлю проверку (ну моразматик я, да :) )..


 
{RASkov} ©   (2008-04-24 12:20) [67]

> [63] ZENsan ©   (24.04.08 12:10)
> Согласен... Фрии - class procedure.

Во первых это статический приватный метод, не классовый.)
Во вторых
> предпочитаю 7 раз отмерить - один раз отрезать.

Тоже не есть верно. Зачем лишние расходы? Можно же еще и так делать и тоже будет верно:
if not Assigned(Ojb) and Obj=nil and (Not assigned(Obj) and Obj=nil) then Obj.Free;
:)


 
ZENsan ©   (2008-04-24 12:21) [68]

const
 Obj: Tobj = nil;

ми про ето не говорим...

Поумничать - это хорошо конечно..


 
ZENsan ©   (2008-04-24 12:22) [69]

{RASkov} - :) это ты круто :)


 
ZENsan ©   (2008-04-24 12:23) [70]

"Во первых это статический приватный метод, не классовый.)" - в делфи это "class procedure/function". (wait)


 
ЮЮ ©   (2008-04-24 12:26) [71]

> [66] ZENsan ©   (24.04.08 12:19)

> finally
> FreeAndNil(Obj1);
> FreeAndNil(Obj2);
> end;


если Obj1 и Obj2 локальные, то нет смфсла в их обNilениее в finally, если &laquo;глобальные&raquo;, т.е. поля объекта, то нет смысла в обNilениее до try.


 
ZENsan ©   (2008-04-24 12:26) [72]

Constructor i Destructor - единственные класс методы до реализации класс методов в делфи начиная по моему с 2005-ого..


 
ZENsan ©   (2008-04-24 12:27) [73]

Если поля обйекта то конечно. Я именно про случай если это локальные переменные не константы..


 
ANB   (2008-04-24 12:30) [74]


>  то нет смфсла в их обNilениее в finally

Вобчем то да. Но могут быть разные глюки потом. Ну его нафиг - мне что жалко один раз выполнить короткое присваивание ? Тем более оно в функции живет.


 
ЮЮ ©   (2008-04-24 12:32) [75]

> Я именно про случай если это локальные переменные не константы&#133


зачем тогда
finally
FreeAndNil(Obj1);
FreeAndNil(Obj2);
end;


так разве менее красиво
finally
Obj1.Free;
Obj2.Free;
end;

P.S. учитывая, что Obj2 := TObj2.Create; часто вызывает исключение, очень вероятно, что при удачном создании обоих объектов упадет с исключением Obj1.Free; и Obj2 останется неосвобожденным :)


 
ЮЮ ©   (2008-04-24 12:36) [76]

> [74] ANB   (24.04.08 12:30)

> Вобчем то да. Но могут быть разные глюки потом


Глюки после смерти? Если они есть, значит проблемы в другом месте кода и это счастье, что тебе удалось уловить их хотя бы опосредованно.


 
Восхищенный   (2008-04-24 12:40) [77]

> ZENsan ©   (24.04.08 12:26) [72]

> Constructor i Destructor - единственные класс методы до реализации класс
> методов в делфи начиная по моему с 2005-ого..

1. Конструктор и деструктор - вообще не классовые методы.

2. Классовые методы реализованы во всех версиях Delphi, начиная аж с 1.

3. В [65] Плохиш дал очень хороший совет. Конечно, можно и дальше переливать здесь из пустого в порожнее, но лучше все же последовать этому совету.


 
{RASkov} ©   (2008-04-24 12:42) [78]

> [70] ZENsan ©   (24.04.08 12:23)

 TObject = class
   constructor Create;
   procedure Free;
   class function InitInstance(Instance: Pointer): TObject;
   procedure CleanupInstance;
   function ClassType: TClass;
   class function ClassName: ShortString;
   class function ClassNameIs(const Name: string): Boolean;
......


Я конечно загнул с приватным :) но не классовый он....


 
Kolan ©   (2008-04-24 12:46) [79]

> но не классовый он&#133

Имхо, слово constructor подразумевает class function, так что, имхо, классовый.


 
{RASkov} ©   (2008-04-24 12:50) [80]

> [79] Kolan ©   (24.04.08 12:46)
> так что, имхо, классовый.

Коструктор, да. Его нужно применять к классу, иначе(если к объекту: Obj.Create;) это не конструктор а вызов метода Create без распределения памяти....

Но я зря его(конструктор) подчеркнул, так как разговор был о Free)


 
Восхищенный   (2008-04-24 12:50) [81]

> Kolan ©   (24.04.08 12:46) [79]

Проверь, что такое Self внутри конструктора - и имхо твое изменится, и имхом быть перестанет.


 
Восхищенный   (2008-04-24 12:57) [82]

> {RASkov} ©   (24.04.08 12:50) [80]

> Его нужно применять к классу, иначе(если к объекту: Obj.Create;) это не
> конструктор а вызов метода Create без распределения памяти....

Ты, возможно, удивишься, но метод Create не выделяет память даже если он был вызван и через ссылку на класс. Память выделяется другим кодом, который в этом случае автоматически вставляется компилятором перед непосредственным вызовом Create. Это просто compiler-magic фича такая и к классовым методам она никакого отношения не имеет.


 
{RASkov} ©   (2008-04-24 13:01) [83]

> [82] Восхищенный   (24.04.08 12:57)
> Ты, возможно, удивишься

Нет, не удевлюсь, так как то что мы видим в редакторе кода для компилятора это совсем другое :)
А честно - "не знал"... Т.е. именно такое про конструктор слышу в первый раз.


 
Восхищенный   (2008-04-24 13:20) [84]

> {RASkov} ©   (24.04.08 13:01) [83]

Поставь на первой строке конструктора бряк и посмотри, что будет в окне CPU перед этим бряком. Там увидишь вызов функции из System (не помню точное название, что-то типа _CreateInstance), которая реально выделяет память и создает объект (ее код можно посмтреть). А на первой строке конструктора объект уже создан и даже проинициализирован (InitInstance), и сам конструктор, по сути, всего лишь дает возможность его дополнительной (юзерской) инициализации. Ну и есть там еще блок try-except (тоже вставленный компилятором) - это уже к сабжу относится (разрушение объекта при исключении в конструкторе).


 
Jack128_   (2008-04-24 13:43) [85]


> начит проблемы в другом месте кода и это счастье, что тебе
> удалось уловить их хотя бы опосредованно.

не фига. как раз если не обниливать переменную после уничтожения - то проблема может и не проявиться(точнее проявиться - но у юзера), а вот если юзать FreeAndNil - то ошибка ГАРАНТИРОВАННО проявиться.

var
 O: TObject;
begin
 O := TObject.Create;
 try
   Caption := O.ClassType.ClassName;
 finally
   O.Free;
 end;
 Caption := O.ClassType.ClassName; // ошибочный код. Но AV не будет.
end;


Поэтому я почти всегда юзаю FreeAndNil


 
Palladin ©   (2008-04-24 13:57) [86]

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


 
ANB   (2008-04-24 14:10) [87]


> ЮЮ ©   (24.04.08 12:36) [76]
> > [74] ANB   (24.04.08 12:30)
>
> > Вобчем то да. Но могут быть разные глюки потом
>
>
> Глюки после смерти? Если они есть, значит проблемы в другом
> месте кода и это счастье, что тебе удалось уловить их хотя
> бы опосредованно.

Да я не нарывался ни разу.


 
Восхищенный   (2008-04-24 14:11) [88]

> Palladin ©   (24.04.08 13:57) [86]

В самую точку.


 
ANB   (2008-04-24 14:13) [89]


> Palladin ©   (24.04.08 13:57) [86]
> Обниление идентификаторов и перенос конструктора в try выглядит
> как-то неестественно, но это так, придирка не посуществу.
>  Другое беспокоит, не знаю как кто, но у меня обычно в локальных
> перменных не числится больше трех-четырех объектов, а если
> и числится, то используются они в разных временных рамках
> и на каждый идет блок try finally, если же происходит раздувание
> количества, то это первая ласточка к разделению процедуры/метода
> на несколько шагов и оформлении их в виде отдельных процедур/методов.
>  Разделяй и влавствуй, как говорится. Так что, обниление
> идентификаторов, это совет тем кто не умеет структурировать
> программу и лепит все в один.

Значится не писал достаточно сложных программ. :)


 
Palladin ©   (2008-04-24 14:21) [90]


> ANB   (24.04.08 14:13) [89]

кто не писал? я неписал?


 
ANB   (2008-04-24 14:24) [91]

Простенький пример :
имеем хитрый текстовый файл, который надо разобрать на клиенте, закачать в БД и потом обработать уже хранимкой.
В процессе разбора иногда придется опять таки обращаться к БД за уточнением информации.
Ошибочные строки надо записать в другой файл и при этом еще вести лог обработки.
Объектов 5-6 наберется.

Естественным подходом в таком случае будет создать все объекты заранее и только по окончании процедуры удалить.

Городить вложенные 5-6 трай - файнелли - жуткий изврат. Весь код фактически вправо уйдет.

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

Это что получится - на кажную строчку в файнелли надо отдельный блок заводить ? А если потом выяснилось, что объект не нужен был - обратно все убирать ?

ИМХО - в функции должен быть один блок трай - файнелли.


 
Anatoly Podgoretsky ©   (2008-04-24 14:26) [92]

Что только не придумают, что бы оправдать лень или не знание,
правильный код только такой

Create;
try
  ...
finally
  Free;
end;

Никаких множественных obj := nil, много, ну и что, а если посмотреть с другой стороны, например отладка и поиск ошибок, код

Create;
try
  Create;
  try
    Create;
    try
      Create;
      try
        ...
      finally
        Free;
      end;
    finally
      Free;
    end;
  finally
    Free;
  end;
end;

Позволяет легко видет структуру, легко искать ошибки и это без лишних действий

    Free;
    Free;
    Free;
..
    Free;

А кто то за такты боролся, вот они где улетели, куча не нужных Free, как было сказано, если произойдет ошибка на втором Create, то Free будет вызван только один раз. При том приведена сильно упрощеная схема, а в реальности между двумя вызовами Create может быть еще много команд.
Есть конечно редкие случае, а это серверы 24x7 где все надо обертывать множеством try, включая и Create, но таких случаев мало, в основном или лень, или ламеризм, при том с "научным" обоснованием.


 
Palladin ©   (2008-04-24 14:26) [93]


> Объектов 5-6 наберется.

каких например?


 
Игорь Шевченко ©   (2008-04-24 14:28) [94]

ANB   (24.04.08 10:31) [36]


> В случае с одним объектом, конечно, доп.строки являются
> лишними.
> Это я по привычке пишу, чтобы потом не переделывать, если
> в процедуре понядобятся еще объекты.


Тех, кто пишет что-либо, на случай, если  потребуется - давить без жалости.


 
Ega23 ©   (2008-04-24 14:29) [95]


> Естественным подходом в таком случае будет создать все объекты
> заранее и только по окончании процедуры удалить.
>


А это что, необходимо делать в одном месте? Это нельзя разнести на несколько методов? И насколько велика вероятность возникновения исключения в конструкторе любого из них?
Я за 9 лет один единственный раз с raise конструктор писал (и то, вроде, можно было без этих извратов сделать).


 
ANB   (2008-04-24 14:31) [96]


> Palladin ©   (24.04.08 14:26) [93]
>
> > Объектов 5-6 наберется.
>
> каких например?

3 файлстрима, пара объектов для селектов к БД, объект для инсерта в БД.


 
Игорь Шевченко ©   (2008-04-24 14:32) [97]

Kolan ©   (24.04.08 12:46) [79]


> Имхо, слово constructor подразумевает class function, так
> что, имхо, классовый.


как же он может быть классовый, когда конструктор работает с данными конкретного экземпляра ?

Воистину www.delphilamer.ru


 
ANB   (2008-04-24 14:33) [98]


> А это что, необходимо делать в одном месте? Это нельзя разнести
> на несколько методов?

Зачем ? В итерации цикла создавать и разрушать объекты - это извращение.


 
Anatoly Podgoretsky ©   (2008-04-24 14:39) [99]

> Игорь Шевченко  (24.04.2008 14:28:34)  [94]

И вычитать из их кармана, за расточительство.


 
Ega23 ©   (2008-04-24 14:39) [100]


> Зачем ? В итерации цикла создавать и разрушать объекты -
>  это извращение.


Создание и инициализация объектов - в один метод, цикл - во второй, финализация и удаление объектов - в третий...
Метод больший, чем на один экран - сразу настораживает.


 
Игорь Шевченко ©   (2008-04-24 14:41) [101]

ANB   (24.04.08 14:33) [98]


>  В итерации цикла создавать и разрушать объекты - это извращение.


Объекты создаются, используются и удаляются, исключительно по мере надобности в этих объектах.

Если надобностью диктуется создать их внутри итерации цикла и удалить в конце итерации цикла, то их надо создавать внутри итерации цикла и не иначе.


 
Игорь Шевченко ©   (2008-04-24 14:43) [102]


> Создание и инициализация объектов - в один метод, цикл -
>  во второй, финализация и удаление объектов - в третий..
> .
> Метод больший, чем на один экран - сразу настораживает.


Нету универсального решения


 
ANB   (2008-04-24 14:43) [103]


> Ega23 ©   (24.04.08 14:39) [100]
>
> > Зачем ? В итерации цикла создавать и разрушать объекты
> -
> >  это извращение.
>
>
> Создание и инициализация объектов - в один метод, цикл -
>  во второй, финализация и удаление объектов - в третий..
> .
> Метод больший, чем на один экран - сразу настораживает.

И как вы это себе представляете с вашим подходом к блокам трай-файнели ?


 
Ega23 ©   (2008-04-24 14:52) [104]


> И как вы это себе представляете с вашим подходом к блокам
> трай-файнели ?


А что с ними не так?
try-finally я использую только для объектов, время жизни которых в пределах данного метода, либо для парных операций, типа DisableControls\EnableControls

А объекты - это либо временный DataSet, либо TStream, либо TStringList, либо TBitmap или TJPEGImage. Ну TIniFile ещё возможно.
Это 95% классов, которые я таким образом использую.


 
Ega23 ©   (2008-04-24 14:54) [105]


> Нету универсального решения


Универсального вообще ничего нет. Это утопия... :)


 
Игорь Шевченко ©   (2008-04-24 14:56) [106]

Ega23 ©   (24.04.08 14:54) [105]


> Универсального вообще ничего нет.


Есть. Принцип Keep It Simple, Stupid


 
Ega23 ©   (2008-04-24 15:04) [107]


> Stupid


блин. Полминуты наверное соображал, что за StupID такой... :)


 
ANB   (2008-04-24 15:08) [108]


> Ega23 ©   (24.04.08 14:52) [104]

Я озвучил простенькую задачу, приближенную к реальной.
Как разделить эту процедуру на три метода ?


 
ZENsan ©   (2008-04-24 15:09) [109]


> Восхищенный   (24.04.08 12:40) [77]
> > ZENsan ©   (24.04.08 12:26) [72] > Constructor i Destructor
> - единственные класс методы до реализации класс> методов
> в делфи начиная по моему с 2005-ого..1. Конструктор и деструктор
> - вообще не классовые методы.2. Классовые методы реализованы
> во всех версиях Delphi, начиная аж с 1.3. В [65] Плохиш
> дал очень хороший совет. Конечно, можно и дальше переливать
> здесь из пустого в порожнее, но лучше все же последовать
> этому совету.


Посмотри http://delphi.about.com/od/objectpascalide/a/classmethods.htm
В Делфи до 2005 версии не было класс методов кроме конструкторов и деструкторов. И в описании Делфи 2005 описивается это как новоая возможность: http://dn.codegear.com/article/34324
Где пишется, что до 7 версии включительно класс методов НЕБЫЛО!


 
ZENsan ©   (2008-04-24 15:10) [110]

На счёт 2005.. ошибочка, помоему в ней были уже - точно не помню. Но в 7 100% никогда не было! Может просто кто-то не знает что это такое...


 
Palladin ©   (2008-04-24 15:11) [111]


> ZENsan ©   (24.04.08 15:09) [109]

о как... а я оказывается ерундой страдаю... пользуюсь тем чего нет... интересно...


 
Palladin ©   (2008-04-24 15:12) [112]


> ZENsan ©   (24.04.08 15:10) [110]

вот вот... кто то не знает, это точно... не будем показывать пальцами...


 
ZENsan ©   (2008-04-24 15:14) [113]

Тут вообще не на шутку у вас дискуссии... А по началу вопрос-то был простой и на него оветили.. А какой вариант правильный - знает только бог :)

"Маке it simple as possible, but no more!" - Как говорил Niklaus Wirth


 
Ega23 ©   (2008-04-24 15:14) [114]


> Простенький пример :
> имеем хитрый текстовый файл, который надо разобрать на клиенте,
>  закачать в БД и потом обработать уже хранимкой.
> В процессе разбора иногда придется опять таки обращаться
> к БД за уточнением информации.
> Ошибочные строки надо записать в другой файл и при этом
> еще вести лог обработки.


type
 
 TХитыйФайлParser = class

 public
   constructor Create;
   destructor Destroy; override;

   procedure ParseFile;

   property Connection : TADOConnection read FConnection write SetFConnection;
   property FileName : string read FFileName write SetFFileName;
   property ErrFileName : string read FErrFileName write SetFErrFileName;
 end;


 
ZENsan ©   (2008-04-24 15:16) [115]

Palladin

type TMyClass - class
 class procedure SomeProc;
end;

Потом ты пишеш в проге просто:

...
TMyClass.SomeProc;
...

Это класс-метод...
В 7 делфи такого нету. Или я ошибаюсь?


 
Ega23 ©   (2008-04-24 15:16) [116]


> Но в 7 100% никогда не было!


упалпацтул.
Они, вообще-то ещё в D5 были (может и раньше, просто я с D5 начинал)


 
Palladin ©   (2008-04-24 15:17) [117]


> ZENsan ©   (24.04.08 15:16) [115]

конечно ошибаешься, методы класса появились давным давно...


 
Ega23 ©   (2008-04-24 15:17) [118]


> type TMyClass - class
>  class procedure SomeProc;
> end;
>
> Потом ты пишеш в проге просто:
>
> ...
> TMyClass.SomeProc;
> ...
>
> Это класс-метод...
> В 7 делфи такого нету. Или я ошибаюсь?


И этот человек принимает участие в разработке JEDI....


 
ZENsan ©   (2008-04-24 15:19) [119]

чуваки дают.......

Не методы класса!!!!  Вы вообще читаете...

Это методы класса, которые могут вызываться без создания объекта!!!

С кем я тут вообще общаюсь тогда....


 
Игорь Шевченко ©   (2008-04-24 15:21) [120]


> Это методы класса, которые могут вызываться без создания
> объекта!!!


они вообще с первой версии Delphi имеются.


 
Palladin ©   (2008-04-24 15:21) [121]


> ZENsan ©   (24.04.08 15:19) [119]

ты это, больной на голову чтоли? а я тебе о чем говорю, или ты считаешь что я читать не умею...


 
ZENsan ©   (2008-04-24 15:22) [122]

Вэ даже на факти с официального сайта разработчика не обращаете внимания - чего тут говоить-то
http://dn.codegear.com/article/34324


 
ZENsan ©   (2008-04-24 15:23) [123]

До 7 делфи вы можете описать только динамические методы класа. И статические были только конструктор/деструктор...


 
Palladin ©   (2008-04-24 15:24) [124]


> ZENsan ©   (24.04.08 15:23) [123]

хватит гнать пургу...


 
ZENsan ©   (2008-04-24 15:25) [125]

А скажи нет еще...? Я болен вместе с CodeGear да?


 
Palladin ©   (2008-04-24 15:27) [126]

да у меня D5 и D6
я с D6 работаю ~6 лет
возможно они есть и в D4
за раньше не скажу


 
Игорь Шевченко ©   (2008-04-24 15:29) [127]

"Unlike ordinary class methods, class static methods have no Self parameter at all"
"Also unlike class methods, class static methods cannot be declared virtual. "

и вся разница.

ZENsan ©   (24.04.08 15:23) [123]


> И статические были только конструктор/деструктор...


деструктор всегда виртуальный (у TObject), следовательно не может быть статическим.


 
ZENsan ©   (2008-04-24 15:30) [128]

Я начинал с 4-ого... Их там никогда не было и в 5 небыло, и в 6-ом.. и в 7-ом..

Может у тебя в 7-ом ещё и записи с методами естй??
типа

type TmyRecord = record
 Value: Integer;
 procedure SomeProc;
end;


 
Восхищенный   (2008-04-24 15:30) [129]

> ZENsan ©   (24.04.08 15:09) [109]

Ссылку посмотрел. Полезная. Для начинающих. Мне уже поздно. Видишь ли, в чем штука - я подобные статьи писал (именно так - уже не читал, а писал) еще когда даже Win32 еще только в проекте была. То есть, лет около 15 тому назад - и именно по Delphi 1 (а других тогда и не было).

Еще раз тебе говорю - классовые методы существовали в Delphi всегда, начиная с самой первой версии. И не спорь даже. Не позорься.

Что касается второй ссылки ("в описании Делфи 2005 описивается это как новоая возможность") - то ты перепутал, извини, зеленое с горячим. Там речь идет совсем о другом.


 
Palladin ©   (2008-04-24 15:31) [130]

почитал то что по ссылке, что то бред какой то, зачем метод класса делать еще и статическим. чем

Class Function Func:Integer;

отличается от
Class Function Func:Integer; Static;


 
ZENsan ©   (2008-04-24 15:32) [131]

Удалено модератором


 
Palladin ©   (2008-04-24 15:32) [132]


> ZENsan ©   (24.04.08 15:30) [128]

еще раз говорю, прекрати нести пургу
процедур в записях нет конечно


 
Anatoly Podgoretsky ©   (2008-04-24 15:33) [133]

> Palladin  (24.04.2008 15:24:04)  [124]

Жалко мне Борланда и проект JEDI


 
ZENsan ©   (2008-04-24 15:34) [134]

Удалено модератором


 
Palladin ©   (2008-04-24 15:34) [135]


> ZENsan ©   (24.04.08 15:32) [131]

да ты достал уже, все прекрасно понимают что ты тут несешь

Type
TShowMessage=Class
 Class Procedure ShowMessage;
End;

...
TShowMessage.ShowMessage
...

найди любой компилятор старый и откомпилируй


 
ZENsan ©   (2008-04-24 15:38) [136]

Удалено модератором


 
Palladin ©   (2008-04-24 15:39) [137]


> Bolshe ja s vami na etu temu obshatsja ne budu...

ну и слава богу...


 
Восхищенный   (2008-04-24 15:41) [138]

> ZENsan ©   (24.04.08 15:23) [123]

> До 7 делфи вы можете описать только динамические методы класа.

А также виртуальные, статические, абстрактные и классовые (которые, в свою очередь, тоже могут быть виртуальными и т.д.)

> И статические были только конструктор/деструктор...

Так. На этом базар заканчиваем. Если человек не знает:

- что статические методы в Delphi были тоже всегда (притом любые);
- что деструктор в Delphi статическим вообще никогда не был;
- что начиная с класса TComponent конструктор всегда был виртуальным...

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

Иначе говоря - "ламер". Спорить с такими бесполезно. И не нужно.


 
sniknik ©   (2008-04-24 15:48) [139]

ожидали чегото иного от использующего транслит?
имхо, это показатель. нынче возможность писать нормально есть, а транслит используют только любители "погнуть пальцы".


 
Ega23 ©   (2008-04-24 16:04) [140]


> ожидали чегото иного от использующего транслит?
> имхо, это показатель. нынче возможность писать нормально
> есть, а транслит используют только любители "погнуть пальцы".


Это что, новая мода какая-то?


 
Anatoly Podgoretsky ©   (2008-04-24 16:08) [141]

> Palladin  (24.04.2008 15:34:15)  [135]

Лучше всего Д1


 
ZENsan ©   (2008-04-24 16:09) [142]

Класс-метод это метод, который может быть вызван из Типа, а не объекта.

TMyClass.SomeMthod(params, params,...)

Этот метод не имеет указателя Self - одни из главных отличий класс-методов от методов класса. Не путать.

А вы мне втираете virtual.... они не могут быть virtual.. не могут быть dynamic, но может быть astract.

Это про Delphi 2007 если что.

Вы меня извините конечно за мой русский корявый может - я не в России живу. Но я подозреваю вы не присмотрелись в разницу между "Метод класса" и "Класс-метод". Ну зайдите кот-нибудь на оф. сайт http://dn.codegear.com/article/34324 и прочтите...я же не просто так пытаюсь вам пояснить.. Я говорю про Класс-методы а не про методы класса, которые ещё паскале были. В добавок к КЛАСС-МЕТОДАМ добаивлась возможность КЛАСС-ПЕРЕМЕННИХ:

var
 X: TmyClass;
 i: Integer;
begin
 i := TMyClass.GetTickCount;//например
end;

Ну плиизз может хоть до кого-то дойдёт наконец о чём я говорю... или скажите как это по русски КЛАСС-МЕТОД.....
end;


 
Anatoly Podgoretsky ©   (2008-04-24 16:09) [143]

> sniknik  (24.04.2008 15:48:19)  [139]

Вот только на нас обжегся, заставили писать нормально, теперь хвастаться можно.


 
Palladin ©   (2008-04-24 16:12) [144]


> ZENsan ©   (24.04.08 16:09) [142]

ты реально болен...


 
Ega23 ©   (2008-04-24 16:15) [145]


> TMyClass.SomeMthod(params, params,...)
>
> Этот метод не имеет указателя Self - одни из главных отличий
> класс-методов от методов класса. Не путать.


С чего ты взял, что внутри class procedure или class function Self нельзя использовать? Посто там он указатель на тип класса, на не на экземпляр.


 
ZENsan ©   (2008-04-24 16:15) [146]

что такое

type
 TMyClass = class
   class var x: Integer;
 end;

вы тоже не знаете или у вас уже в 4 делфи это есть...


 
ZENsan ©   (2008-04-24 16:17) [147]

"class static methods have no Self parameter at all" - официальный источник.

Это про Делфи 2007. Там нету вообще Селф.


 
ZENsan ©   (2008-04-24 16:18) [148]

Ты не можеш также получать доступ к полям класса (которие не класс-поля)..


 
Palladin ©   (2008-04-24 16:19) [149]


> ZENsan ©   (24.04.08 16:17) [147]

это статический метод класс, тебе уже сказали, что ты мягкое с теплым перепутал...

короче, вердикт: LMD


 
ZENsan ©   (2008-04-24 16:23) [150]

Значит у тебя в 7 делфи они есть? Как и класс-переменные?


 
Anatoly Podgoretsky ©   (2008-04-24 16:23) [151]

> ZENsan  (24.04.2008 16:15:26)  [146]

Ты чего юлить начал?


 
ZENsan ©   (2008-04-24 16:24) [152]


> Ты чего юлить начал?

Делфи 2007 синтаксис


 
Игорь Шевченко ©   (2008-04-24 16:32) [153]

"Кто не работает, не ест, ты спутал, батя"


 
ZENsan ©   (2008-04-24 16:33) [154]

Я просто рассказываю-то не static members...


type
 TMyClass = class
   strict private
     class var
       FX: Integer;
   strict protected  

   // Note: accessors for class properties must be declared class static.

     class function GetX: Integer; static;
  class procedure SetX(val: Integer); static;
   public
     class property X: Integer read GetX write SetX;
  class procedure StatProc(s: String); static;
 end;

TMyClass.X := 17;
TMyClass.StatProc("Hello");


Или вы даже сайту CodeGear не верите уже...что это новшество в языке и появилось только недавно.


 
{RASkov} ©   (2008-04-24 16:34) [155]

> [146] ZENsan ©   (24.04.08 16:15)

Классовые методы имеются всегда. TObject он вообще практически из них только и состоит, а вот классовые переменные появились позже... позже D7..


 
Игорь Шевченко ©   (2008-04-24 16:35) [156]


> ZENsan ©   (24.04.08 15:16) [115]
> Palladin
>
> type TMyClass - class
>  class procedure SomeProc;
> end;
>
> Потом ты пишеш в проге просто:
>
> ...
> TMyClass.SomeProc;
> ...
>
> Это класс-метод...
> В 7 делфи такого нету. Или я ошибаюсь?


Ошибаешься


 
ZENsan ©   (2008-04-24 16:35) [157]

Игорь неужели даже вы не видите различия здесь от Делфи 7....


 
{RASkov} ©   (2008-04-24 16:37) [158]

> [157] ZENsan ©   (24.04.08 16:35)

А что от чего отличаем-то?


 
ZENsan ©   (2008-04-24 16:40) [159]


> А что от чего отличаем-то?


begin
 TMyClass.X := 17;
 TMyClass.StatProc("Hello");
end.


 
Игорь Шевченко ©   (2008-04-24 16:41) [160]

ZENsan ©   (24.04.08 16:35) [157]

type TMyClass = class
 class procedure SomeProc;
end;

...
 TMyClass.SomeProc;

Этот код можно выполнить в D1,D2,D3,D4,D5,D6,D7, далее со всеми остановками до станции Можайск Смоленского направления.


 
ZENsan ©   (2008-04-24 16:42) [161]

Вложенные классы.. Ето всё новое после 7 делфи..


 
{RASkov} ©   (2008-04-24 16:42) [162]

> [159] ZENsan ©   (24.04.08 16:40)

И что? Вторая строка откомпилится во всех делфи...


 
{RASkov} ©   (2008-04-24 16:44) [163]

> [161] ZENsan ©   (24.04.08 16:42)
> Вложенные классы..

куда? :) в МММ?


 
ZENsan ©   (2008-04-24 16:45) [164]

type
 TOuterClass = class
 strict private
MyField: Integer;
 public
type
     TInnerClass = class
  public
       MyInnerField: Integer;
 procedure InnerProc;
     end;
     procedure OuterProc;
 end;


 
{RASkov} ©   (2008-04-24 16:45) [165]

> Вторая строка откомпилится во всех делфи...

имелось в виду эта:

> TMyClass.StatProc("Hello");


 
ZENsan ©   (2008-04-24 16:46) [166]

Вы просто на 2007 не работали я смотрю...


 
{RASkov} ©   (2008-04-24 16:46) [167]

> [164] ZENsan ©   (24.04.08 16:45)

Это что за вообще такое и к чему оно вообще здесь? :)


 
{RASkov} ©   (2008-04-24 16:47) [168]

> [166] ZENsan ©   (24.04.08 16:46)

не работали и что? :)
От этого классовые методы из предыдущих делфи не пропали.... поверь :)


 
Palladin ©   (2008-04-24 16:47) [169]


> {RASkov} ©   (24.04.08 16:46) [167]

он юлить начал, вот к тому это...


 
ZENsan ©   (2008-04-24 16:47) [170]

Ну про новшества since Delphi 7...


 
{RASkov} ©   (2008-04-24 16:49) [171]

> [169] Palladin ©   (24.04.08 16:47)

Уже давно начал...


 
Ega23 ©   (2008-04-24 16:50) [172]


> Ну про новшества since Delphi 7...


Вот чудак-человек. Ты сейчас пытаешься доказать то, что колесо было изобретено в 20 веке.


 
Восхищенный   (2008-04-24 16:51) [173]

> ZENsan ©   (24.04.08 16:17) [147]

> "class static methods have no Self parameter at all" - официальный источник.
> Это про Делфи 2007. Там нету вообще Селф.

Все правильно. Но новое здесь только слово static, а не class. Ты ошибся. Спутал теплое с мягким.

Классовые методы (class methods), как тебе уже устали говорить, в Delphi были всегда, начиная еще с D1. Они действительно могут быть вызваны без создания экземпляра класса - и это тоже было всегда. Параметр Self в них есть, но, в отличие от обычных методов, указывает он именно на класс, а не на экземпляр класса - и это тоже было всегда.

Новое здесь по сравнению с D7 (и всеми предыдущими) - слово static. Оно означает, что метод может быть вызван из типа класса. Читай описание внимательно, там же все сказано:

"Classes can have static class methods -- i.e. methods that can be called from a class type. Class static methods can be accessed without an object reference. Unlike ordinary class methods, class static methods have no Self parameter at all. They also cannot access any instance members. (They still have access to class fields, class properties, and class methods.) Also unlike class methods, class static methods cannot be declared virtual".

Обрати внимание на выделенные слова "Unlike ordinary class methods" и "unlike class methods". Об отличиях от чего здесь говорится, по-твоему? Об отличиях от каких других классовых методов?

Вот от тех самых, которые существовали всегда, но только не были static. А ты почему-то решил, что их вообще никогда не было.

А они были. Всегда. Ты просто этого не знал. Но почему-то решил, что можешь спорить с людьми, которые знают и понимают гораздо больше тебя. И напорол чуши.

Подумай. И не ламерствуй более.


 
{RASkov} ©   (2008-04-24 16:57) [174]

А мне сразу JEDI не понравилась... жаль что RX к ним перешла :(
:о)

> ZENsan ©

если что, это у меня шутки такие) Хотя в данном случае - не совсем шутка.


 
Игорь Шевченко ©   (2008-04-24 17:00) [175]


> А мне сразу JEDI не понравилась


А причем тут Jedi ?


 
Ega23 ©   (2008-04-24 17:02) [176]


> А причем тут Jedi ?


http://delphimaster.net/view/15-1208941969/
[15]


 
ZENsan ©   (2008-04-24 17:03) [177]

Ща переварю..


 
{RASkov} ©   (2008-04-24 17:06) [178]

> А причем тут Jedi ?

Не повезло ей
:о)


 
Игорь Шевченко ©   (2008-04-24 17:07) [179]

Ega23 ©   (24.04.08 17:02) [176]

"Ну так и вы говорите - в чем проблема" (с) известный анекдот про соседа


 
{RASkov} ©   (2008-04-24 17:15) [180]

> [175] Игорь Шевченко ©   (24.04.08 17:00)

Просто ZENsan уверяет, что он является разработчиком компонента(ов) в проекте JEDI... в [176] вместе со ссылкой есть номер поста.
Ну а мне почему-то издавна.... т.е. сразу как первый раз попробывал, не понравился данный монстр-проект.... а тут еще такое ...свалилось :)
Ничего личного.... считайте за шутку.


 
ZENsan ©   (2008-04-24 17:18) [181]

Удалено модератором
Примечание: Выражения выбираем, не в пивной


 
ZENsan ©   (2008-04-24 17:20) [182]

Я не прямой Jedi developer... не пугайтесь так.. просто с некоторыми разработчиками вместе ковырялись часто с некоторыми проблемами...


 
Ega23 ©   (2008-04-24 17:25) [183]


> Ну чё теперь с лохом со мной делать будем? ....


Оскопить, предать анафеме и торжественно сжечь на городской площади. :)


 
ZENsan ©   (2008-04-24 17:25) [184]

Простите мастера за упрямость... блин ну так жестоко лохануться...

Всё иду вешаться....


 
ZENsan ©   (2008-04-24 17:27) [185]

Иду торжественно вешаться...

Так облили из-за этого промаха... вот так ло....


 
sniknik ©   (2008-04-24 17:30) [186]

не изза промаха, а изза гонора... общался бы нормально без апломба и наездов давно бы уж все разъяснили бы.

опять путаешь теплое с мягким.


 
{RASkov} ©   (2008-04-24 17:31) [187]

> [185] ZENsan ©   (24.04.08 17:27)

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


 
ZENsan ©   (2008-04-24 17:34) [188]

Согласен. Стыдно даже... Извините пожалуйста... В селдующий раз точно буду внимателней...

Ещё раз извините.


 
Восхищенный   (2008-04-24 17:38) [189]

> ZENsan ©   (24.04.08 17:18) [181]

Хочешь совет, за который ты потом сто раз "спасибо" скажешь (если ему последуешь, конечно)?

Отложи на время разработку компонентов. Рано тебе еще. Без обид. Почитал я тут твои сообщения (не только в этой ветке, в других тоже) - и говорю тебе - рано. Не знаешь ты еще объектной модели Delphi и не понимаешь ее на том уровне, чтобы хорошие компоненты писать. А плохие - кому они нужны? Их только ленивый не писал, плохих-то, ими пол-инета завалено. Только мусор все это.

Поэтому - отложи на время разработку компонентов. А вместо этого потрать время на то, чтобы найти, скачать и капитально проштудировать книгу Рэя Конопки по разработке компонентов.

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

Вот поверь. Может, оно и кажется обидным, но потом благодарить будешь. Этих самых компонентов я написал штук сто (а может и больше), очень разных, и простых, и сложных, и визуальных, и невизуальных, и для работы с данными, и всяких прочих - и все написаны профессионально, можешь поверить. Поэтому и говорю тебе - рано. Тебе сейчас не писать, а читать надо. И лучшей книги по этой теме, чем Конопка ты на русском не найдешь. Ее нет просто. Есть еще две другие книжки, но они послабее будут.

Вот такой совет.


 
ZENsan ©   (2008-04-24 17:44) [190]

Спасибо Восхищённый. Я и не говорил что я прям разрабатываю компоненты - лишь ингода учавствую в этом. А книжку поищю. Обид никаких. Я не силён сам в разработке компонентов, только чуток. Больше уделял время другому, поэтому и не знаю так глубоко объектную модель Делфи. Знал только то что использовал..наследования там всё такое.. А вот ети нюансы.. Буду читать, учится.. пригодится.

Спасибо, Восхищенный - даёшь дельные советы а не добиваешь в итак хреновой моральной обстановке..


 
ZENsan ©   (2008-04-24 17:45) [191]

А книгу уже стянул, приступлю скоро..


 
Palladin ©   (2008-04-24 17:50) [192]

чет я про ANB забыл :)


> ANB   (24.04.08 14:31) [96]

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

Type
TTextProceedManager=Class
 Private
  m_fileInText:TextFile;
  m_theLogStm:TFileStream;
  m_theErrStm:TFileStream;
  m_theSelQuery:TADOQuery;
  m_theExecQuery:TADOQuery;
 Public
  Constructor Create(Const p_strSrcFileName,p_strLogFileName,p_strErrFileName,p_strConnectionString:String) ;
  Destructor Destroy; Override;

  Procedure LogWriteLn(s:String);
  Function ReadLn:String;
  Procedure SaveErrorLine(s:String);
  Procedure Select(Const p_strSQL:String);
  Procedure Execute(Const p_strSQL:String);

  Property DataSourceQuery:TADOQuery Read m_theSelQuery;
End;

Constructor TTextProceedManager.Create;
Begin
If Not FileExists(p_strSrcFileName) Then Raise Exception(Format("File %s not found",[p_strSrcFileName]));

AssignFile(m_fileInText,p_strSrcFileName); Reset(m_fileInText);

m_theLogStm:=TFileStream.Create(p_strLogFileName,fmCreate);
m_theErrStm:=TFileStream.Create(p_strLogFileName,fmCreate);

m_theSelQuery:=TADOQuery.Create(Nil);
m_theSelQuery.ConnectionString:=p_strConnectionString;

m_theExecQuery:=TADOQuery.Create(Nil);
m_theExecQuery.ConnectionString:=p_strConnectionString;
End;

Destructor TTextProceedManager.Destroy;
Begin
CloseFile(m_fileInText);
m_theLogStm.Free;
m_theErrStm.Free;
m_theSelQuery.Free;
m_theExecQuery.Free;
End;

Procedure TTextProceedManager.LogWriteLn;
Begin
s:=s+#13#10;
m_theLogStm.Write(s[1],Length(s));
End;

Procedure TTextProceedManager.SaveErrorLine;
Begin
s:=s+#13#10;
m_theErrStm.Write(s[1],Length(s));
End;

Procedure TTextProceedManager.Select;
Begin
m_theSelQuery.Close;
m_theSelQuery.SQL.Text:=p_strSQL;
m_theSelQuery.Open;
End;

Procedure TTextProceedManager.Execute;
Begin
m_theExecQuery.SQL.Text:=p_strSQL;
m_theExecQuery.ExecSQL;
End;

Function TTextProceedManager.ReadLn;
Begin
System.ReadLn(m_fileInText,Result);
End;


и с наслаждением используем без всяких каскадов из try finally


Var
TPM:TTextProceedManager;
...
TPM:=TTextProceedManager.Create;
Try
Finally
TPM.Free;
End;


 
sniknik ©   (2008-04-24 18:13) [193]

<> CODE>m_theSelQuery:=TADOQuery.Create(Nil);
> m_theSelQuery.ConnectionString:=p_strConnectionString;

> m_theExecQuery:=TADOQuery.Create(Nil);
> m_theExecQuery.ConnectionString:=p_strConnectionString;

ай, нехорошо... чревато глюками (2 коннекта, одним сделал изменения, другим тут же прочитал, а данные то старые... не синхронизированные).


 
Palladin ©   (2008-04-24 18:16) [194]


> sniknik ©   (24.04.08 18:13) [193]

аааа.... ты придешь... я знал... я знал.... :) в общем тонкости реализации работы с БД в этом псевдопримере лучше доверить Николаю :) схема понятна...


 
ANB   (2008-04-25 09:51) [195]


> Palladin ©   (24.04.08 17:50) [192]

Хай. Снимаю свой наезд по поводу разработки сложных программ. Ты их реально пишешь. :)
Значится по коду замечания :
1) Все что здесь уже написано - это заменяет всего строк 10 в одной процедуре. Сильно проще не стало.
2) Про коннекты - отдельная песня, но т.к. я работаю с ораклом и не через АДО - это тут по барабану. В одаке тяжелее так лопухнутся, т.к. компоненты не умеют сами по себе коннектится.
3) Более серьезное замечание : селекты и инсерты надо запихать ДО цикла и препарировать. Чтобы уже в итерации тока параметры подсовывать. Потому я под кажный ДМЛ и отвел отдельный объект.
4) А теперь самое главное - чем отличается принципиально твой подход от моего с одним файнелли ? Ну разве что тем, что ты пользуешь поля класса, а я - локальные переменные, посему мне надо их нилить, а за тебя это неявно конструктор сделает.


 
ANB   (2008-04-25 09:53) [196]

Да. По п.2. В принципе ИНОГДА имеет смысл открыть и несколько сессий для ускорения.


 
Восхищенный   (2008-04-25 09:55) [197]

> ANB   (25.04.08 09:51) [195]

> 4) А теперь самое главное - чем отличается принципиально
> твой подход от моего с одним файнелли?

Структурированностью и обозримостью. Из которых вытекают более простые модификация, расширение и поддержка. Они и есть - принципиально.


 
Ega23 ©   (2008-04-25 10:09) [198]


> 4) А теперь самое главное - чем отличается принципиально
> твой подход от моего с одним файнелли ? Ну разве что тем,
>  что ты пользуешь поля класса, а я - локальные переменные,
>  посему мне надо их нилить, а за тебя это неявно конструктор
> сделает.
>


Дык и всю программу можно без процедур и функций писать. С глобальными переменными и goto. И будет работать. И может быть даже не хуже.
Вот только нечитабельно будет.


 
Игорь Шевченко ©   (2008-04-25 10:16) [199]


> Вот только нечитабельно будет.


Тоже не факт. Иные напишут с десяток классов в иерархии - вааще не прочитаешь, не то, что изменения какие вносить


 
Восхищенный   (2008-04-25 10:28) [200]

> Игорь Шевченко ©   (25.04.08 10:16) [199]

Если в голове разруха - то да. А если вся иерархия четко спроектирована, если понятно, для чего каждый класс нужен, что и как он делает - то нет.


 
Ega23 ©   (2008-04-25 10:39) [201]


> Тоже не факт. Иные напишут с десяток классов в иерархии
> - вааще не прочитаешь, не то, что изменения какие вносить


Игорь, ты же сам говорил, что универсальных решений не бывает.
Но вот уже достаточно длительное время у меня никак не получается процедуры-фунции-метода более, чем на 50 строк кода. Чаще - 10-20 между основным begin..end


 
Anatoly Podgoretsky ©   (2008-04-25 10:59) [202]

> Игорь Шевченко  (25.04.2008 10:16:19)  [199]

Ну так любуб вещь можно испоганить, дело то не хитрое.


 
Игорь Шевченко ©   (2008-04-25 11:03) [203]

Восхищенный   (25.04.08 10:28) [200]

А если в голове разрухи нет, можно и с goto вполне читабельно написать


 
sniknik ©   (2008-04-25 11:08) [204]

> В одаке тяжелее так лопухнутся, т.к. компоненты не умеют сами по себе коннектится.
больше возможностей -> больше вероятность какуюто применить не по адресу.
так данная возможность "отдельно стоящего" рекордсета мной часто используется, не связывая с базой, для хранения и обработки данных.

> Да. По п.2. В принципе ИНОГДА имеет смысл открыть и несколько сессий для ускорения.
коннект может держать собственные потоки (асинхронность), т.е. нет нужды в дополнительных сессиях, если только эти сессии не к разным sql серверам. ("ИНОГДА" еще на 100 поделить, для определения реальной нужды в использовании)


 
ANB   (2008-04-25 11:14) [205]


> Тоже не факт. Иные напишут с десяток классов в иерархии
> - вааще не прочитаешь, не то, что изменения какие вносить

+1.

Смотрел я как то модуль импорта в новом проекте. 20 методов по 3-5 строчек в каждом. Вызываются друг из друга. Черт ногу сломит. Хотя процедура и алгоритм довольно простые.
А так сам автор пол-часа искал, где у него что живет.


 
ANB   (2008-04-25 11:17) [206]


> коннект может держать собственные потоки (асинхронность),
>  т.е. нет нужды в дополнительных сессиях

Не. У оракла если сессия чего то делает, пусть и асинхронно, второй запрос параллельно уже не пустишь. Там с сессиями все строго.
А для мс скл - не наю. Когда сталкивался с ним, понял, что понятие "сессия" у него более гибкое и сложное.


 
Игорь Шевченко ©   (2008-04-25 12:06) [207]


> Не. У оракла если сессия чего то делает, пусть и асинхронно,
>  второй запрос параллельно уже не пустишь. Там с сессиями
> все строго.


Э...я как бы запускал несколько запросов параллельно в одной сессии...


 
ANB   (2008-04-25 12:09) [208]


> Э...я как бы запускал несколько запросов параллельно в одной
> сессии...

Невозможно.
Чем пользовались (компоненты) ?
Есть подозрение, что сессии были созданы автоматически.
ОДАК и ДОА такого не допускают.
Можно только распараллелить запрос, но при этом все равно оракл под кажную порцию сам запустит свою сессию.


 
Palladin ©   (2008-04-25 13:14) [209]


> ANB   (25.04.08 09:51) [195]

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

1. В какие десять строк? 6 компонентов, 6 присваниваний в Nil, 6 конструкторов, 6 вызово free, сколько? 24 строчечки... + try finally end, 27 строчечек, + еще десятки строк на работу с объектами и сам по себе парсинг.
2. Я не привел тебе код для копирования и вставки, я привел тебе метод решения задачи.
3. До какого цикла? Ты где у меня циклы увидел вообще?
4. Вот именно что отличается принципиально. Перед нами сущность созданная для функционала, а не для конкретной работы. Сегодня текстовые файлы, завтра файл с определенной структурой, после завтра XML. И что будет менятся? Не вся жирная процедура, а только методы этой сущности, которые отвечают за работу с внешними данными.


 
ANB   (2008-04-25 13:40) [210]


> 3. До какого цикла? Ты где у меня циклы увидел вообще?

Цикл подразумевается в методе "Все сделать".


 
ANB   (2008-04-25 13:44) [211]


> Да, у меня каскадом вложенных try блоков и не пахнет.

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


 
Игорь Шевченко ©   (2008-04-25 13:57) [212]

ANB   (25.04.08 12:09) [208]


> Невозможно.


Выдержку из оракловской доки, плз.


> Чем пользовались (компоненты) ?


Своими.

Где-то такой код:

procedure TdmMember.DataModuleCreate(Sender: TObject);
begin
...
 if Options.RunBirthdayThread then
   TBirthdayThread.Create;
 if Options.RunExpiredTempThread then
   TExpiredTempThread.Create;
end;

procedure TBirthdayThread.Execute;
...
   dmMember.BirthdayThreadRunning := true;
   with dmMember.qMemberBirthday do
   begin
     Prepare;
     Params[0].AsString := Today;
     Open;
     try
       while not Eof and not Terminated do
       begin
....
      end;
...
   end;
...
end;

...

procedure TExpiredTempThread.Execute;
begin
....
   dmMember.ExpiredTempThreadRunning := true;
   with dmMember.qExpiredTemp do
   begin
     Prepare;
     Open;
     try
       while not Eof and not Terminated do
       begin
          ....
       end;
    ...
    end;
...
end;


 
Восхищенный   (2008-04-25 14:35) [213]

> ANB   (25.04.08 13:44) [211]

> я переношу в отдельную функцию код, если он повторяется более одного
> раза.

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


 
ANB   (2008-04-25 14:44) [214]


> Восхищенный   (25.04.08 14:35) [213]

Да я как то не прусь от ООП. Пользуюсь, только если очень надо. Как то без него быстрее и понятней получается. Есно, это сугубо личное впечатление.


> Игорь Шевченко ©   (25.04.08 13:57) [212]

Вот выдержку не найду. Не уверен, что запрещены параллельные фетчи из одной сессии. Скорее всего опен у вас быстро отрабатывает и вы не нарывались на пересечение, когда они работают одновременно.
А сессия лежит на ДМ основного потока и на ошибку не нарывались при работе с ней из доп.потоков ?

Попробуйте для чистоты эксперимента следующее :
Запустите хранимку, которая долго работает. И из под той же сессии попробуйте выполнить любой запрос.


 
jack128_   (2008-04-25 14:51) [215]


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

какая разница, полиморфизм используется для того же, для уменьшения дубляжа кода, так что вынос общего кода в статический метод,а "переменного" кода - в виртуальные методы, так же подподает под критерий ANB ;)


 
Ega23 ©   (2008-04-25 14:57) [216]


> Дык это Ega23 любит вложенные трай.


Где я такое говорил? Моё максимальное, что за 8 лет было -

......
try
 ........
 try
   ........
   try
     .......
   except

   end;
 finally

 end;
.......
except

end


Я просто такой фигнёй не страдаю, чтобы создать 6 объектов и в finally их грохать. Если тебе так писать понятнее и удобнее - ради бога.


 
Восхищенный   (2008-04-25 14:57) [217]

> jack128_   (25.04.08 14:51) [215]

> полиморфизм используется для того же, для уменьшения дубляжа кода,
??????????????!!!!!!!!!!!!!!!!!!!

> так же подподает под критерий ANB
??????????????


 
ANB   (2008-04-25 15:10) [218]


> Ega23 ©   (25.04.08 14:57) [216]

А для 6 как сделаешь ?


 
Ega23 ©   (2008-04-25 15:21) [219]


> А для 6 как сделаешь ?


1. Я постараюсь такого не делать. Ну не встречал я ещё такой необходимости по созданию 6 объектов внутри одного метода, с обязательным их гроханием в том же методе.
2. Если всё-таки надо создать больше одного (ну, например, битмап в jpg), то тупо
bmp := TBitmap.Create;
jpg := TJPEGImage.Create;
try
 ..... работаем с ними
finally
 jpg.Free;
 bmp.Free;
end;


Дело в том, что вероятность того, что TBitmap или TJPEGImage дадут exception в конструкторе - ну практически нулевая.


 
ANB   (2008-04-25 15:26) [220]


> ну практически нулевая.

"ну практически" и совсем нулевая - разные вещи.

Обниление до трая сожрет несколько тиков проца. И намного меньше, чем само создание объектов. Это так критично ?

Фри нилового объекта тоже пара тактов.


 
jack128_   (2008-04-25 15:27) [221]


> > полиморфизм используется для того же, для уменьшения дубляжа
> кода,


function TMyClass.MyFunc1(D: Double): Double;
begin
 Result := 152*D - D*D + sqr(D) + sin(D);
end;

function TMyClass.MyFunc2(D: Double): Double;
begin
 Result := 152*D - D*D + sqr(D) + cos(D);
end;


различие в двух функциях минимальное.

теперь прикрутим сюда полиморфизм:

type
 TMyBaseClass =class
   function VirtMethod(D: Double): Double; virtual; abstract;
   function MyFunc(D: Double): Double;
 end;

// теперь мы вынесли общую часть кода - в статический метод. Уменьшили дубляж кода..

function TMyBaseClass.MyFunc(D: Double): Double;
begin
 Result := 152*D - D*D + sqr(D) + VirtMethod(D);
end;

function TMyClass1.VirtMethod(D: Double): Double;
begin
 Result := sin(D);
end;

function TMyClass2.VirtMethod(D: Double): Double;
begin
 Result := cos(D);
end;


> так же подподает под критерий ANB


ну цитирую:

> я переношу в отдельную функцию код, если он повторяется
> более одного

я сделал тоже самое - нашел повторяющийся кусок кода - и вынес его в отдельную функцию(метод)


 
Ega23 ©   (2008-04-25 15:39) [222]


> "ну практически" и совсем нулевая - разные вещи.


Загляни прикола ради в конструктор TBitmap.
"ну практически" - здесь - пнули ногой системник, какой-то сбой операционки и т.п.


 
Восхищенный   (2008-04-25 15:41) [223]

> jack128_   (25.04.08 15:27) [221]

> я сделал тоже самое - нашел повторяющийся кусок кода - и вынес его в
> отдельную функцию(метод)

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

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


 
jack128_   (2008-04-25 15:43) [224]


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

хе.  чем поможет наследование БЕЗ полиморфизма??


 
Anatoly Podgoretsky ©   (2008-04-25 15:44) [225]

> ANB  (25.04.2008 15:10:38)  [218]

Хочешь знать как я сделаю?
Это будет зависить от задачи и от настроения иногда.


 
jack128_   (2008-04-25 15:44) [226]

в данном случае, я имею в виду..


 
Leonid Troyanovsky ©   (2008-04-25 15:44) [227]


> jack128_   (25.04.08 15:27) [221]

> // теперь мы вынесли общую часть кода - в статический метод.
>  Уменьшили дубляж кода..

Не. Статический не нужен.

function TMyBaseClass.VirtMethod(D: Double): Double; // virtual;
begin
Result := 152*D - D*D + sqr(D);
end;

function TMyClass1.VirtMethod(D: Double): Double; // override;
begin
Result := inherited VirtMethod(D);
Result := Result + sin(D);
end;

--
Regards, LVT.


 
jack128_   (2008-04-25 15:45) [228]


>
> Не. Статический не нужен

Ну с такой позиции - статические методы вообще не нужны ;-)  Кроме хаков, а-ля TObject.Free


 
Восхищенный   (2008-04-25 15:46) [229]

> jack128_   (25.04.08 15:27) [221]

Кстати, в отдельный метод ты вынес как раз НЕповторяющийся кусок кода (Sin и Cos). Что полностью противоречит [211] и о чем говорилось в [213].


 
Leonid Troyanovsky ©   (2008-04-25 15:48) [230]


> Восхищенный   (25.04.08 14:35) [213]

>  и делать его виртуальным
> (или динамическим, если замещение маловероятно).

Наоборот.
Динамический - компактней.

--
Regards, LVT.


 
Восхищенный   (2008-04-25 15:49) [231]

> jack128_   (25.04.08 15:43) [224]

>  чем поможет наследование БЕЗ полиморфизма??

??????????????!!!!!!!!!!!!!!

Как раз тем, что снижает дубляж. Класс-предок при этом может вообще не иметь ни одного виртуального метода, не обязан. А класс-потомок может добавить парочку своих, статических. Вот тебе и наследование без полиморфизма - и все тип-топ.


 
Восхищенный   (2008-04-25 15:51) [232]

> Leonid Troyanovsky ©   (25.04.08 15:48) [230]

Динамический действительно компактнее. Но медленнее. Поэтому ты неправ.


 
Восхищенный   (2008-04-25 15:55) [233]

> Leonid Troyanovsky ©   (25.04.08 15:48) [230]

Небольшое уточнение: но медленнее при замещении наследниками (особенно, многократном). Поэтому ты неправ.


 
jack128_   (2008-04-25 15:57) [234]


> А класс-потомок может добавить парочку своих, статических


см [226]


> Что полностью противоречит [211] и о чем говорилось в [213].

ты не находишь, что "вынес изменяемый кусок кода" и "вынес НЕизменяемый кусок кода" - это лингвистические изыски??  

Главное: было X функций -> стало Y функций. При этом - совпадающих участков кода - стало меньше.


 
Leonid Troyanovsky ©   (2008-04-25 15:58) [235]


> Восхищенный   (25.04.08 15:51) [232]

> Динамический действительно компактнее. Но медленнее. Поэтому
> ты неправ.

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

А, во-ще, тут и не стоило даже поминать динамический.
Virtual forever.

--
Regards, LVT.


 
Восхищенный   (2008-04-25 16:06) [236]

> Leonid Troyanovsky ©   (25.04.08 15:58) [235]

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

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

Кстати, они сами своей же рекомендации и следуют. Загляни в VCL - все методы диспетчеризации событий у них динамические. А вот методы, которые наследники наверняка перекроют - все до одного виртуальные.

> jack128_   (25.04.08 15:57) [234]

Спор прекращаю. Извини, но у тебя небольшие проблемы с пониманием сути базовых терминов ООП, поэтому смысла нет.


 
Игорь Шевченко ©   (2008-04-25 16:07) [237]


> Мне лень искать, но была такая рекомендация от борландов,
>  мол,
> чем чаще предполагается замещать метод, тем предпочтительней
> его сделать динамическим, например, для обработки событий.
>


С точностью до наоборот, чем реже, тем больше смысла делать динамическим


 
Leonid Troyanovsky ©   (2008-04-25 16:10) [238]


> ANB   (25.04.08 09:51) [195]

>  что ты пользуешь поля класса, а я - локальные переменные,
>  посему мне надо их нилить, а за тебя это неявно конструктор
> сделает.

В этом и отгадка того, почему обычно не стоит обрамлять вызов
конструктора, бо, в ООП для хранения ссылок на объекты более
естественны поля, а вовсе не локальные переменные.

--
Regards, LVT.


 
Восхищенный   (2008-04-25 16:11) [239]

> Leonid Troyanovsky ©   (25.04.08 15:58) [235]

Тут смысл простой. Если динамический метод не перекрыт, то по скорости он не уступает виртуальному, а по компактности - лучше. То есть, имеет преимущество. Но как только мы начинаем его перекрывать, это преимущество начинает снижаться - и чем больше наследников его перекрыли, тем больше снижение. Поэтому динамический метод хорош как раз тогда, когда вероятность его перекрытия невелика.


 
Leonid Troyanovsky ©   (2008-04-25 16:18) [240]


> Игорь Шевченко ©   (25.04.08 16:07) [237]

> С точностью до наоборот, чем реже, тем больше смысла делать
> динамическим

Путаница между "частыми вызовами" и "частыми перекрытиями".
А про диспетчеризацию  (это ж юзеровские действия) -
time-critical - не критично.

--
Regards, LVT.


 
jack128_   (2008-04-25 16:20) [241]


> Спор прекращаю.

жаль, я хотел узнать, что у меня за
>небольшие проблемы с пониманием сути базовых терминов ООП, поэтому смысла нет.

-)


 
Leonid Troyanovsky ©   (2008-04-25 16:24) [242]


> Восхищенный   (25.04.08 16:11) [239]

>  Поэтому динамический метод хорош как раз тогда, когда вероятность
> его перекрытия невелика.

У метода диспетчеризации вероятность перекрытия весьма ненулевая.
И, вот именно оные рекомендовали к динамическим.

Полистай Конопку и доложи, плиз, а то у меня под рукой нет.

Но, оное обсуждение весьма академично, бо, пользующих ныне
dynamic можно счесть по пальцам одной руки.

--
Regards, LVT.


 
Восхищенный   (2008-04-25 16:37) [243]

> Leonid Troyanovsky ©   (25.04.08 16:24) [242]

> Полистай Конопку и доложи, плиз, а то у меня под рукой нет.

Уговорил. Вечером доложу (сейчас его тоже нет под рукой). С указанием точной цитаты и точного номера страницы. На чем, полагаю, спор и будет завершен.

Только имей в виду следующее. Книгу Конопки я знаю чуть ли не наизусть, поэтому точно помню, что о выборе "virtual vs dynamic" он действительно говорит. И точно помню, что именно он об этом говорит. И точно знаю, что в итоге ты окажешься неправ.

И что тогда, о великий спорщик? Ты публично посыпешь голову пеплом?


 
Leonid Troyanovsky ©   (2008-04-25 16:37) [244]


> Игорь Шевченко ©   (25.04.08 16:07) [237]

> С точностью до наоборот, чем реже, тем больше смысла делать
> динамическим

Был неправ, sorry.

Dynamic methods are useful when a base class declares many overridable methods which are inherited by many descendant classes in an application,
but only occasionally overridden.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2008-04-25 16:42) [245]


> Восхищенный   (25.04.08 16:37) [243]

> И что тогда, о великий спорщик? Ты публично посыпешь голову
> пеплом?

Есть необходимость? :)

Правило простое - для методов диспетчеризации - dynamic.
Остальное - virtual.

Я освободил тебя от перечитывания Конопки ;)

--
Regards, LVT.


 
ANB   (2008-04-25 17:06) [246]


> В этом и отгадка того, почему обычно не стоит обрамлять
> вызов
> конструктора, бо, в ООП для хранения ссылок на объекты более
> естественны поля, а вовсе не локальные переменные.

Я не говорил, что не надо обрамлять. А если отвалится создание третьего объекта (предположим, что нам надо 3 файлстрима, у которых вероятность рэйза не равна нулю), что будет с первыми двумя ? Опять вложенные трай городить ?


 
ANB   (2008-04-25 17:14) [247]

Домой пора.
Вобчем то по поводу объекты  + трай файнелли я уж лучше послушаю Сашу Просторова.
Как то привык доверять его мнению. Сколько раз проверял даже спорные советы - он всегда оказывался прав. А если не знает, как лучше - так и советов не дает.
А тем, кто сомневается в его авторитете :
http://softwarer.ru/certifications.html
Ну и плюс мона зайти на SQL.ru, поближе познакомится.


 
Восхищенный   (2008-04-25 17:14) [248]

> Leonid Troyanovsky ©   (25.04.08 16:42) [245]

> Есть необходимость?

ОК, от посыпания головы пеплом я тебя тоже освобождаю. Такой необходимости действительно нет.

Есть другая неоходимость - поменьше снобизма проявлять. Вот такого, например: "Полистай Конопку и доложи".

Тебе не приходило в голову, что ты тут вовсе не наместник бога? И что тут найдутся люди, которые Delphi и Конопку знают, как минимум не хуже тебя?

Надеюсь, ты это усвоил.


 
Leonid Troyanovsky ©   (2008-04-25 18:26) [249]


> Восхищенный   (25.04.08 17:14) [248]

> Тебе не приходило в голову, что ты тут вовсе не наместник
> бога? И что тут найдутся люди, которые Delphi и Конопку
> знают, как минимум не хуже тебя?

Смотрел, смотрел и не усмотрел никакого снобизма.
Бо, нет у меня ни Конопки, ни Шрайбера, ни других Руссиновичей
под рукой.

Поэтому и попросил.
Ну, а если ломает, то извини, сами уж как нибудь.

--
Regards, LVT.


 
Восхищенный   (2008-04-25 18:30) [250]

> Leonid Troyanovsky ©   (25.04.08 18:26) [249]

Не юли. Все ты прекрасно понял.

"Попросил" он, видите ли. Доложить.

И хватит об этом.


 
Leonid Troyanovsky ©   (2008-04-25 18:37) [251]


> Восхищенный   (25.04.08 18:30) [250]

> "Попросил" он, видите ли. Доложить.

Простите, г-н генерал-майор, засранца.

Говорила ж мама: увидел анонима - отойди.

--
Regards, LVT.


 
Loginov Dmitry ©   (2008-04-25 20:45) [252]

> Дело в том, что вероятность того, что TBitmap или TJPEGImage
> дадут exception в конструкторе - ну практически нулевая.


+1

Даже при стихийном действии скорее погорит все напрочь, чем тут exception возникнет :)

На практике доводилось юзать только один класс, в котором exception в конструкторе возникает (TFileStream). Других щас и не припомню...


 
Anatoly Podgoretsky ©   (2008-04-26 00:57) [253]

> Loginov Dmitry  (25.04.2008 20:45:12)  [252]

Программисты ИБМ тоже так говорили, когда придумывали формат даты для ДОС и БИОС


 
Восхищенный   (2008-04-26 12:01) [254]

1. "Этого не случится никогда, потому что вероятность этого очень мала и потому что в моей практике такого еще ни разу не случалось" - очень распространенный (к сожалению) взгляд дилетантов.

2. Два присваивания подряд:
A := nil;
try
 A := TSomeClass.Create;
 ...
это код дилетанта.

3. Код, в котором пытаются защитить сразу группу ресурсов одним try:
try
 O1 := TSomeClass1.Create;
 O2 := TSomeClass2.Create;
 ...
 ON := TSomeClassN.Create;
 ...
finally
 O1.Free; // Или FreeAndNil
 O2.Free;
 ...
 O3.Free;
end;

тоже код дилетанта.

4. И только вот такой код:
захват_одного_ресурса;
try
 ...
finally
 освобождение_этого_ресурса
end;

это правильный, профессиональный код. И при грамотном структурировании программы глубина вложенности try в одном методе в 99.9% случаев не превышает трех (что вполне нормально и вполне читаемо). В оставшемся 0.1% сколько нужно вложенных try - столько и нужно честно писать, а не халтурить. Но сначала, как совершенно верно заметил Palladin, стоит задуматься - а все ли хорошо в консерватории?

Только так. И всякие иные рассуждения на эту тему есть попытки подвести базу под лень и дилетантизм.


 
Loginov Dmitry ©   (2008-04-26 12:40) [255]

> 2. Два присваивания подряд:
> A := nil;
> try
> A := TSomeClass.Create;
> ...
> это код дилетанта.



> 3. Код, в котором пытаются защитить сразу группу ресурсов
> одним try:
> try
> O1 := TSomeClass1.Create;
> O2 := TSomeClass2.Create;
> ...
> ON := TSomeClassN.Create;
> ...
> finally
> O1.Free; // Или FreeAndNil
> O2.Free;
> ...
> O3.Free;
> end;
> тоже код дилетанта.


Очень жаль, что Delphi и VCL разрабатывают одни дилетанты. Грустно даже... :(


 
Экс-Оригинал   (2008-04-26 20:20) [256]


> Только так. И всякие иные рассуждения на эту тему есть попытки
> подвести базу под лень и дилетантизм.


Это твои личные мысли? Или мысли неких "Классиков"?
На чем основаны твои безапелляционные утверждения?

НАсчет Конопки и снобизма ты молодец, но надо не только чужие утверждения опровергать, но и свои доказывать.

Я поначалу тоже удумал в защите группы ресурсов некоторую неправильность.
Но доказать эту неправильность не смог для себя.

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


 
Экс-Оригинал   (2008-04-26 20:21) [257]


> Восхищенный   (25.04.08 18:30) [250]


PS.

А дискуссию провёл на ++ ;)


 
Восхищенный   (2008-04-26 20:40) [258]

> Экс-Оригинал   (26.04.08 20:20) [256]

Вряд ли я нуждался в комментариях и уж тем более в поощрениях.

Насчет [254] - доказывать я никому ничего не собираюсь. Ты же видишь - [255] было просто проигнорировано (хотя не совсем - улыбнулся).

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

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


 
Пёсик В   (2008-04-26 21:07) [259]


> 2. Два присваивания подряд:A := nil;try  A := TSomeClass.
> Create;  ...это код дилетанта.


Хотелось бы вот насчет этого комментарий услышать.

Первая строка присваивание, а вторая - выполнение функции, и лишь потом присваивание.

Так что это не одинаковые присваивания.


>  Ты же видишь - [255] было просто проигнорировано (хотя
> не совсем - улыбнулся).


Я же не о [255] говорю, а о твоих высказываниях.


> Доказать можно, но слишком долго - это раз.


Ну хотя бы основные мысли, ведь сам сказал -

> Поскольку профи в этом и так не нуждаются, а дилетанты все
> равно не поймут.


Не считаю себя дилетантом, однако мысль твоя мне непонятна.


> Каждый, кто хочет, может просто принять на веру...


С какой стати?


 
Экс-Оригинал   (2008-04-26 21:10) [260]


> Восхищенный   (26.04.08 20:40) [258]


Сорри, пред. пост от меня. Немного дурковал в трёпе.


 
Loginov Dmitry ©   (2008-04-26 22:22) [261]

> Доказать можно, но слишком долго - это раз


Пока доказательств не будет, можно считать, что
а) доказать это нельзя
б) доказывать вам просто лень

Насчет [255]. Я просмотрел исходники VCL для Delphi7 - там сплошь и рядом этот "дилетанский" код. Получается, что все, кто Дельфю разрабатывает - дилетанты. А дилетанты не умеют программировать и не знают Delphi. Приходим к однозначному выводу: разработчики Delphi не знают Delphi! Как вам?


 
Восхищенный   (2008-04-27 00:01) [262]

> Экс-Оригинал

Не надо меня разводить, не выйдет. Я ж тебе сказал, что доказывать я никому ничего не собираюсь. И объяснил, почему (и прав оказался).

Не хочешь принимать на веру - не принимай, никто не заставляет.

> Loginov Dmitry ©   (26.04.08 22:22) [261]

Не ври.


 
Экс-Оригинал   (2008-04-27 00:14) [263]


> Не надо меня разводить, не выйдет.


Еще чего - разводить.


> Не хочешь принимать на веру - не принимай, никто не заставляет.


Ты не мессия.
Не хочешь ничего говорить - не флуди.


 
Восхищенный   (2008-04-27 00:20) [264]

> Экс-Оригинал   (27.04.08 00:14) [263]

Вот именно: не хочешь ничего говорить - не флуди.
Пока ты не появился, разговор шел о Delphi.


 
{RASkov} ©   (2008-04-27 00:21) [265]

> Я просмотрел исходники VCL для Delphi7 - там сплошь и рядом этот "дилетанский" код.

В VCL сплошь и рядом код такого типа:
захват ресурса или создание объекта
try
 действия
finally
 освобождение ресурса или уничтожение объекта
end;


 
Игорь Шевченко ©   (2008-04-27 00:28) [266]

столько известных анонимов развелось - диву даться


 
Loginov Dmitry ©   (2008-04-27 00:42) [267]

> Не ври.


Врать? Зачем мне это?

> В VCL сплошь и рядом код такого типа:
> захват ресурса или создание объекта
> try
> действия
> finally
> освобождение ресурса или уничтожение объекта
> end;


А также там сплошь и рядом код такого типа:

захват ресурса или создание объекта
захват ресурса или создание объекта
try
действия
finally
освобождение ресурса или уничтожение объекта
освобождение ресурса или уничтожение объекта
end;


 
Экс-Оригинал   (2008-04-27 00:44) [268]


> Восхищенный   (27.04.08 00:20) [264]
> > Экс-Оригинал   (27.04.08 00:14) [263]Вот именно: не хочешь
> ничего говорить - не флуди.Пока ты не появился, разговор
> шел о Delphi.


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


 
Восхищенный   (2008-04-27 00:45) [269]


> Loginov Dmitry ©   (27.04.08 00:42) [267]


Снова врешь.


 
Восхищенный   (2008-04-27 00:47) [270]

> Экс-Оригинал   (27.04.08 00:44) [268]

С двух раз тебе тоже непонятно? Тогда ничем не могу помочь.


 
Экс-Оригинал   (2008-04-27 00:47) [271]


> Пока ты не появился, разговор шел о Delphi.


Уж ты точно своими последними высказываниями говоришь о Delphi.


 
Экс-Оригинал   (2008-04-27 00:51) [272]


> Восхищенный   (27.04.08 00:47) [270]
> > Экс-Оригинал   (27.04.08 00:44) [268]С двух раз тебе тоже
> непонятно? Тогда ничем не могу помочь.


Ну что можно сказать на пустой трёп? Только развести руками.

Он, должно быть, очень невежественный человек, поскольку отвечает на все вопросы, которые ему задают. /Франсуа Вольтер/


 
Экс-Оригинал   (2008-04-27 00:52) [273]


> Восхищенный   (27.04.08 00:47) [270]
> > Экс-Оригинал   (27.04.08 00:44) [268]С двух раз тебе тоже
> непонятно? Тогда ничем не могу помочь.


Оставайся уподобившимся некоторым товарищам в упоеньи собственной правотой.


 
Германн ©   (2008-04-27 01:29) [274]


> Игорь Шевченко ©   (27.04.08 00:28) [266]
>
> столько известных анонимов развелось - диву даться
>

Одного из них я уже идентифицировал. Только вот какого именно?
:)))


 
Loginov Dmitry ©   (2008-04-27 09:15) [275]

> Снова врешь.


Ты можешь сам Delphi открыть? Я вот открыл и посмотрел.
А от тебя пока только одни бездоказательные высказывания.


 
Palladin ©   (2008-04-27 09:33) [276]


>Loginov Dmitry ©(27.04.08 09:15) [275]

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


 
Palladin ©   (2008-04-27 09:39) [277]

Удалено модератором
Примечание: Offtopic


 
{RASkov} ©   (2008-04-27 09:46) [278]

Удалено модератором
Примечание: Offtopic


 
{RASkov} ©   (2008-04-27 09:50) [279]

> указать конкретный модуль и либо конкретный класс и метод, либо процедуру

Замечу только то, что в ответ на это не нужно ничего искать по исходникам VCL...
Открывай любой и Ctrl+F вводи finally + Enter и далее F3.... и постоянно поподается [1] схема...


 
{RASkov} ©   (2008-04-27 09:52) [280]

> и постоянно поподается [1] схема...

Ну т.е. в [1] не схема, а уже код.... хорошо, схему я в [265] "зарисовал"...


 
Palladin ©   (2008-04-27 09:58) [281]


>{RASkov} ©(27.04.08 09:50) [279]

да я верю, мне интересно посмотреть на такое как в Loginov Dmitry ©(27.04.08 00:42) [267]


 
{RASkov} ©   (2008-04-27 10:01) [282]

> [281] Palladin ©   (27.04.08 09:58)
> да я верю,

А это и не тебе было :) Сорри)


 
Loginov Dmitry ©   (2008-04-27 10:03) [283]

> тебе доказать свое утверждение очень просто. указать конкретный
> модуль и либо конкретный класс и метод, либо процедуру.


раз это нужно, то с радостью все укажу! (для Delphi7, как было сказано выше)

1) Forms: TCustomForm.Print

FormImage := GetFormImage; // Создание объекта
Canvas.Lock; // захват ресурса
try
  .........
finally
  Canvas.Unlock; // Освобождение ресурса
  FormImage.Free; // Уничтожение объекта
end;


2) Forms: TCustomForm.ShowModal

В одном finally выполняется множество действий

3) Forms: TApplication.MessageBox

Не знаю, как это следует расценивать...


 finally
   if MBMonitor <> AppMonitor then
     SetWindowPos(Handle, 0,
       Rect.Left + ((Rect.Right - Rect.Left) div 2),
       Rect.Top + ((Rect.Bottom - Rect.Top) div 2),
       0, 0, SWP_NOACTIVATE or SWP_NOREDRAW or SWP_NOSIZE or SWP_NOZORDER);
   EnableTaskWindows(WindowList);
   SetActiveWindow(ActiveWindow);
   RestoreFocusState(FocusState);
 end;


4) Classes: TReader.ReadVariant, TWriter.WriteVariant


InnerStream := nil;
OuterStream := TMemoryStream.Create;
try
 InnerStream := TMemoryStream.Create;
 ..................
finally
 InnerStream.Free;
 OuterStream.Free;
end;


5) Graphics: WriteIcon()


MonoInfo := nil;
MonoBits := nil;
ColorInfo := nil;
ColorBits := nil;
try
 MonoInfo := AllocMem(MonoInfoSize);
 MonoBits := AllocMem(MonoBitsSize);
 ColorInfo := AllocMem(ColorInfoSize);
 ColorBits := AllocMem(ColorBitsSize);
 ...........................
finally
 FreeMem(ColorInfo, ColorInfoSize);
 FreeMem(ColorBits, ColorBitsSize);
 FreeMem(MonoInfo, MonoInfoSize);
 FreeMem(MonoBits, MonoBitsSize);
end;


Кстати, в модуле Controls мне не удалось найти ничего подозрительного. Там для каждого ресурса - свой try..finally, видимо, чтобы подобных споров не было ;)

В других модулях не смотрел. Достаточно и того, что я привел.


 
{RASkov} ©   (2008-04-27 10:14) [284]

> [283] Loginov Dmitry ©   (27.04.08 10:03)

А не кажется ли, что нашел иголку? ;) Даже пробежавшись по указаннум модулям >90% схема с одним объектом/ресурсрм...


 
Loginov Dmitry ©   (2008-04-27 10:23) [285]

> А не кажется ли, что нашел иголку?


Это не важно. Важно, что все-таки нашел. А поэтому фраза "Ты врешь" тут совершенно не к месту.


 
Leonid Troyanovsky ©   (2008-04-27 10:28) [286]


> {RASkov} ©   (27.04.08 10:14) [284]

> А не кажется ли, что нашел иголку? ;)

Даже меньше.
Из приведенных примеров лишь 4 бросает тень.
Но, как мы уже знаем, в борланд попадают и двоешники.
Что касается 5, то там надо было объявить структуру,
объединяющую все эти Mono-Color. Т.е., это на троечку.

--
Regards, LVT.


 
{RASkov} ©   (2008-04-27 10:31) [287]

> [285] Loginov Dmitry ©   (27.04.08 10:23)
> А поэтому фраза "Ты врешь" тут совершенно не к месту.

Я думаю, что данная фраза была к твоему "сплошь и рядом"....


 
Leonid Troyanovsky ©   (2008-04-27 10:34) [288]


> Loginov Dmitry ©   (27.04.08 10:23) [285]

> Это не важно. Важно, что все-таки нашел

Мне когда-то даже хотелось создать зал борландовской славы,
но, к сожалению, руки не дошли. А так 4 - вполне достоен.

--
Regards, LVT.


 
Loginov Dmitry ©   (2008-04-27 10:48) [289]

А интересно, следующий код тоже дилетанский?


ADataBase := TDataBase.Create(nil);
AQuery1 := TQuery.Create(ADataBase);
AQuery2 := TQuery.Create(ADataBase);
AQuery3 := TQuery.Create(ADataBase);
try
 ................................
finally
 ADataBase.Free;
end;


 
Palladin ©   (2008-04-27 10:56) [290]

да, причем очень сильно.


 
Palladin ©   (2008-04-27 10:57) [291]

за такое, пожизненный эцих с гвоздями.


 
Loginov Dmitry ©   (2008-04-27 11:04) [292]

> за такое, пожизненный эцих с гвоздями.


а гвозди-то за что? За TQuery? ;)


 
Anatoly Podgoretsky ©   (2008-04-27 11:22) [293]

Потому что это не код, а целенаправленая диверсия.


 
Loginov Dmitry ©   (2008-04-27 11:30) [294]

> Потому что это не код, а целенаправленая диверсия.


Анатолий, объясните Вы хоть, в чем тут заключается диверсия? Почему целенаправленная?
К каким потенциальным проблемам может привести подобный код?


 
Восхищенный   (2008-04-27 11:53) [295]

> Loginov Dmitry ©   (27.04.08 11:30) [294]

Объясняю. Этот код - супердилетантский. Если на 2, 3 или 4 строке возникнет исключение, DataBase повиснет в памяти вместе с теми Query, которые успели создаться.

Типичный пример дилетантского подходе "этого не случится, потому что вероятность этого слишком мала и потому что в моей практике такого не случалось". Профи же, наученные горьким опытом, на "авось" никогда не рассчитывают, даже если вероятность ошибки 10e-6.

Сравни:

ADataBase := TDataBase.Create(nil);
try
 AQuery1 := TQuery.Create(ADataBase);
 AQuery2 := TQuery.Create(ADataBase);
 AQuery3 := TQuery.Create(ADataBase);
 ................................
finally
 ADataBase.Free;
end;

Вроде бы, тот же самый код - но без риска утечки памяти.


 
Anatoly Podgoretsky ©   (2008-04-27 11:57) [296]

> Loginov Dmitry  (27.04.2008 11:30:54)  [294]

К простым, в случае ошибки, теряем от одного до дву Query и сам ADataBase
А вего то переместить try на три строки выше.


 
Loginov Dmitry ©   (2008-04-27 12:09) [297]

> Профи же, наученные горьким опытом, на "авось" никогда не
> рассчитывают, даже если вероятность ошибки 10e-6.


"Профи же, наученные горьким опытом" - такие вообще существуют, или это лишь теория?

Как вообще может произойти ошибка в таких безобидных конструкторах, как
TDataBase.Create, TQuery.Create, TList.Create, TStringList.Create, TMemoryStream.Create
если ее намеренно не спровоцировать?

Таким же макаром и в деструкторе может произойти ошибка, а в случае TDataBase и TQuery ошибка в деструкторе даже более вероятна, чем в конструкторе, тогда опять же есть риск утечки памяти.

10e-6 - очень большая цифра, означающая, что если в цикле миллион раз вызвать данный код, то в одном из конструкторов хотябы 1 раз произойдет AV.


 
Palladin ©   (2008-04-27 12:29) [298]


>Как вообще может произойти ошибка в таких безобидных конструкторах, как
TDataBase.Create, TQuery.Create, TList.Create, TStringList.Create, TMemoryStream.Create

да очень просто, не нужно рассуждать так линейно. например рядом крутящийся поток пишущий в неверную область памяти, программа какого нибудь "кул хацкера" делающая WriteProcessMemory. все это угрожает стабильности приложения.

идеально стабильное - не существует, но приблизить его к идеалу мы можем. чем и занимаемся, грамотно выстраивая try finally и стараясь спасти ситуацию. приложению ведь еще и дальше работать.

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


 
Palladin ©   (2008-04-27 12:35) [299]


>конструктор для нас темная лошадка.

извиняюсь, не договорил,

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


 
{RASkov} ©   (2008-04-27 12:37) [300]

:)
Аринушка наверное в трансе)


 
Anatoly Podgoretsky ©   (2008-04-27 12:52) [301]

> {RASkov}  (27.04.2008 12:37:00)  [300]

В трансе наверно Дмитрий глаза открыли - откуда дети берутся.


 
Loginov Dmitry ©   (2008-04-27 12:54) [302]

> например рядом крутящийся поток пишущий в неверную область
> памяти


Очень часто это приводит к краху программы, и мало вероятности, что try..finally от этого сможет спасти. К чему спасать, если программа дальше не сможет работать корректно? Запись в неверную область памяти - это программная ошибка, которую исправлять надо.


> стараясь спасти ситуацию. приложению ведь еще и дальше работать.


Кратко и убедительно!


> [299] Palladin ©   (27.04.08 12:35)
>
> >конструктор для нас темная лошадка.
>
> извиняюсь, не договорил,
>
> темная лошадка. сегодня он безобидный, завтра преопаснейший.
> и мы имеем огромную кучу проблем и мемликов.


Если сегодя какой-нибудь TList.Create безопасный, а завтра - преопаснейший, то какой толк от всех этих try..finally, если программа работать не сможет? ;) Хотя то, что при этом не будет никаких утечек памяти - это конечно круто!

Хотя в принципе и такое возможно. Действительно, если класс не такой примитивный, как TList (например, тот же TDataBase / TQuery), то еще неизвестно, как конструктор себя поведет, если на компьютере не инсталлирован необходимый для его работы софт, а приложение должно работать в любом случае...

Ладно! Основную идею понял! Убедили! Спасибо!


 
Восхищенный   (2008-04-27 13:06) [303]

> Loginov Dmitry ©   (27.04.08 12:09) [297]

> "Профи же, наученные горьким опытом" - такие вообще существуют

Существуют, и очень много. Здесь они тоже есть, и тоже немало. Ты их тоже видишь, просто пока не понимаешь их действительного уровня.

> Как вообще может произойти ошибка в таких безобидных конструкторах,
> как TDataBase.Create, TQuery.Create, TList.Create, TStringList.Create,
> TMemoryStream.Create если ее намеренно не спровоцировать?

Вот ты сам и привел пример дилетантских рассуждений "этого не случится, потому что вероятность этого слишком мала и потому что в моей практике такого не случалось".

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

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


 
Loginov Dmitry ©   (2008-04-27 13:24) [304]

> В твоем примере любой профи, даже вдрызг пьяный, автоматически
> и не задумываясь написал бы try на 3 строки выше. Автопилот
> срабатывает.


Ну ладно. Опустили Вы меня (и не только :), аж не по себе стало!
Я даже по такому случаю статейку ту перепишу, чтоб не позориться :)


 
Игорь Шевченко ©   (2008-04-27 13:31) [305]


> Я даже по такому случаю статейку ту перепишу, чтоб не позориться
> :)


Не писал бы ты...Зачем нужны клоны трудов Архангельского ?


 
Экс-Оригинал   (2008-04-27 13:54) [306]

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

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

Пока из всего вышесказанного видно, что в некоторых случаях (если не знать внутреннй реализации до тонкостей) конструкция с дополнительным присваиванием может быть неустойчивой к исключениям. но это только лишь В НЕКОТОРЫХ случаях.

Вряд ли стоит индуцировать отдельный пример в закономерность.

Это тоже самое, что сказать - вот в этом случае GOTO плохо. Значит, плохо везде.


 
Экс-Оригинал   (2008-04-27 13:58) [307]


> Loginov Dmitry ©   (27.04.08 13:24) [304]
> Опустили Вы меня (и не только :),
>  аж не по себе стало!Я даже по такому случаю статейку ту
> перепишу, чтоб не позориться :)


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

Правило может действовать в общем случае. В частном же бывает, что можно сделать лучше, нарушая его.
Для этого нужны всего лишь знания.


 
Loginov Dmitry ©   (2008-04-27 14:07) [308]

> Не писал бы ты...Зачем нужны клоны трудов Архангельского
> ?


По хорошему удалить ее следует. Но жалко :(


 
Loginov Dmitry ©   (2008-04-27 14:31) [309]

> Зачем нужны клоны трудов Архангельского


Кстати, Архангельский в одном из источников некорректно описывал спицифику работы с try..finally, а из-за этого я долгое время пренебрегал использованием данного оператора, и извращался с try..except. А статья была написана с целью помочь начинающему в освоении и понимании try..finally, поскольку достаточные объяснения приводятся далеко не каждым автором. Статья свою работу, считаю, делает, так зачем ее удалять? Нужно ее просто доработать с учетом всех накопленных с того момента знаний.


 
Восхищенный   (2008-04-27 14:42) [310]

> Loginov Dmitry ©   (27.04.08 14:31) [309]

> А статья была написана с целью помочь начинающему в освоении и
> понимании try..finally,

И, желая помочь начинающему в понимании try..finally, ты пишешь вот такой страшный пример (кстати, четко показывающий, что ты и сам толком не понимаешь того, о чем пишешь). А этот бедняга начинающий, не в состоянии даже понять, что пример страшный, и думает, что так и надо делать.

Выглядишь ты при этом довольно смешно, но не это главное. Главное вот что - ты понимаешь, что совершаешь почти преступление?


 
Игорь Шевченко ©   (2008-04-27 14:57) [311]

Расстрелять и дело с концом


 
Экс-Оригинал   (2008-04-27 15:39) [312]


> Leonid Troyanovsky ©   (27.04.08 10:28) [286]


По поводу кода 4:
Delphi 6:
 function ReadCustomVariant: Variant;
 var
   OuterStream, InnerStream: TMemoryStream;
   OuterReader: TReader;
   StreamSize: Integer;
   CustomType: TCustomVariantType;
   CustomTypeClassName: string;
   VarStreamer: IVarStreamable;
 begin
   CheckValue(vaBinary);
   OuterStream := TMemoryStream.Create;
   InnerStream := TMemoryStream.Create;
   try
     Read(StreamSize, SizeOf(StreamSize));
     OuterStream.Size := StreamSize;
     Read(OuterStream.Memory^, StreamSize);

     OuterReader := TReader.Create(OuterStream, 1024);
     try
       CustomTypeClassName := OuterReader.ReadString;
       OuterReader.Read(StreamSize, SizeOf(StreamSize));
       InnerStream.Size := StreamSize;
       OuterReader.Read(InnerStream.Memory^, StreamSize);

       if not FindCustomVariantType(CustomTypeClassName, CustomType) or
          not Supports(TObject(CustomType), IVarStreamable, VarStreamer) then
         raise EReadError.CreateRes(@SReadError);
       TVarData(Result).VType := CustomType.VarType;
       VarStreamer.StreamIn(TVarData(Result), InnerStream);
     finally
       OuterReader.Free;
     end;
   finally
     InnerStream.Free;
     OuterStream.Free;
   end;
 end;


BDS2006:

 function ReadCustomVariant: Variant;
 var
   OuterStream, InnerStream: TMemoryStream;
   OuterReader: TReader;
   StreamSize: Integer;
   CustomType: TCustomVariantType;
   CustomTypeClassName: string;
   VarStreamer: IVarStreamable;
 begin
   CheckValue(vaBinary);

   InnerStream := nil;
   OuterStream := TMemoryStream.Create;
   try
     InnerStream := TMemoryStream.Create;

     Read(StreamSize, SizeOf(StreamSize));
     OuterStream.Size := StreamSize;
     Read(OuterStream.Memory^, StreamSize);

     OuterReader := TReader.Create(OuterStream, 1024);
     try
       CustomTypeClassName := OuterReader.ReadString;
       OuterReader.Read(StreamSize, SizeOf(StreamSize));
       InnerStream.Size := StreamSize;
       OuterReader.Read(InnerStream.Memory^, StreamSize);

       if not FindCustomVariantType(CustomTypeClassName, CustomType) or
          not Supports(CustomType, IVarStreamable, VarStreamer) then
         raise EReadError.CreateRes(@SReadError);
       TVarData(Result).VType := CustomType.VarType;
       VarStreamer.StreamIn(TVarData(Result), InnerStream);
     finally
       OuterReader.Free;
     end;
   finally
     InnerStream.Free;
     OuterStream.Free;
   end;
 end;


В первом случае потерян один try..finally - утечка памяти.
Если добавить, код будет менее прозрачным.

Во втором случае всё наглядно.


 
Loginov Dmitry ©   (2008-04-27 23:41) [313]

> И, желая помочь начинающему в понимании try..finally, ты
> пишешь вот такой страшный пример (кстати, четко показывающий,
> что ты и сам толком не понимаешь того, о чем пишешь). А
> этот бедняга начинающий, не в состоянии даже понять, что
> пример страшный, и думает, что так и надо делать.
>
> Выглядишь ты при этом довольно смешно, но не это главное.
> Главное вот что - ты понимаешь, что совершаешь почти преступление?


Признаю все свои ошибки. И по поводу статьи, и по поводу примеров и т.д. и т.п.
Если разобраться, то в VCL (начиная с Delphi7) действительно нет ни одного участка, в котором исключение в конструкторе привело бы к утечке памяти. Видимо, не просто так они там все подправили. Наверно, от них требуют (или требовали) придерживаться существующего стандарта, наказывая за произвол :) Либо же на самом деле вероятность ошибки в конструкторе - ненулевая. Ну так или, VCL как и всегда является примером для подражания :)

Статью переписал (ссылка в [33]). Заменил весь контент, идущий, после перевода хэлпа, на более правдоподобную информацию (в основном копи-пастом из этой ветки :)
Прошу профи оценить правдоподобность изложенного в ней материала. Если по Вашему мнению все правильно, то оставлю как есть, иначе же все что необходимо - исправлю. Главное, чтобы она приносила, как минимум, больше пользы, чем вреда :)


 
Игорь Шевченко ©   (2008-04-28 00:05) [314]

"В секции finally должна выполняться обработка любых возникающих в ней исключений, в противном случае будет невозможно выполнить обработку других исключений. "

- что-то я крайне редко видел код, подобный следующему:

try
 ....
finally
 try
   ...
 except
   ...
 end;
end;

"Не следует использовать уровень вложенности операторов try..finally больше 4-х, т.к. это снижает читабельность кода"

а 4 - это эмпирическая константа или как ?

"Код конструктора выглядит примерно так:

constructor TSomeClass.Create;
begin
 try
  { Ваш код конструктора }
 except
   Destroy;
 end;
end;

"

точнее, так:
 try
  { Ваш код конструктора }
 except
   Destroy;
   raise;
 end;


"Правильно разработанный код деструктора теоретически не должен ни при каких обстоятельствах провоцировать возникновение исключения."

почему не должен - оно просто передастся наверх и вся радость.

"Теоретически исключение может возникнуть при любой операции, требующей выделения участка памяти ненулевой длины. Вызов любого конструктора приводит к выделению памяти, необходимой для хранения полей создаваемого объекта"

не любого.

"Если при выделении памяти функцией AllocMem() произойдет исключение, FreeMem() освободит память только для ненулевых указателей"

что, FreeMem проверяет на nil ?

"In Delphi code, FreeMem destroys the variable referenced by P and returns its memory to the heap. If P does not point to memory in the heap, a runtime error occurs. If P points to a structure that includes long strings, variants, dynamic arrays, or interfaces, call Finalize before calling Freemem .

P is a variable of any pointer type previously assigned by the GetMem procedure.

Size specifies the size in bytes of the dynamic variable to dispose of; if specified, it must be exactly the number of bytes previously allocated to that variable by GetMem .
After calling FreeMem, the value of P is undefined.
Note: It is preferable to use the New and Dispose procedures rather than GetMem and FreeMem. When using New and Dispose , there is no need to explicitly call Finalize ."


Говорил же - не пиши.


 
Anatoly Podgoretsky ©   (2008-04-28 00:21) [315]

> Игорь Шевченко  (28.04.2008 00:05:14)  [314]

"Код конструктора выглядит примерно так:

constructor TSomeClass.Create;
begin
try
 { Ваш код конструктора }
except
  Destroy;
end;
end;

"

точнее, так:
try
 { Ваш код конструктора }
except
  Destroy;
  raise;
end;

-----------

это тоже смущение для неокрепших душ, а вдруг поверят? Тебе же тогда второй приз надо будет выдавать, первый Архангельскому, а вот правильный код

constructor TSomeClass.Create;
begin
  { Ваш код конструктора }
end;

destructor Destroy
begin
  Destroy;
end;


 
Anatoly Podgoretsky ©   (2008-04-28 00:24) [316]

> Anatoly Podgoretsky  (28.04.2008 00:21:15)  [315]

Ах да, для конструктора Destroy не надо делать, Destroy только для созданых в конструкторе или далее в коде объектов, и конечно без какого либо (кроме редких случаеу) Assingned, для необъектов или если рашрушение в коде, но и тогда не стоит, лучше сделать obj := nil


 
Anatoly Podgoretsky ©   (2008-04-28 00:26) [317]

> Anatoly Podgoretsky  (28.04.2008 00:24:16)  [316]

Кстати у тебя есть большое желание писать, но надо подождать (если желание не пройдет), пока уровень мастерства возрастет, а пока только вред наносишь.


 
Игорь Шевченко ©   (2008-04-28 00:29) [318]

Anatoly Podgoretsky ©   (28.04.08 00:21) [315]


> это тоже смущение для неокрепших душ, а вдруг поверят? Тебе
> же тогда второй приз надо будет выдавать, первый Архангельскому


Ага, сознаюсь, повелся.
Это код _ClassCreate выглядит так, с try..except


 
Экс-Оригинал   (2008-04-28 00:47) [319]


> Говорил же - не пиши.


Жалко, что-ли? -(


 
Экс-Оригинал   (2008-04-28 00:49) [320]


> Loginov Dmitry ©   (27.04.08 23:41) [313]


Если ечть желание писать, то обязательно договариваться с рецензентами - пусть читают, потом апрвить, опять на рецензию отдавать...
И только после этого - выкладывать в общество...


 
Игорь Шевченко ©   (2008-04-28 00:54) [321]

Экс-Оригинал   (28.04.08 00:47) [319]

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


 
Германн ©   (2008-04-28 01:41) [322]

Ну да. Вот Коля Карих (и почему меня постоянно тянет написать Рарих :) тоже наверно стремился сеять разумное доброе и вечное. А сколько жертв его стремления?


 
Loginov Dmitry ©   (2008-04-28 08:04) [323]

> "В секции finally должна выполняться обработка любых возникающих
> в ней исключений, в противном случае будет невозможно выполнить
> обработку других исключений. "
>
> - что-то я крайне редко видел код, подобный следующему:
>
> try
> ....
> finally
> try
>   ...
> except
>   ...
> end;
> end;


Не бейте! Это просто перевод хэлпа :)


> точнее, так:
> try
>  { Ваш код конструктора }
> except
>   Destroy;
>   raise;
> end;


Спасибо! raise Пропустил :(


> "Если при выделении памяти функцией AllocMem() произойдет
> исключение, FreeMem() освободит память только для ненулевых
> указателей"
>
> что, FreeMem проверяет на nil ?


Этот код просто взят из VCL. Как я могу его осуждать? Это прихоть разработчиков. Формально FreeMem проверяет на nil, но это - недокументированная фича.


> это тоже смущение для неокрепших душ, а вдруг поверят? Тебе
> же тогда второй приз надо будет выдавать, первый Архангельскому,
> а вот правильный код
>
> constructor TSomeClass.Create;
> begin
>  { Ваш код конструктора }
> end;


В смысле сам вызов конструктора защищен try..except? Ладно, подправим!

> Кстати у тебя есть большое желание писать, но надо подождать
> (если желание не пройдет), пока уровень мастерства возрастет,
> а пока только вред наносишь.


Дык я и не пишу. Всего лишь исправляю давнишнюю статью, чтобы к ней не было нареканий.


 
Anatoly Podgoretsky ©   (2008-04-28 08:41) [324]

> Loginov Dmitry  (28.04.2008 08:04:23)  [323]

Исключение в конструкторе автоматически вызывает деструктор, это документировано в справке.
Не могу обсуждать код вне контекста, может там и правильно.


 
Loginov Dmitry ©   (2008-04-28 09:17) [325]

Судя по ассемблерному коду, до вызова конструктора никакого try..except не вставляется. Поэтому, как ни крути, получается что-то наподобие этого:

> try
>  { Ваш код конструктора }
> except
>   Destroy;
>   raise;
> end;

Проще, наверно, указать, что это всего-лишь псевдокод, а как на самом деле - смотрите asm...


 
Loginov Dmitry ©   (2008-04-28 09:19) [326]

> а 4 - это эмпирическая константа или как ?

Да, эмпирическая. В качестве рекомендации. Считаете, что лучше ее совсем не указывать?


 
Игорь Шевченко ©   (2008-04-28 10:01) [327]

Loginov Dmitry ©   (28.04.08 09:17) [325]


> Судя по ассемблерному коду, до вызова конструктора никакого
> try..except не вставляется


RTFM: System.pas, _ClassCreate

А.П. верно поправил


> Да, эмпирическая. В качестве рекомендации. Считаете, что
> лучше ее совсем не указывать?


Считаю.

Считаю, что луше прислушаться к рекомендациям и не писать вовсе


 
Восхищенный   (2008-04-28 10:44) [328]

http://neogranka.com/forum/showthread.php?t=1461


 
Восхищенный   (2008-04-28 10:53) [329]

"Что изменилось? (прим.: с появлением Интернета).

Правильно. Сеть терпима к объему. Необязательно писать рассказы, необязательно учиться, как в три страницы вместить Человека, Мир и Сюжет. Можно сразу начинать с большой фантастической эпопеи.

Кстати, параллельно с рассказами я тоже писал свои "Кровавые бани". Первые три были полной ерундой. На четвертой произошел какой-то перелом, переход количества в какое ни есть, но качество. И четвертая повесть уже была издана на бумаге.

Но существуй в те годы интернет - могли бы выйти и первые три.

И очень вероятно, что четвертая и пятая повести оставались бы на том же самом уровне".

© Сергей ЛУКЬЯНЕНКО.


 
Leonid Troyanovsky ©   (2008-04-28 11:22) [330]


> Экс-Оригинал   (27.04.08 15:39) [312]

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

--
Regards, LVT.


 
Экс-Оригинал   (2008-04-28 13:59) [331]


> . Если отстаивать последовательно
> объектную модель, то нужно было б создать временный объект,
>

Не всегда нужно плодить сущности ради выполнения кода в единственном месте.


 
Экс-Оригинал   (2008-04-28 14:02) [332]


> Восхищенный   (27.04.08 14:42) [310]
> > Loginov Dmitry ©   (27.04.08 14:31) [309]
>  Главное вот что - ты понимаешь, что совершаешь почти преступление?
>


Бред какой...


 
Leonid Troyanovsky ©   (2008-04-28 14:20) [333]


> Экс-Оригинал   (28.04.08 13:59) [331]

> Не всегда нужно плодить сущности ради выполнения кода в
> единственном месте.

Т.е., лучше скрестить две сущности: объектную и не совсем.

--
Regards, LVT.


 
Экс-Оригинал   (2008-04-28 14:22) [334]


> Т.е., лучше скрестить две сущности: объектную и не совсем.


Иногда да. Синтез плоской и объектной модели бывает более эффективным, а код - читабельным и прозрачным.


 
Leonid Troyanovsky ©   (2008-04-28 14:31) [335]


> Экс-Оригинал   (28.04.08 14:22) [334]

> Иногда да. Синтез плоской и объектной модели бывает более
> эффективным, а код - читабельным и прозрачным.

Чаще встречал обратное :)

Как раз  этом случае - не поля, а неинициалированные локальные
переменные и трудности с контролем времени жизни объектов
и др., ранее здесь обсуждавшееся.

--
Regards, LVT.


 
Игорь Шевченко ©   (2008-04-28 15:07) [336]

Собственно все зависит от программиста, а не от языка :) Можно и в Java и в .Net написать полностью процедурный код, хотя там без классов не обойтись.


 
Palladin ©   (2008-04-28 18:51) [337]

так... пойдем дальше... :)


> ANB   (25.04.08 13:40) [210]

и где"ж ты у меня этот метод то нашел? :) я написал класс-оболочку для работы с "чем то извне", что отвечает за IO. потому что ты привел все 6 объектов для своего "сложного" примера отвечающих за IO. оболочка нам позволила абстрагироватся от конкретных источников/форматов данных. вот ее смысл. + достачно ясная работа с IO в самой процедуре, всегда по одной строчке, по одному вызову метода, видно, что же происходит, это называется написание самодокументируемого кода.

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


> ANB   (25.04.08 14:44) [214]
> Да я как то не прусь от ООП.

вот с этого и надо было начинать, если не знать как готовить кошек, то они и нафик не нужны, эт точно....

только, ты наверное не поверишь, но без ООА и ООП действительно сложную программу, не ту "сложную" программу в которой есть процедура работающая аж с 6ю объектами IO (ужос!), а сложную, динамически развивающуюся, с гибко построенной структурой, способной реагировать на большинство внешних изменений, реализовать практически не возможно...


> Экс-Оригинал   (28.04.08 14:02) [332]
>
> > Восхищенный   (27.04.08 14:42) [310]
> > > Loginov Dmitry ©   (27.04.08 14:31) [309]
> >  Главное вот что - ты понимаешь, что совершаешь почти
> преступление?
> >
>
> Бред какой...

Тебе не понять... ты не преподавал...

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

по поводу "неплодите сущностей без необходимости" - эта фраза, которую любят цитировать некоторые товарищи, совершенно верна в случае

TPoint=Class
Public
 X,Y:Integer;
End;

(ну или чуть посложнее record взять :) )

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

грубо говоря фраза "неплодите сущностей без необходимости" относится к скелету/каркасу проекта. всегда нужно взвешивать некоторую зарождающуюся, в голове проектировщика, сущность на предмет сколько она может совершить действий (влияние на другие сущности) и сколько над ней можно совершить действий (влияние другие сущностей),  + на сколько может быть изменчива сущность, можно ли взять и абстрагировать некоторые ее положения и тем самым применить к бОльшему количеству реальных объектов, именно так решается ее (сущности)судьба :)

короче сложная это штука... проектирование...


 
Loginov Dmitry ©   (2008-04-28 22:07) [338]

Вопрос созрел следующий. Дан код:


InnerStream := nil;
OuterStream := TMemoryStream.Create;
try
 InnerStream := TMemoryStream.Create;
 ......................  
finally
 InnerStream.Free;
 OuterStream.Free;
end;


С одной стороны имеется недостаток: 2 присвоения одному объекту.
С другой стороны, если добавить еще один try..finally, то:
 1-увеличивается число строк исходного кода
 2-увеличивается объем скомпилированного кода и, как следствие, размер файла
 3-падает производительность.
Надежность кода лишний try..finally не увеличивает, но дает следующие плюсы:
 1-увеличивается читабельность кода (правда, на приведенном коде трудно судить об этом)
 2-уменьшается число присваиваний

получается 3 vs 2!
Эдакое соревнование ;)
Так почему же код, выигравший в данном "соревновании" считается дилетанским? )


 
Loginov Dmitry ©   (2008-04-28 22:40) [339]

Кстати, вновь подправил статью, учтя ВСЕ замечания, присутствующие в данной ветке.

Сейчас статья мне самому стала нравиться (а это кстати - главное :) Если что-то получается неправильно, или что-то где-то не доконца продумано, то подсознательно это всегда чувствуется (ощущается какая-то незавершенность). А сейчас чувствуется, что работа сделана не менее, чем на "хор" (я на это надеюсь, но проверять не мне, а Вам ;)


 
Anatoly Podgoretsky ©   (2008-04-28 22:46) [340]

> Loginov Dmitry  (28.04.2008 22:07:38)  [338]

А ты сравни два кода


OuterStream := TMemoryStream.Create;
try
  InnerStream := TMemoryStream.Create;
  try
    ......................  
  finally
    InnerStream.Free;
  end;
finally
  OuterStream.Free;
end;


По читабельности, а строк всего на две строки больше.
А аргументы могут иметь значение только на данном коде, но если добавить сюда вместо точек, что-то, то их значимость стремится к нулю.


 
{RASkov} ©   (2008-04-28 22:54) [341]

> [339] Loginov Dmitry ©   (28.04.08 22:40)
> Кстати, вновь подправил статью

Вот какой-нибудь читатель, который вообще не в курсе проиходящего, читал твою статью, потом "другую".... потом "третью".... Подумает: "Автор определиться не может, не буду я ему верить" :) Шутка....)


 
Loginov Dmitry ©   (2008-04-28 23:06) [342]

> Вот какой-нибудь читатель, который вообще не в курсе проиходящего,
> читал твою статью, потом "другую".... потом "третью"


то он ПСИХ!

Шутка))


 
Loginov Dmitry ©   (2008-04-28 23:11) [343]

> А аргументы могут иметь значение только на данном коде,
> но если добавить сюда вместо точек, что-то, то их значимость
> стремится к нулю.


Ну тогда правильнее 2й называть "предпочтительным", а первый - "менее предпочтительным", но не так же резко: "дилетанский"!!


 
Восхищенный   (2008-04-28 23:39) [344]

> Loginov Dmitry ©   (28.04.08 23:11) [343]

"Mенее предпочтительный" - это осетрина второй свежести.


 
Loginov Dmitry ©   (2008-04-28 23:53) [345]

> "Mенее предпочтительный" - это осетрина второй свежести.


Ну и ассоциации!... )


 
Palladin ©   (2008-04-29 00:11) [346]


> Loginov Dmitry [343]

Еще раз повторю за Восхищенным. (гы... лучше с ним не связываейтесь... :) )

все отличное от схемы


взятие ресурса
try
работа с ресурсом
finally
отказ от ресурса
end


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


1. а предахранися мы от освобождения ресурса которого мы не взяли, но так что бы при его освобождении не вылезло АВ
2. взяли основной защищаемый ресурс
3.try
4. попытались взять ресурс, который мы типа предохранили, а если не получится, то хаха, все равно Ав не будет... бебебе, я ANB, мне мона, я "классику" читаю
5. работа
...
N finally
N+1 по барАбану, я предохранился, возьму и освобожу может взятый, а может и не взятый ресурс...
N+2 отдали основной защищенный ресурс
N+3 End;


так вот, в чем проблемма такого подхода, есть такое понятие "времени использования ресурса"
дилетантство "классики" заключается в том что эта "классика" скрывает от программиста истинный временной отрезок использования объекта в коде. структура программы, увы далеко не вечна, однажды совпадающие временные отрезки жизни двух объектов, могут разойтись и тогда прийдется ломать данную двойную структуру защищения, если этого не делать то это угоражает потери наглядности кода при дальнейшем его развитии... дилетанство заключается в том что никто не задумывается, а что же будет дальше то? а дальше мы будем бегать по одному большому блоку между try и finally в поисках, а когда же мля у нас объект использоваться начинает то!! а какой где, а куда тот, а этот откуда, зачем у меня столько присваиваний в Nil то??? а?? господи, чем я раньше то думал???... одним словом, проблемы с рефакторингом :)

Второй момент, так называемые "безопасные" конструкторы. Я уже про это рассказывал. Но чет никто из поклонников "классики" не проникся. Берем, млин, шаг №2 и предпологаем, что под губительным внешним воздействием жестоко калечится шаг 1. где было предохранение от осовобождение ресурса, причем так калечит (например в память неверное значение записывается) и все на нет, и тут сразу вдруг попытка взять "типа защищенный ресурс номер два" дает сбой, по причине губительного воздействия, да такой что попытка в finally его освобождения жестоко выносит приложение за пределы видимой вселенной... вероятность такого, конечно, очень мала... так проблемма то в том что как бы нибыла она мала, но она ЕСТЬ!.. когда же вы это поймете наконец то... и у нас есть реальные шансы спастись и остаться в области наблюдаемой галактики вместо провала в другое измерение...

вот по этим причинам ни ANB, ни жексон(гуруделфи.гуглепагес.ру) с таким подходом и не напишут ни одной серьезной программы... кроме "сложнейших" процедур с 5-6 объектами (о ужос!)... да и с ними в трясине повязнут со временем...

господи, ну если вы такие избегатели каскадов из try finally, то пишите тогда так


o1:=TObject1.Create; Try
o2:=TObject2.Create; Try
o3:=TObject3.Create; Try
o4:=TObject4.Create; Try
o5:=TObject5.Create; Try
o6:=TObject6.Create; Try
o7:=TObject7.Create; Try
и нету никаких ненавистных каскадов... одна трясина из кода процедуры, в которой вы потом увязните по уши :)
Finally o7.Free; End;
Finally o6.Free; End;
Finally o5.Free; End;
Finally o4.Free; End;
Finally o3.Free; End;
Finally o2.Free; End;
Finally o1.Free; End;


ps. на все комментарии/вопросы/замечания/наезды отвечу уже завтра...


 
Восхищенный   (2008-04-29 01:08) [347]

> Palladin ©   (29.04.08 00:11) [346]

Я восхищен(ный).
:о)

Только... жаль, но ведь все равно не поймут. Кто может понять, тот уже и сам давно все понял и в объяснениях не нуждается, а кто еще не дозрел (шишек еще достаточно не набил) - тот один хрен не поймет. Увы.

Есть, правда, еще одна категория - дальшесвоегоносаневидящие. Люди вполне профессиональные, но недопонимающие, что это за конфа, почему в ней далеко не всегда следует говорить о нюансах и почему в ней бывает гораздо полезнее сказать - делай так и никак иначе.

Жди, Тимур. Щас тебе начнут объяснять, что мир неплоский. Ты ведь об этом не догадывался, правда?


 
Германн ©   (2008-04-29 01:40) [348]


> Жди, Тимур. Щас тебе начнут объяснять, что мир неплоский.

А он предупредил заранее, что отвечать будет завтра. :)
И понятно почему предупредил :)

Ну и главное. Сия ветка уже давно переросла из конкретного обсуждения в весьма расплывчатое словоблудие. Да. Это словоблудие по теме ветки, но всё равно словоблудие.

P.S. То что мир не плоский все давно знают. Это не вопрос. Вопрос в том что мир не круглый :)


 
Восхищенный   (2008-04-29 01:56) [349]

> Германн ©   (29.04.08 01:40) [348]

> Это словоблудие по теме ветки, но всё равно словоблудие.

А why бы и not? Раз по теме - значит, не оффтоп. Правила не нарушены.

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

После коего перерастания становится уже можно и статьи писать.
:о)

PS
Я не пьян. И с крышей тоже все в порядке.
:о)


 
Германн ©   (2008-04-29 02:15) [350]


> Восхищенный   (29.04.08 01:56) [349]
>
> > Германн ©   (29.04.08 01:40) [348]
>
> > Это словоблудие по теме ветки, но всё равно словоблудие.
>
>
> А why бы и not? Раз по теме - значит, не оффтоп. Правила
> не нарушены.
>
> Только не словоблудие это, вот в чем фокус. Это та самая
> грань, где кончается простое ремесленничество и начинается
> искусство. Где знания уже перерастают в интуицию, в чутье,
>  в автопилот, а из них - в красоту и надежность кода, в
> его читабельность, гибкость, развиваемость и поддерживаемость.
>
>
> После коего перерастания становится уже можно и статьи писать.
>
> :о)
>
> PS
> Я не пьян. И с крышей тоже все в порядке.
> :о)
>

Всё равно это словоблудие! Но словоблудие словоблюдию рознь. Какое-то размышление над каким-то вопросом действительно могут помочь перейти ту самую "грань".

А я и не подозревал тебя в пьянстве. Но уже подозреваю, кто ты есть.
Очень много знакомого. :)


 
Германн ©   (2008-04-29 02:43) [351]


> А я и не подозревал тебя в пьянстве. Но уже подозреваю,
> кто ты есть.
> Очень много знакомого. :)
>

Может летом, в июле или августе, смогу выбраться на ММП.


 
Loginov Dmitry ©   (2008-04-29 07:55) [352]

> Только... жаль, но ведь все равно не поймут. Кто может понять,
> тот уже и сам давно все понял и в объяснениях не нуждается,
> а кто еще не дозрел (шишек еще достаточно не набил) - тот
> один хрен не поймет. Увы.


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

Теперь о главном: можно ли статью оставить в том виде, в котором она есть сейчас? )


 
ANB   (2008-04-29 09:44) [353]


> для своего "сложного" примера отвечающих за IO

Да. Это была самая сложная задача в моей программерской жизни. И решал я ее целых 15 минут.


 
ANB   (2008-04-29 09:46) [354]


> А ты сравни два кода
>
>
> OuterStream := TMemoryStream.Create;
> try
>   InnerStream := TMemoryStream.Create;
>   try
>     ......................  
>   finally
>     InnerStream.Free;
>   end;
> finally
>   OuterStream.Free;
> end;
>
>
> По читабельности, а строк всего на две строки больше.
> А аргументы могут иметь значение только на данном коде,
> но если добавить сюда вместо точек, что-то, то их значимость
> стремится к нулю.

По читабельности - намного хуже варианта Димы и моего.
Чем меньше в процедуре вложений, тем лучше.


 
ANB   (2008-04-29 09:53) [355]

Сравниваем :
Palladin ©   (28.04.08 18:51) [337]
и
Palladin ©   (29.04.08 00:11) [346]

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

Вот где дилетантство.


 
Игорь Шевченко ©   (2008-04-29 10:19) [356]

Не удержусь, чтобы не процитировать:

"ОО-языки упрощают абстракцию, возможно, даже слишком ее упрощают. Они поддерживают создание структур с большим количеством связующего кода и сложными уровнями.
Это может оказаться полезным в случае, если предметная область является
действительно сложной и требует множества абстракций, и вместе с тем такой подход может обернуться неприятностями, если программисты реализуют простые вещи сложными способами, просто потому что им известны эти способы и они умеют ими пользоваться.
Все ОО-языки несколько склонны "втягивать" программистов в ловушку избыточной иерархии. Чрезмерное количество уровней разрушает прозрачность: крайне затрудняется их просмотр и анализ ментальной модели, которую по существу реализует код. Всецело нарушаются правила простоты, ясности и прозрачности, а в результате код наполняется скрытыми ошибкми и создает постоянные проблемы при сопровождении.
Данная тенденция, вероятно, усугубляется тем, что множество курсов по
программированию преподают громоздкую иерархию как способ удовлетворения правила представления. С этой точки зрения множество классов приравнивается к внедрению знаний в данные. Проблема данного подхода заключается в том, что слишком часто "развитые данные" в связующих уровнях фактически не относятся у какому-либо естественному объекту в области действия программы - они предназначены только для связующего уровня.
Одной из причин того, что ОО-языки преуспели в большинстве характерных для них предметных областей (GUI-интерфейсы, моделирование, графические средства), возможно, является то, что в этих областях относительно трудно неправильно определить онтологию типов. Например, в GUI-интерфейсах и графических средствах присутствует довольно естественное соотвествие между манипулируемыми визуальными объектами и классами. Если выясняется, что создается большое количество классов, которые не имеют очевидного соответствия с тем, что
происходит на экране, то, соотвественно, легко заметить, что связующий уровень стал слишком большим."

(с) Эрик Рэймонд, "Искусство программирования для Unix"


 
ANB   (2008-04-29 11:42) [357]


> Игорь Шевченко ©   (29.04.08 10:19) [356]

+1


 
Восхищенный   (2008-04-29 12:14) [358]

> ANB   (29.04.08 09:53) [355]

Вынесение внутреннего try в отдельный метод каскада try не отменяет. И не затем оно делается, а по соображениям структурирования кода.


 
Восхищенный   (2008-04-29 12:15) [359]

> не отменяет.

Добавление: и не устраняет.


 
Восхищенный   (2008-04-29 12:23) [360]

И пояснение (специально для дальшесвоегоносаневидящих).

То есть - код, конечно, структурируется исходя не из какого-то там стремления разнести try, а совсем из других соображений (функционал, гибкость, читабельность и пр.). И каждый блок try пишется там, где он нужен. А уж какая у него при этом получится вложенность, в одном методе или в нескольких - это вопрос вторичный и непринципиальный, в общем-то.


 
ANB   (2008-04-29 12:31) [361]


> Вынесение внутреннего try в отдельный метод каскада try
> не отменяет.

O1 := TO.Create;
try
O2 := TO.Create;
try
O3 := TO.Create;
try
O4 := TO.Create;
try
...
finally
O1.Free;
finally
O2.Free;
finally
O3.Free;
finally
O4.Free;

и

ProcCreate
begin
 O1 := TO.Create;
 O2 := TO.Create;
 O3 := TO.Create;
 O4 := TO.Create;
end;

ProcFree
begin
 O1.Free;
 O2.Free;
 O3.Free;
 O4.Free;
end;

ProcMain
begin
 ProcCreate;
 try
 ...
 finally
   ProcFree;
 end;
end;

- По моему это совершенно разные подходы.
Причем второй подход будет корректен только если O1..O4 - поля класса.
И каскада во втором случае ну никак не будет.


 
Восхищенный   (2008-04-29 12:35) [362]

> По моему это совершенно разные подходы.

По-моему, тоже. Второй - неверный в обоих вариантах. И не об этом шла речь.


 
ANB   (2008-04-29 12:38) [363]


> (функционал, гибкость, читабельность и пр.).

+ учет критических для скорости работы приложения мест.
Экономить такты в куске кода, через который выполнение пройдет один раз в сутки смысла нету. А вот кусок кода, который будет выполнен в цикле пару миллионов раз надо вылизывать до безобразия. Лишний вызов метода вместо линейного алгоритма - это потеря времени.

Что быстрее : X := Y;, если X - локальная переменная в случаях :
1) Y - переменная (локальная или глобальная)
2) Y - функция, возвращающая значение глобальной переменной
3) Y - поле класса
4) Y - метод класса
5) Y - свойство класса с сеттером и геттером.
?


 
ANB   (2008-04-29 12:46) [364]


> И не об этом шла речь.

Разве ?

Мой оппонент заявил, что для повышения читабельности кода при каскадном трай файнелли он вынесет создание и уничтожение объектов в отдельные методы.
Получил второй вариант.
При этом продолжает утверждать, что каскады - это эталлон.


 
Восхищенный   (2008-04-29 13:10) [365]

Вынужден повториться.

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

1. > Что быстрее

Очевидно, "и пр." включает в себя все неупомянутое - и скорость критичных участков тоже.

2. > Мой оппонент заявил, что для повышения читабельности кода при
   >  каскадном трай файнелли он вынесет создание и уничтожение
   > объектов в отдельные методы.

Ни на секунду не сомневаюсь, что он никогда не стал бы плодить методы ради лишь одной читабельности. Равно как и ради только разнесения try.

Вынужден попросить перечитать [360] внимательно.


 
ANB   (2008-04-29 13:53) [366]


> Вынужден попросить перечитать [360] внимательно.

Смотрим : Palladin ©   (24.04.08 17:50) [192]. И код, в нем приведенный.


 
Восхищенный   (2008-04-29 15:49) [367]

> ANB   (29.04.08 13:53) [366]

Я видел. И что?


 
ANB   (2008-04-29 15:53) [368]


> Я видел. И что?

Чем отличается от моего второго варианта ?


 
Восхищенный   (2008-04-29 16:07) [369]

> ANB   (29.04.08 15:53) [368]

> Чем отличается от моего второго варианта ?

Тем, что ProcFree не вызовется автоматически при исключении в ProcCreate. А деструктор при исключении в конструкторе - вызовется.

В результате получаем, что в [192] код безопасный (в смысле мемликов), а в ProcMain - опасный. Вот чем отличается.


 
ANB   (2008-04-29 16:20) [370]


> В результате получаем, что в [192] код безопасный (в смысле
> мемликов), а в ProcMain - опасный. Вот чем отличается.

Вот зануда.

ProcCreate
begin
try
O1 := TO.Create;
O2 := TO.Create;
O3 := TO.Create;
O4 := TO.Create;
except
 ProcFree;
end;
end;

ProcFree
begin
O1.Free;
O2.Free;
O3.Free;
O4.Free;
end;

ProcMain
begin
ProcCreate;
try
...
finally
  ProcFree;
end;
end;

Так логика совпадает ?

Дык где тут каскадные трай файнелли ?


 
Восхищенный   (2008-04-29 16:24) [371]

> Так логика совпадает ?

Нет. Не хватает инициализации переменных.


 
ANB   (2008-04-29 16:38) [372]


> Нет. Не хватает инициализации переменных.

Это не переменные, а поля объекта. А процедуры - его методы. Можно даже переименовать их в конструктор и деструктор и выбросить трай-эксцепт.

От этого появятся каскады трай-файнелли ?


 
Восхищенный   (2008-04-29 17:01) [373]

> ANB   (29.04.08 16:38) [372]

Конечно не появятся. И что?

То, что Борланд придумал и использовал эту схему для автоматической и неявной обработки исключений в конструкторе? Так и правильно сделал, потому что и нет другого варианта для общего решения проблемы обработки исключений в любом написанном юзером конструкторе. Заранее же неизвестно, что это будет за конструктор, что в нем юзер понапишет и поназахватывает - вот поэтому Борланд так и сделал. Схема неэффективная (из-за двойной инициализация полей), но другого общего (независимого от кода конструктора) решения просто нет.

Но у нас-то - другой вариант. Мы-то, в отличие от Борланда всегда точно знаем, что и где мы поназахватывали, что и где надо освобождать. Поэтому и имеем возможность, которой у Борланда не было - строить лестницы (явные или неявные).


 
Palladin ©   (2008-04-29 17:15) [374]


> Игорь Шевченко ©   (29.04.08 10:19) [356]

А я знал, что ты не удержишься, в общем"то последние абзацы [337] именно тебе и посвящались...


> ANB   (29.04.08 09:53) [355]

Ну то есть по существу сказать"то оказывается и нечего. Начинаем придираться. Да без проблем, хоть до потери сознания :) ...

В [337] я высказывал соображения по поводу того каким должно быть идеальное построение приложения, но не бывает идеала на свете, не бывает абсолютно черного и абсолютно белого, к тому и сказал что все мы люди, а не божественные существа.

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

Однако, халтурить, без знания чем это может грозить, - непозволительно. автор "классики" именно это и делает, он показывает как нужно халтурить, вот только чем это грозит он не рассказывает. А вот плохо это...

В [346] я заполнил этот пробел автора "классики", вот только к сожалению читатели "классика" не увидят этих строк

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

Кстати по предпоследнему предложению я не совсем осознал, где я чего вынес... в [337] ни капли кода, ну разве что рекорд в класс преобразованный :) так что если можно поподробней или исправься если ошибся...

Дальнейшее комментировать не буду, бо уже пошли юления... по поводу структуры без обращения на смысл конструкции... странные попытки доказать, что [192] это вред...

Как верно заметил, ээ, не буду расскрывать инкогнито :), Восхищенный, я не просто взял и куда то там чего то перенес, я построил новое видение решения. Чего ты пытаешься доказать я не понимаю...

Хотя все же прокомментирую одну высказанную тобою вещь в ANB   (29.04.08 12:38) [363]. Ты знаешь, где то в "детстве", во времена 486 и TP/BP7, я решил написать одну весчь, два прямоугольника катались по экрану управляемые клавишами, и не просто катались, а могли еще вертется по осям. То бишь, что то по типу 3D, вычитал просто где то про матрицы поворота. Написал я ее в тогдашнем своем стиле, процедурного программирования. То бишь создания иерархий вызовов процедур, то что ты сейчас пропагандируешь. Потом подумал и смотрю передо мной два объекта, думаю, а чего бы все это дело в объекты (Object) не оформить, прикольно получится наверное. Ну взял и оформил, жутко коряво конечно, я тогда только только к ООП приходил, все было в зачаточном состоянии. Но результат меня поразил. Exe файл стал гораздо меньше, код поразительно ясен и самое для тебя интересное, работать стало ощутимо быстрей, как я уже позже разобрался за счет именно уменьшения количества вызовов, механизм перекрытия методов сработал. Не стало кучи сравнений, ветвлений.

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

И еще, самое интересное, что то решение в [192] например, поможет нам здорово ускорить работу, за счет ввода механизмов кеширования в объекте IO, причем основная процедура останется нетронутой... да и еще много чего позволит, если грамотно подойти к этому вопросу....


 
Игорь Шевченко ©   (2008-04-29 17:34) [375]

Palladin ©   (29.04.08 17:15) [374]


> А я знал, что ты не удержишься, в общем"то последние абзацы
> [337] именно тебе и посвящались...


Я собственно против догматизма :)


 
ANB   (2008-04-29 17:42) [376]


> Palladin ©   (29.04.08 17:15) [374]

1. По поводу придирок.
Ты одновременно защищаешь 2 противоположные позиции : каскадные трай-файнелли (кстати, классик не против них совсем, если ты внимательно читал статью, он призывает сокращать количество каскадов, причем безопасным способом) и фактически позицию классика (то, что ты перенес создание и уничтожение нужных объектов в конструктор и деструктор сути не меняет. Более того - классик предупреждает о существовании небезопасных деструкторов и что на них тоже надо обратить внимание).
2. По поводу ООП. Я тут недавно разгребал код, писанный в 90-е. Авторы построили очень стройную систему классов, спроецировали все это на БД и все было бы клево. Пока не началась модификация. Проблема в том, что писано все было на обжект паскале, соответственно без РТТИ. И в конкретном месте кода оооочень тяжко понять - метод из какого модуля таки вызывается. Сейчас лезть в эти недра вообще не рискует никто, а авторов давно уже нету.
ИМХА : ООП не панацея. Все новомодные фичи есть смысл применять, если они сокращают код, повышают его читабельность.

> что то решение в [192] например

Нетронутость основной процедуры - не бог весть какое преимущество. К тому же в процессе отладки и сопровождения она скорее всего и будет меняться чаще всего.

ЗЫ. Применение классов вместо процедур ускорения не даст. Если же дало - процедуры были очень халтурно написаны. При этом никто не мешает таки использовать классы в уместных случаях (как в последнем посте ИШ).
ЗЫЫ. Детство было, похоже, недавно. Во времена юности я работал не на 486, а на ЕС-1045 и ЕС-1035 под ОС ЕС и СВМ. :)


 
Игорь Шевченко ©   (2008-04-29 17:47) [377]


> Во времена юности я работал не на 486, а на ЕС-1045 и ЕС-
> 1035 под ОС ЕС и СВМ. :)


Коллега. Я еще на 1022 успел поработать. Куда никакой VM (СВМ) не встанет :)


 
ANB   (2008-04-29 17:47) [378]


> строить лестницы (явные или неявные).

Про неявные лестницы мона поподробнее ?


 
ANB   (2008-04-29 17:53) [379]


> Игорь Шевченко ©   (29.04.08 17:47) [377]

Дык знаю, что коллега. Я 1020 тока видел. И помогал выносить на утилизацию. Печатная машинка, ридер, ацпу. И все ботало. ОС ЕС МФТ.

А уж чего тока не стояло у нас на 1045 : Сначала МФТ, потом МВТ, потом СВС. И коллективки : джек, фокус, примус. Мне больше всего ред понравился, но его не развернули, т.к. были проблемы с организацией безопасного доступа, а дописать ее так и не успели.
Зато крякнули СВМ через команды диагностики.
Год успел поковыряться с 1066. во зубряра. Работают 60 человек - и как один за компом . . .


 
Игорь Шевченко ©   (2008-04-29 17:59) [380]

ANB   (29.04.08 17:53) [379]

примус таки ностальгия. И без всякого ООП написан, хотя очень и очень грамотно.

от фокуса осталось воспоминание пункта "ввод текста с рукописи". И пароль "винтовка".


 
Восхищенный   (2008-04-29 18:04) [381]

> ANB   (29.04.08 17:47) [378]

> Про неявные лестницы мона поподробнее?

Нет проблем.

proc1
try
 ...
finally
 ...
end;

proc2
try
 proc1;
 ...
finally
 ...
end;

В proc2 имеем лестницу, которую я обозвал неявной.


 
ANB   (2008-04-29 18:18) [382]


> Восхищенный   (29.04.08 18:04) [381]

И сколько процедур придется писать, если объектов 6 ?


> Игорь Шевченко ©   (29.04.08 17:59) [380]

Не, ред еще на порядок круче был :
1) совсем не тормозил (практически мновенная реакция)
2) никогда не глючил
3) НЕ БЛОКИРОВАЛ консоль, т.е. прямо поверх него мона было запускать свои приложения, использующие эту же консоль. Примусу же надо было сказать, чтобы он ее освободил, а потом хапнул обратно.


 
Восхищенный   (2008-04-29 19:14) [383]

> ANB   (29.04.08 18:18) [382]

> И сколько процедур придется писать, если объектов 6?

Блин. Писал [360], надеясь, что будет не только прочтено, но и осмыслено. Потом в явном виде просил перечитать [360] внимательно. И снова-здорова... чукча не читатель?

Так. Еще раз (блин, какой я терпеливый, однако!).
:о)

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

Если при этом получаются еще и неявные лестницы (при вызовах процедур ) - и пусть себе.


 
Palladin ©   (2008-04-29 19:52) [384]

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

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


 
Игорь Шевченко ©   (2008-04-29 21:51) [385]

Palladin ©   (29.04.08 19:52) [384]

Писание не зависит от объектов и классов, неужели так трудно понять ? Сами по себе ни объекты ни классы не являются серебряной пулей, охотно верю, что когда они появились, их объявили панацеей в плане борьбы со сложностью, но не сложилось у них бороться со сложностью. Ну вот - объявили, а не сложилось. Бывает. Наоборот, в многих случаях они свою сложность привносят. Хороший модульный код на простом С может дать 100 очков плохому ООП-коду, с классами, паттернами и прочими связующими слоями ради самих слоев.


 
Anatoly Podgoretsky ©   (2008-04-29 23:05) [386]

> Игорь Шевченко  (29.04.2008 21:51:25)  [385]

Да получилось, но и получилось как обычно, раньше нельзя было сложно, а как только стало можно, так сразу и накрутили и стало хуже.
Это же очень наглядно на играх наблюдалось, наращивается мощность компьютера, что бы было быстро, тут же пишутся новые игры и опять медленно и так по нарастающей, тоже и с размерами игры, одна дискета, много дискет, один СД диск - много, один ДВД и уже опять много ДВД.
Один к одному и с програмированием.


 
Игорь Шевченко ©   (2008-04-29 23:31) [387]

Anatoly Podgoretsky ©   (29.04.08 23:05) [386]

Онтогенез повторяет филогенез :)


 
Anatoly Podgoretsky ©   (2008-04-29 23:40) [388]

> Игорь Шевченко  (29.04.2008 23:31:27)  [387]

Ты не ругайся, а то в словарь полезу.


 
Германн ©   (2008-04-30 00:15) [389]


> Anatoly Podgoretsky ©   (29.04.08 23:40) [388]
>
> > Игорь Шевченко  (29.04.2008 23:31:27)  [387]
>
> Ты не ругайся, а то в словарь полезу.
>

Чё тут в словарь то лезть:
"Хотели как лучше, а получилось как всегда" (с)


 
Palladin ©   (2008-04-30 03:50) [390]


>Игорь Шевченко ©(29.04.08 21:51) [385]


>Писание не зависит от объектов и классов, неужели так трудно понять ?

вообщето я это ни разу не опроверг и более того писание не зависит и от процедур и функций.


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

так речь то я веду совсем не о том, что давайте применять ооп в каждой дырке. во-первых я показал anb какое преимущество оно иногда может принести при чем в ответ например призванный показать мне, что ох как много может быть локальных идентификаторов. anb конечно этого не увидел. ну хоть другие увидят.

и второй момент я все таки привел аргументы против обниления идентификаторов и свалки их в один большой try.

и чем занимается anb? а фик его знает... пространственными измышлениями об ооп. в ответ на мои слова, что ни один серьезный продукт без ооа не реализовать.

и придирками к решению 192, и попытками доказать что можно также сделать и процедурами, говорящими лишь о том что нифика невкурено решение

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


 
Palladin ©   (2008-04-30 09:31) [391]


> ANB   (29.04.08 17:42) [376]

я защищаю

> каскадные трай-файнелли (кстати, классик не против них совсем,
>  если ты внимательно читал статью, он призывает сокращать
> количество каскадов, причем безопасным способом)

да я их защищаю, и что с того?


> (то, что ты перенес создание
> и уничтожение нужных объектов в конструктор и деструктор
> сути не меняет. Более того - классик предупреждает о существовании
> небезопасных деструкторов и что на них тоже надо обратить
> внимание).

ну и о чем речь? если ты считаешь, что я только перенес фнукционал try/finally в конструктор/деструктор, то о чем вообще с тобой разговаривать? я тебе всю ветку талдычу, что не просто перенес, не убрал каскад из try/finally, я не преследовал эту цель, убрать каскад:

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

2. я оставил задел на будущее, я абстрагировал работу с внешними данными, и потом позже, вместо того что бы лазить по процедуре вверх и вниз, когда начальство вдруг решило перейти на XML например, а не plain-text, изменить методы класса...

ну что толку с тобой разговаривать, когда ты не хочешь ничего понимать/признавать, уперся просто и все...

Восхищенный все это уже озвучил, и что это грозит нормальной поддержкой кода в будущем (он самодокументирован) и развитием (нет трясины рутинного кода между работы с IO и собственно самой разработкой)
но ты упорно все это игнорируешь...

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

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

На SQL ру знакомится с ним я не пойду, зачем мне это надо? Я не буду нести разумное, доброе вечное как Юрий... он тоже на vr-online сходил, но там одни чукчи, не хочу такого же негатива на свой адрес с sql.ru, хотя люди там конечно грамотные, но чувство стада сыграть вполе сможет...

И третий момент, интересно, вот пойду я наберу кучу сертификатов, на целых два например больше чем у автора, напишу кучу статей, на целых две больше чем у автора, причем в одной из статей укажу: массовое обниление - зло, и докажу это. И вот интересно станешь ты меня классиком сразу считать или нет.... :)


 
ANB   (2008-04-30 10:19) [392]

> что не просто перенес, не убрал каскад из try/finally, я
> не преследовал эту цель, убрать каскад

Изначально дискуссия шла : каскадный трай вс один трай с обнилением.
Приведя пример разделения кода по методам ты, не собираясь этого делать, фактически грохнул каскад. И перешел в мой лагерь :) Но по прежнему пытаешься доказать, что каскад лучше.


> 1. избавил процедуру обработки информации от ненужных 6
> локальных объектов, что бы она выглядела как можно проще
> и что бы в ней была только работа по обработке информации,
>  избавил ее от рутины, и сама обработка информации стала
> намного наглядней выглядеть.
>
> 2. я оставил задел на будущее, я абстрагировал работу с
> внешними данными, и потом позже, вместо того что бы лазить
> по процедуре вверх и вниз, когда начальство вдруг решило
> перейти на XML например, а не plain-text, изменить методы
> класса...


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


> И третий момент, интересно, вот пойду я наберу кучу сертификатов,
>  на целых два например больше чем у автора, напишу кучу
> статей, на целых две больше чем у автора, причем в одной
> из статей укажу: массовое обниление - зло, и докажу это.
>  И вот интересно станешь ты меня классиком сразу считать
> или нет.... :)

Не, не буду считать. Т.к. у классика, кроме сертификатов, имеется целая куча больших и толстых внедренных объектов. И ООП он знает и применяет. (частенько из-за этого мы спорили, т.к. мне его без дела применять лениво).
Главный принцип Саши (я его раньше не понимал, а терь полностью поддерживаю) "Писать быстро - значит писать правильно". Причем утверждение верно в обе стороны.

На закуску про ООП : на чем написана винда и никсы ?
Из опыта : как только разработчики начинают увлекаться проектированием классов по делу и без, там где мона обойтись процедурным подходом, так проект с вероятностью 90% заваливают. А там, где пишут опытные процедурники, как правило проект внедряется.


 
Игорь Шевченко ©   (2008-04-30 10:20) [393]

Palladin ©   (30.04.08 03:50) [390]


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


А не трудно привести примеры серьезных продуктов, реализованных с помощью ООП ?

Про серьезные продукты, реализованные без ООП я могу говорить довольно долго - это Windows, Unix, Linux, Oracle. Продукты более чем серьезные, строк кода там за миллионы.


 
ANB   (2008-04-30 10:20) [394]


> внедренных объектов

внедренных проектов


 
Восхищенный   (2008-04-30 10:56) [395]

Странный спор: ООП vs ПП (процедурное программирование).

Очевидно же, что у каждого подхода есть свои сильные и слабые стороны. Значит, вопрос надо ставить так: ООП + ПП. А не "vs".


 
ANB   (2008-04-30 11:01) [396]


> Странный спор: ООП vs ПП (процедурное программирование).

А он и не такой. Он такой :

ООП по делу и без дела вс ПП, когда оно удобнее. :)


 
Восхищенный   (2008-04-30 11:03) [397]

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


 
Игорь Шевченко ©   (2008-04-30 11:07) [398]

Восхищенный   (30.04.08 11:03) [397]

Windows это не окна. Я скажу более - и во внутренностях Windows есть "зачатки ООП-подхода" - есть диспетчер объектов, есть базовые свойства типа объекта и т.д.
Но никакой реализацией с использованием ООП в Windows (а это более чем большая система) и не пахнет - ни наследования, ни полиморфизма, одна только инкапсуляция и та сделана искусственно.


 
Восхищенный   (2008-04-30 11:21) [399]

> Игорь Шевченко ©   (30.04.08 11:07) [398]

Ядро Windows - это не окна. Но и ядро - это еще не вся Windows. А вся Windows - это и окна тоже. Нужен же какой-то UI.

Даже консольные приложения - и те в окне работают. Даже у сервисов предусмотрено взаимодействие с рабочим столом.


 
Игорь Шевченко ©   (2008-04-30 11:27) [400]

Восхищенный   (30.04.08 11:21) [399]

Мы немножко в сторону отошли. Мне все-таки хотелось бы увидеть пример серьезной системы написанной с использованием ООП.

Ну кроме Delphi, разумеется :)


 
Palladin ©   (2008-04-30 11:32) [401]


> Игорь Шевченко ©   (30.04.08 10:20) [393]

Извиняюсь. Позволь мне конкретизировать, то что я имею в виду, под серьезным приложением. Я имею ввиду пользовательское приложение прикладного уровня. С тенденцией развития.

По поводу Windows. С точки зрения программиста из чего состоит ядро Windows? из набора трех dll, конечно там и не пахнет ООП, а зачем оно там? так же Windows состоит из мяса написанного самим же MS, вот тут то ООП и используется (али я не прав?). Windows это не какое то конкретное приложение - это целый набор из ядра и приложений-саттелитов.

Linux - ну тут мне сказать нечего...

Oracle - не верю (С) Станиславский, та же ситуация с Windows, в ядре, конечно и ни капли ООП, но, Игорь, там в инструменталке, Orcale Forms, основной используемый инструмент Jawa :) о чем ты...

В общем категорию приложений где ООП более чем уместно я определил.

Дальше к ANB:

> Изначально дискуссия шла : каскадный трай вс один трай с
> обнилением.
> Приведя пример разделения кода по методам ты, не собираясь
> этого делать, фактически грохнул каскад. И перешел в мой
> лагерь :) Но по прежнему пытаешься доказать, что каскад
> лучше.

Ага, только гроханье каскада - это побочный приятный эффект. Если ты внимательно прочитал [86] то наверное заметил бы, мою фразу о том, что если у нас столько много объектов, то следует задуматся, а нельзя ли сделать попроще. И вот если ты вдруг все еще не понял, то [192] это ответ на твой пример, и ответ на вопрос "а нельзя ли сделать попроще?". Всегда есть какой то процент, когда действительно нельзя, просто пример ты привел, в котором очень даже можно.


> Да она еще сложнее стала для понимания и сопровождения.

хм... ну что я могу сказать, это твое "ИМХО" вот только ты забыл это добавить. переубеждать тебя не буду. Форматы меняют, да еще так быстро, что надо было сделать вчера. Просто ты с этим не сталкивался.


> Классический пример, когда ООП только затрудняет понимание
> и сопровождение.

Опять "классический"... а "ИМХО" опять ты случайно не забыл добавить?


> ANB   (30.04.08 11:01) [396]
> ООП по делу и без дела

где? где у меня это утверждение? где я всех склоняю к ООП? ты прочитал, что я Игорю ответил? неа... ну и ладно...


 
Palladin ©   (2008-04-30 11:35) [402]


> Игорь Шевченко ©   (30.04.08 11:27) [400]

Все еще хочешь? :) Даже с учетом выделения конкретной категории приложений в [401] ? :)


 
Восхищенный   (2008-04-30 11:38) [403]

> Игорь Шевченко ©   (30.04.08 11:27) [400]

Это вопрос не ко мне (в силу [395]).

А вообще, системы, которые ты считаешь серьезными ("Windows, Unix, Linux, Oracle"), во-первых, зарождались еще до бурного развития ООП (и писались, соответственно, на ПП); во-вторых, подобного рода системы вряд ли вообще на ООП пишутся (в силу повышенных требований по памяти и скорости).

ООП - это, видимо, в большей степени инструмент для прикладной разработки. Ну, и для разработки инструментов для прикладной разработки (всяческие IDE и т.п.).


 
Игорь Шевченко ©   (2008-04-30 11:53) [404]

Восхищенный   (30.04.08 11:38) [403]

Я могу объяснить, почему я их такими считаю - потому чтоООП изначально декларировалось как панацея от сложности программ. Так вот, программы, которые я привел, они достаточно сложные, как по объему кода, так и по функциональности.


> во-вторых, подобного рода системы вряд ли вообще на ООП
> пишутся (в силу повышенных требований по памяти и скорости).
>


Каким боком ООП относится к памяти и скорости ?

Проводник виндовый написан без всякого ООП - какие тут нафиг повышенные требования ?

Palladin ©   (30.04.08 11:32) [401]


> Позволь мне конкретизировать, то что я имею в виду, под
> серьезным приложением. Я имею ввиду пользовательское приложение
> прикладного уровня. С тенденцией развития.


Что, ООП - оно только для прикладных задач ? :)
Я так считал что это парадигма программирования вообще...


> По поводу Windows. С точки зрения программиста из чего состоит
> ядро Windows? из набора трех dll


Ну зачем ерунду-то говорить ? :) причем тут точка зрения программиста ?
Как ты понимаешь, и DLL гораздо больше, и набор трех DLL не Windows вовсе.


> Oracle - не верю (С) Станиславский


А эт ты зря не веришь. Никакого там ООП в ядре нет - чистый C


 
ANB   (2008-04-30 11:55) [405]


> Форматы меняют, да еще так быстро, что надо было сделать
> вчера. Просто ты с этим не сталкивался.

Сталкивался. При этом нужно чтобы некоторое время поддерживались оба. "Нерезко" != "нечасто"
При этом частенько изменение формата приводить к полному изменению алгоритма обработки.


> Ага, только гроханье каскада - это побочный приятный эффект.
>  Если ты внимательно прочитал [86] то наверное заметил бы,
>  мою фразу о том, что если у нас столько много объектов,
>  то следует задуматся, а нельзя ли сделать попроще. И вот
> если ты вдруг все еще не понял, то [192] это ответ на твой
> пример, и ответ на вопрос "а нельзя ли сделать попроще?".
>  Всегда есть какой то процент, когда действительно нельзя,
>  просто пример ты привел, в котором очень даже можно.

То что ты сделал, это не "попроще".
Попроще (и быстрее) делается так :
выкидывается нафиг весь код, в процедуре создается один объект, с помощью которого файл закидывается клобом в хранимку и уже на сервере парсится и обрабатывается.
Затем из аут параметров сохраняем логи.
А прикрутить ООП - это в данном случае еще больше все усложнить.
С XML же в случае больших объемов вообще придется ВСЕ переделывать и это нетривиально. Во всяком случае, приведенный пример разделения никак этому не поможет.

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


 
ANB   (2008-04-30 11:56) [406]


> Никакого там ООП в ядре нет - чистый C

А то, что в оракле написали с помощью явы - настолько неудобно, что этим никто не хочет пользоваться.


 
Игорь Шевченко ©   (2008-04-30 12:00) [407]

ANB   (30.04.08 11:56) [406]


> А то, что в оракле написали с помощью явы - настолько неудобно,
>  что этим никто не хочет пользоваться.


Эт ты неправду говоришь


 
Palladin ©   (2008-04-30 12:00) [408]


> Игорь Шевченко ©   (30.04.08 11:53) [404]



> Ну зачем ерунду-то говорить ? :) причем тут точка зрения
> программиста ?
> Как ты понимаешь, и DLL гораздо больше, и набор трех DLL
> не Windows вовсе.

ну тут ты прав конечно, это я слишком уж утрировал...


> Что, ООП - оно только для прикладных задач ? :)
> Я так считал что это парадигма программирования вообще..

И представляешь! :) Я тоже думаю что это парадигма! Но ты демагогией занимаешься. Я утверждаю "серьезному прикладному приложению без ООА/ООП не выжить", а ты мне вопросом "Что, ООП - оно только для прикладных задач ?"... ты либо не понял либо меня хочешь запутать...


> А эт ты зря не веришь. Никакого там ООП в ядре нет - чистый
> C

Ага, а дальше-то, дочитать фразу после Станиславского таки не судьба? :)


 
Palladin ©   (2008-04-30 12:03) [409]


> ANB   (30.04.08 11:55) [405]

Извини, но я больше ничего нового для тебя сказать не могу... Останемся при своих мнениях...


> и начало использования рекомендаций Саши Просторова, против
> которых ты и выступал.

Я не выступал против вообще всех его рекомендаций, я выступал против конкретного массового обниления.


 
Восхищенный   (2008-04-30 12:04) [410]

> Игорь Шевченко ©   (30.04.08 11:53) [404]

> Каким боком ООП относится к памяти и скорости?

Таким, что реализация парадигмы ООП связана с накладными расходами (VMT и пр.) - а они приводят к дополнительным затратам памяти и снижению скорости.


 
Anatoly Podgoretsky ©   (2008-04-30 12:16) [411]

> Palladin  (30.04.2008 09:31:31)  [391]

Какой ты классик, ты Монстр


 
Anatoly Podgoretsky ©   (2008-04-30 12:17) [412]

> ANB  (30.04.2008 10:19:32)  [392]

> на чем написана винда

Думаю там страшная солянка, усугубленная долгой историей и гигантизмом.


 
Игорь Шевченко ©   (2008-04-30 12:18) [413]

Palladin ©   (30.04.08 12:00) [408]


> И представляешь! :) Я тоже думаю что это парадигма! Но ты
> демагогией занимаешься. Я утверждаю "серьезному прикладному
> приложению без ООА/ООП не выжить", а ты мне вопросом "Что,
>  ООП - оно только для прикладных задач ?"... ты либо не
> понял либо меня хочешь запутать...


Я действительно не понял. Вот скажем, компилятор - оно ведь достаточно серьезное приложение ? Для реализации компилятора можно применить и тот и другой подход, более того, они, эти подходы, достаточно успешно применяются, не скажу, что в равной степени, но я видел и тот и другой подход при реализации.
Вот скажем, система управления базами данных - тоже вроде серьезное приложение. Опять же, может быть реализовано и с помощью одного и с помощью другого подхода. Опять же, есть и такая и такая реализация. Из ООП-реализаций навскидку вспомню Postgress
А вот СУБД Oracle реализована без него.

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


 
Anatoly Podgoretsky ©   (2008-04-30 12:18) [414]

> Восхищенный  (30.04.2008 10:56:35)  [395]

Вопрос надо ставить про пчел, остальное чепуха.


 
ANB   (2008-04-30 12:27) [415]


> я выступал против конкретного массового обниления

И применил его в своем примере :)
От того, что обниление за тебя сделал конструктор, ничего не поменялось.
Ну чего юлить то ? Я попросил пример разделения с сохранением каскада.
Ты дал якобы его.
При этом код не упростил.


> > А то, что в оракле написали с помощью явы - настолько
> неудобно,
> >  что этим никто не хочет пользоваться.
>
>
> Эт ты неправду говоришь

Правду. Скока с народом общался, которые с формсами работают - все вопят, что жутко неудобно.
Я ж не грю, что НЕ пользуются. Я грю, что не хотят. Мыши продолжают есть кактус.


 
Anatoly Podgoretsky ©   (2008-04-30 12:27) [416]

> Palladin  (30.04.2008 11:32:41)  [401]

> Linux - ну тут мне сказать нечего...

За Линукс я могу сказать, если в Виндоус падает штатное или постороннее приложение, это Виндоус виноват - кривой. А в Линуксе - не линукс не виноват, линукс мол это только ядро, а к остальному Линукс отношения не имеет. А примеры как вешается тоже ядро и при том намертво тщательно игнорируются.
Поэтому что либо говорить об Линуксе не имеет смысла.


 
Ega23 ©   (2008-04-30 12:31) [417]

<OFFTOP>
фигасе, сколько постов...
Не надоело?
</OFFTOP>

Теперь по делу: господа модераторы!
А не взять ли эту ветку, почистить ненужный флуд, и выложить её в FAQ? Или чем-то вроде статьи оформить? Полезной информации здесь - более чем...


 
Игорь Шевченко ©   (2008-04-30 12:36) [418]

ANB   (30.04.08 12:27) [415]

Смени народ :)
У моего народа противоположное мнение


 
Palladin ©   (2008-04-30 12:38) [419]


> Игорь Шевченко ©   (30.04.08 12:18) [413]

Ну я не считаю, что компилятор это прикладное приложение, это больше приложение-инструмент.


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

Верю. Мне кажется, что применяются они в разных ситуациях, зависит от самого компилируемого языка.


> Вот скажем, система управления базами данных - тоже вроде
> серьезное приложение.

Да, но я не считаю его приложением, я считаю его комплексом из модулей/приложений. Уровня ядра и прикладного уровня. В некоторых СУБД вообще нет никакого прикладного уровня, есть только ядро. Так что смотря, что рассматривать.


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

И представляешь, я с ними согласен! Полностью! :)
Извиняюсь еще раз за не понятки в определениях. Давай конкретизируем теперь понятие "Серьезное", что я имел ввиду под серьезным приложением.

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

Да и вообще я конечно неоднозначный термин подобрал...


 
Palladin ©   (2008-04-30 12:40) [420]


> Игорь Шевченко ©   (30.04.08 12:36) [418]

ANB ярый противник ООП, он не видит очевидного, спорить безполезно.


 
Игорь Шевченко ©   (2008-04-30 12:44) [421]

Palladin ©   (30.04.08 12:38) [419]


> Да и вообще я конечно неоднозначный термин подобрал...



> проектировщик пятой точкой чувствует


почему - вполне однозначный :)
Я с тобой не спорю вообще, я просто к тому, что и каждый подход сам по себе и их совокупность имеют право на существование при разработке приложений. И что именно применять, зависит в первую очередь от предметной области.


 
{RASkov} ©   (2008-04-30 12:45) [422]

> Теперь по делу: господа модераторы!
> А не взять ли эту ветку, почистить ненужный флуд....

Делать им больше нечего :)
Тут пару-тройку постов можно оставить, а остольное это перекладывание с места на место)
А вообще мне интересны такие "могучие" ветки....
:о)


 
Palladin ©   (2008-04-30 12:52) [423]


> Игорь Шевченко ©   (30.04.08 12:44) [421]


> что и каждый подход сам по себе и их совокупность имеют
> право на существование при разработке приложений. И что
> именно применять, зависит в первую очередь от предметной
> области.

вот это точно, так и есть... совершенно согласен...


 
Palladin ©   (2008-04-30 13:00) [424]

Мне не приложения стоило бы назвать серьезными, а предметную область...


 
ANB   (2008-04-30 13:36) [425]


> ANB ярый противник ООП, он не видит очевидного, спорить
> безполезно.

ANB ярый противник бестолкового применения ООП.

АБС - серьезное прикладное приложение ?


 
ANB   (2008-04-30 13:36) [426]

А бухгалтерия (торговля + склад для малого предприятия) ?


 
ANB   (2008-04-30 13:42) [427]


> Смени народ :)
> У моего народа противоположное мнение

Тормозит, жуткий интерфейс. Даже с 1С удобнее работать. Как юзеру.


 
ANB   (2008-04-30 13:43) [428]


> Palladin ©   (30.04.08 12:40) [420]

Вы работали с OEBS ?


 
Anatoly Podgoretsky ©   (2008-04-30 15:33) [429]

> Ega23  (30.04.2008 12:31:57)  [417]

Это не задача модераторов, модератор может только поудалять.
А с вопросами публикации к Максиму, только предварительно составь статью для публикации.


 
Anatoly Podgoretsky ©   (2008-04-30 15:38) [430]

> Anatoly Podgoretsky  (30.04.2008 15:33:09)  [429]

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


 
Palladin ©   (2008-05-01 00:36) [431]


> ANB ярый противник бестолкового применения ООП

И я ярый противник бестолкового применения ООП. И я ярый противник безсмысленного обращения к ПП, когда есть более чем смысленное решение ООП.


 
ANB   (2008-05-04 10:26) [432]


>  И я ярый противник безсмысленного обращения к ПП, когда
> есть более чем смысленное решение ООП

Такого не бывает практически никогда.

Единственная область, где ООП имеет практически подавляющее преимущество - моделирование и рисование (которое тоже, в принципе, моделирование). Собственно, с него ООП и начиналось.

Во всех остальных задачах ПП и ООП практически либо равны по трудоемкости реализации, либо ПП имеет преимущество. Причем, по скорости, выполнения ПП имеет преимущество почти всегда.


 
Жуков Олег   (2008-05-04 10:50) [433]

Любая прикладная программа - моделирование части реального мира


 
oxffff ©   (2008-05-04 12:09) [434]


> ANB   (04.05.08 10:26) [432]
>
> >  И я ярый противник безсмысленного обращения к ПП, когда
>
> > есть более чем смысленное решение ООП
>
> Такого не бывает практически никогда.
>
> Единственная область, где ООП имеет практически подавляющее
> преимущество - моделирование и рисование (которое тоже,
> в принципе, моделирование). Собственно, с него ООП и начиналось.
>
>
> Во всех остальных задачах ПП и ООП практически либо равны
> по трудоемкости реализации, либо ПП имеет преимущество.
> Причем, по скорости, выполнения ПП имеет преимущество почти
> всегда.


ПП это что полупрограммирование?


 
Anatoly Podgoretsky ©   (2008-05-04 13:31) [435]


> Во всех остальных задачах ПП и ООП практически либо равны
> по трудоемкости реализации, либо ПП имеет преимущество.
> Причем, по скорости, выполнения ПП имеет преимущество почти
> всегда.

Только давай уж сравнивать сравнимое, я посмотрю сколько времени у тебя уйдет на реализацию, того, что тебе дается уже в готовом виде, с обработкой исключений, очередей сообщений, форм, аналогов компонент с обработкой событий, ошибок,  и т.д. и т.п. Или ты будешь делать все в WinAPI или работать в консоли? Не забудем и про базы данных и графику.
Вот тогда и поговорим.

А так все можно сделать и с помощью АСМ, и если хорошо поработать, разработав приличную библиотеку макросов, то в дальнейшем создание приложений, в совокупности с внешним редактором ресурсов будет занимать примерно тоже время или даже быстрее.


 
Palladin ©   (2008-05-04 14:01) [436]


> ANB   (04.05.08 10:26) [432]
> Единственная область, где ООП имеет практически подавляющее
> преимущество - моделирование

Моделирование чего?


 
ANB   (2008-05-04 14:50) [437]


> Только давай уж сравнивать сравнимое, я посмотрю сколько
> времени у тебя уйдет на реализацию, того, что тебе дается
> уже в готовом виде, с обработкой исключений, очередей сообщений,
>  форм, аналогов компонент с обработкой событий, ошибок,
>  и т.д. и т.п. Или ты будешь делать все в WinAPI или работать
> в консоли? Не забудем и про базы данных и графику.
> Вот тогда и поговорим.

Использование готовых классов - это не ООП, а фактически процедурное программирование.
ЗЫ. Чего бы их не пользовать, если они уже написаны.


 
ANB   (2008-05-04 15:00) [438]

Есть предложение.
Решаем задачу тем способом, который больше нравится, затем сравниваем время, потраченное на решение и объем кода.
Рискнем доверять друг другу, т.е. поверим времени на слово. (в конце концов не корову разыгрываем).

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

<?xml version="1.0" encoding="windows-1251" ?>
 <requests>
   <request request_type="101" sum="15.45"/>
   <request request_type="102" sum="15.45"/>
   <request request_type="104" sum="16.45"/>
   <request request_type="101" sum="11.45"/>
   <request request_type="101" sum="15.45"/>
   <request request_type="101" sum="15.45"/>
   <request request_type="101" sum="15.45"/>
   <request request_type="102" sum="15.45"/>
   <request request_type="101" sum="15.45"/>
   <request request_type="101" sum="15.45"/>
   <request request_type="103" sum="15.45"/>
   <request request_type="101" sum="14.45"/>
   <request request_type="105" sum="15.45"/>
   <request request_type="101" sum="15.45"/>
   <request request_type="101" sum="11.45"/>
   <request request_type="106" sum="15.45"/>
   <request request_type="101" sum="12.45"/>
   <request request_type="101" sum="15.45"/>
   <request request_type="101" sum="15.45"/>
   <request request_type="107" sum="15.45"/>
   <request request_type="101" sum="15.45"/>
   <request request_type="102" sum="18.45"/>
   <request request_type="103" sum="15.45"/>
   <request request_type="101" sum="15.45"/>
 </requests>

Считаем, что более 5 тысяч элементов не будет.
Нужно - быстренько посчитать, сколько элементов какого типа и на какую сумму содержится в этом XML. Уточняю : группировка по request_type.

Приступаем ?


 
Palladin ©   (2008-05-04 15:04) [439]

ок... приступил...


 
ANB   (2008-05-04 15:13) [440]

Мой ответ :

with X as
(
select
"<?xml version="1.0" encoding="windows-1251" ?>
 <requests>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="102" request_sum="15.45"/>
   <request request_type="104" request_sum="16.45"/>
   <request request_type="101" request_sum="11.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="102" request_sum="15.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="103" request_sum="15.45"/>
   <request request_type="101" request_sum="14.45"/>
   <request request_type="105" request_sum="15.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="101" request_sum="11.45"/>
   <request request_type="106" request_sum="15.45"/>
   <request request_type="101" request_sum="12.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="107" request_sum="15.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="102" request_sum="18.45"/>
   <request request_type="103" request_sum="15.45"/>
   <request request_type="101" request_sum="15.45"/>
 </requests>
"
XMLValue
from dual
)
select
request_type
,count(*) request_count
,sum(request_sum) request_count
from
(
select
 extractvalue (value (XMLValue), "/request@request_type") request_type
,to_number(extractvalue (value (XMLValue), "/request@request_sum"),"999999999999.9999") request_sum
from
table
(
  xmlsequence
  (
   xmltype((
   select
    XMLValue
   from
    X
    )).extract ("/requests/request")
  )
) XMLValue
)
group by
 request_type
-- Начал 15:02
-- Закончил 15:12


Зазвиняюсь за задержку - начальник отвлек. Время честное.


 
ANB   (2008-05-04 15:15) [441]

Да. Реальное решение будет еще проще, т.к. я заранее перегоню клоб в переменную.


 
ANB   (2008-05-04 15:18) [442]

Для тех, у кого нету оракла ответ :

   REQUEST_TYPE REQUEST_COUNT REQUEST_COUNT
1 101 15 219.75
2 102 3 49.35
3 103 2 30.9
4 104 1 16.45
5 105 1 15.45
6 106 1 15.45
7 107 1 15.45


 
ANB   (2008-05-04 15:19) [443]

Ой. Накосячил чуток.
Код :

with X as
(
select
"<?xml version="1.0" encoding="windows-1251" ?>
 <requests>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="102" request_sum="15.45"/>
   <request request_type="104" request_sum="16.45"/>
   <request request_type="101" request_sum="11.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="102" request_sum="15.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="103" request_sum="15.45"/>
   <request request_type="101" request_sum="14.45"/>
   <request request_type="105" request_sum="15.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="101" request_sum="11.45"/>
   <request request_type="106" request_sum="15.45"/>
   <request request_type="101" request_sum="12.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="107" request_sum="15.45"/>
   <request request_type="101" request_sum="15.45"/>
   <request request_type="102" request_sum="18.45"/>
   <request request_type="103" request_sum="15.45"/>
   <request request_type="101" request_sum="15.45"/>
 </requests>
"
XMLValue
from dual
)
select
request_type
,count(*) request_count
,sum(request_sum) request_sum
from
(
select
 extractvalue (value (XMLValue), "/request@request_type") request_type
,to_number(extractvalue (value (XMLValue), "/request@request_sum"),"999999999999.9999") request_sum
from
table
(
  xmlsequence
  (
   xmltype((
   select
    XMLValue
   from
    X
    )).extract ("/requests/request")
  )
) XMLValue
)
group by
 request_type

Ответ :
   REQUEST_TYPE REQUEST_COUNT REQUEST_SUM
1 101 15 219.75
2 102 3 49.35
3 103 2 30.9
4 104 1 16.45
5 105 1 15.45
6 106 1 15.45
7 107 1 15.45

Мона засчитать, что закончил в 15:19.


 
Palladin ©   (2008-05-04 15:25) [444]

procedure TForm1.Button1Click(Sender: TObject);
Type
PRec=^TRec;
TRec=Record
 Count:Integer;
 Sum:Currency;
End;

Var
theSource:TWRXMLElements;
theReqs:TWRXMLElements;
theResults:TWRIntegerMap;

nType:Integer;
fSum:Currency;

n,i:Integer;

Function _NewElement:PRec;
Begin
 New(Result);
 Result.Count:=0;
 Result.Sum:=0;
End;

begin
theResults:=TWRIntegerMap.Create;
Try
 theSource:=CreateWRXMLFromFile("c:\test.xml");
 Try
 
  If theSource.Count=2 Then theReqs:=theSource[1].Elements.ByName["request"] Else
  If theSource.Count=1 Then theReqs:=theSource[0].Elements.ByName["request"] Else Exit;
  If theReqs=Nil Then Exit;

  For i:=0 to theReqs.Count-1 Do
   Begin
    nType:=theReqs[i].AsInt["request_type"];
    fSum:=theReqs[i].AsCur["sum"];

    If Not theResults.Find(nType,n) Then theResults.Add_Integer(nType,Integer(_NewElement),n);
    Inc(PRec(theResults.IntegerData[n]).Count);
    With PRec(theResults.IntegerData[n])^ Do Sum:=Sum+fSum;
   End;

  For i:=0 to theResults.Count-1 Do
   With PRec(theResults.IntegerData[i])^ Do
    Memo1.Lines.Add("Type:"+IntToStr(theResults[i])+", Count:"+IntToStr(Count)+", Sum:"+CurrToStr(Sum));
   
 Finally
  theSource.Free;
 End;
Finally
 For i:=0 to theResults.Count-1 Do
  Dispose(PRec(theResults.IntegerData[i]));
 theResults.Free;
End;
end;


жду вопросов и претензий


 
Palladin ©   (2008-05-04 15:27) [445]

о как... мы оказывается не о делфи...


 
ANB   (2008-05-04 15:42) [446]


> о как... мы оказывается не о делфи...

1. Где было про делфи ?
2. Время больше моего
3. Код у меня явно короче
4. В Д7 у меня не компиляется (ругается на неизвестный тип WRXMLElements)
Что надо прикрутить в юзес ?


 
ANB   (2008-05-04 15:45) [447]

Претензии :
1. А где ООП то ?
2. По собственно коду претензий особо нету.
Но : For i:=0 to theResults.Count-1 Do
 Dispose(PRec(theResults.IntegerData[i])); меня слегка смущает. Это действительно безопасно ?


 
Palladin ©   (2008-05-04 15:56) [448]


> ANB   (04.05.08 15:45) [447]



> 1. А где ООП то ?

Везде, я оперирую тремя объектами.


> Но : For i:=0 to theResults.Count-1 Do
>  Dispose(PRec(theResults.IntegerData[i])); меня слегка смущает.
>  Это действительно безопасно ?

абсолютно


> 4. В Д7 у меня не компиляется (ругается на неизвестный тип
> WRXMLElements)
> Что надо прикрутить в юзес ?

Ничего не нужно, без моих библиотек он у тебя и не скомпилируется. В кратце:

TWRXMLElements,TWRXMLElements - классы представляющие элементы распарсенного XML файла

TWRIntegerMap - класс, карты ключ-значение


 
Восхищенный   (2008-05-04 15:59) [449]

> ANB   (04.05.08 15:45) [447]

> 1. А где ООП то ?

ООП как раз видно. Не видно ПП. Скорее, это ХП называется.
:о)


 
ANB   (2008-05-04 16:05) [450]


> TWRXMLElements,TWRXMLElements - классы представляющие элементы
> распарсенного XML файла

А про сторонние компоненты я тоже ничего не писал :) Но все соответствует задаче - чем удобнее, тем и пользуемся.


> Везде, я оперирую тремя объектами.

ИМХО : Использование готовых классов - это не совсем ООП. Иначе мона сказать, что я тока ООП и использую.


 
ANB   (2008-05-04 16:07) [451]

Пока вывод : противники ПП пользуются им таки, когда нужно быстро чего-нибудь написать.


 
Palladin ©   (2008-05-04 16:21) [452]


> А про сторонние компоненты я тоже ничего не писал :)

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


> ИМХО : Использование готовых классов - это не совсем ООП.

Это как раз ООП. Как ты думаешь, на кой нужны классы сами по себе? А никому они не нужны сами по себе. Они призваны решать какие-то задачи. Если ты ожидал, что я сейчас начну рождать систему из мелких классов для решения этой задачи, то ты ошибаешься, у меня набор конкретных классов, однажды написанных, и использование из в совокупности позволяет быстро решить, как эту задачу, так и множество других. Причем решение это интуитивно понятно для тех кто даже и не знает эти классы. Из названий методов и обращений можно догадаться что происходит.

А ты как поклонник ПП и противник ООП не должен пользоватся существующими классами, а разбить процедуру на подпроцедуры. Вот это и будет ПП.


 
Игорь Шевченко ©   (2008-05-04 16:28) [453]

Palladin ©   (04.05.08 15:25) [444]

Фаулер бы тебя с дерьмом смешал :)


 
ANB   (2008-05-04 16:28) [454]


> А ты как поклонник ПП и противник ООП не должен пользоватся
> существующими классами, а разбить процедуру на подпроцедуры.
>  Вот это и будет ПП.

Гм. Ну тогда я не поклонник ПП, наоборот - крутой ООП программер, т.к. готовыми классами активно пользовался и пользоваться буду. Т.к. удобно и быстро.
А вот свои классы буду как и раньше, писать, тока если очень надо будет и явно будут напрашиваться.

Кстати, твой результат с моим сошелся ?

И последнее - несмотря на использование готового НЕШТАТНОГО кода, я написал минимум втрое быстрее и раз в 5 короче. Причем с использованием штатных процедур сервера.


 
Palladin ©   (2008-05-04 16:28) [455]


> Игорь Шевченко ©   (04.05.08 16:28) [453]

А кто это и за что? позвольте поинтересоваться.. )


 
ANB   (2008-05-04 16:30) [456]


> Гм. Ну тогда я не поклонник ПП, наоборот - крутой ООП программер,
>  т.к. готовыми классами активно пользовался и пользоваться
> буду. Т.к. удобно и быстро.
> А вот свои классы буду как и раньше, писать, тока если очень
> надо будет и явно будут напрашиваться.

Смайлик забыл :)

ту ИШ : будь арбитром, сравни код :)


 
Восхищенный   (2008-05-04 16:31) [457]

> ANB   (04.05.08 16:28) [454]

А можно маленький вопрос - что будет, если понадобится перейти на другой сервер?
:о)


 
Palladin ©   (2008-05-04 16:38) [458]


> ANB   (04.05.08 16:28) [454]
> Кстати, твой результат с моим сошелся ?

я проверил прежде чем запостить...


> А вот свои классы буду как и раньше, писать, тока если очень
> надо будет и явно будут напрашиваться.

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

А ты не знаю...


 
Anatoly Podgoretsky ©   (2008-05-04 16:39) [459]

> ANB  (04.05.2008 16:05:30)  [450]

Так один из плюсов ООП как раз и состоит в повторном использование кода, в том числе и чужого.


 
Игорь Шевченко ©   (2008-05-04 16:40) [460]

Palladin ©   (04.05.08 16:28) [455]


> А кто это


Мартин Фаулер такой. Программист. Автор книг по UML, Рефакторингу и архитектуре корпоративных приложений.


>  и за что?


За код, вестимо :)
Где блин инкапсуляция, полиморфизм и прочие там ... наследования ? :)
Что за глобальные переменные n,i ? :)

ANB   (04.05.08 16:30) [456]


> ту ИШ : будь арбитром, сравни код :)


Оба кода плохие - вручную посчитать гораздо быстрее.

или скачать из сети нечто, через XPath решающее нужную задачу без всякого оракла


 
Palladin ©   (2008-05-04 16:47) [461]


> Где блин инкапсуляция, полиморфизм и прочие там ... наследования
> ? :)

как это где? это все прекрасно используется в TWRIntegerMap и TWRXMLElements... )
но программисту-клиенту этого видеть и знать об этом и не нужно... )


> Что за глобальные переменные n,i ? :)

какие они глобальные, они очень даже локальные... :)


> Мартин Фаулер такой. Программист. Автор книг по UML, Рефакторингу
> и архитектуре корпоративных приложений.

не читал... а может и читал, только автора не запомнил...


 
ANB   (2008-05-04 16:48) [462]


> А можно маленький вопрос - что будет, если понадобится перейти
> на другой сервер?
> :о)

А зачем переходить на другой сервер ?

Проблема возникнет тока если подать на вход более 60 тысяч строк.
Тады придется разбирать XML руками.
Кистате, у Palladin этот вопрос решен ?


> Я разрабатываю фирменный сервер приложений

Трехслойка - самое хреновое новшество от МС.


 
ANB   (2008-05-04 16:51) [463]


> Оба кода плохие - вручную посчитать гораздо быстрее.

Дамс. Об этом варианте я не подумал.


> или скачать из сети нечто, через XPath решающее нужную задачу
> без всякого оракла

1. Эт еще надо найти, скачать и поставить, а оракл уже под рукой
2. Возможности SQL при этом отвалятся. Группировать, что - руками ?


 
Игорь Шевченко ©   (2008-05-04 16:53) [464]

Palladin ©   (04.05.08 16:47) [461]


> какие они глобальные, они очень даже локальные... :)


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

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

Foo.Elements.ByName(....)


 
Игорь Шевченко ©   (2008-05-04 16:53) [465]


> Группировать, что - руками ?


в Excel-е


 
Palladin ©   (2008-05-04 16:54) [466]


> Кистате, у Palladin этот вопрос решен ?

дело в том что у меня вообще никакого сервера не используется....


> Проблема возникнет тока если подать на вход более 60 тысяч
> строк.

это смешная цифра...


 
Игорь Шевченко ©   (2008-05-04 16:56) [467]

В Excel мне потребовалась ровно одна минута чтобы получить результат:

Названия столбцов      
101 102 103 104 105 106 107
sum 219,75 49,35 30,9 16,45 15,45 15,45 15,45
Общий итог
362,8


 
Игорь Шевченко ©   (2008-05-04 17:00) [468]

ANB   (04.05.08 16:51) [463]


> 1. Эт еще надо найти, скачать и поставить, а оракл уже под
> рукой
> 2. Возможности SQL при этом отвалятся. Группировать, что
> - руками ?


Видишь ли, Excel - он еще более у всех под рукой и не такой толстый, как оракл.

А если у тебя файл изменится, ты его по новой будешь в with вставлять ?


 
ANB   (2008-05-04 17:03) [469]


> дело в том что у меня вообще никакого сервера не используется.
> ...

Не, я не про это. Файл тысяч в 60 строк аналогичной структуры твой класс нормально съест ?

Просто XMLDom клинит начиная примерно с такого объема.

Мне пришлось писать парсер на клиенте.


> Игорь Шевченко ©   (04.05.08 16:56) [467]

Вот млин. Самая высокая скорость кодирования. Но опять таки это не ООП :)


 
Восхищенный   (2008-05-04 17:04) [470]

> ANB   (04.05.08 16:48) [462]

> А зачем переходить на другой сервер ?

А мало ли... например, появился новый заказчик со сходной задачей.. а у него Oracle не используется... да и вообще никакая СУБД не используется... а хочется повторного использования кода, а получается облом-с. Не лучше ли один раз написать, а потом юзать где угодно и сколько угодно?

Да и вообще, какое отношение имеет парсинг XML к серверам БД? Вот нужно XML-файл распарсить - так что ж, из-за этого всем клиентам Oracle ставить, что ли? Как то неправильно это, наверное... монстроидально как-то...


 
ANB   (2008-05-04 17:05) [471]


> А если у тебя файл изменится, ты его по новой будешь в with
> вставлять ?

Не. Это я для наглядности и простоты.
Так файл либо в табличку либо в параметр хранимки.


 
ANB   (2008-05-04 17:06) [472]


> Видишь ли, Excel - он еще более у всех под рукой и не такой
> толстый, как оракл.

Дистрибутив офиса скока весит ?


 
Palladin ©   (2008-05-04 17:11) [473]


> ANB   (04.05.08 17:03) [469]

Мой класс не является парсером, мой класс лишь представление данных, парсером я пользуюсь внешним... кстати MSXML... сейчас попробую создать большой xml файл и обработать...


 
Игорь Шевченко ©   (2008-05-04 17:14) [474]


> Дистрибутив офиса скока весит ?


Всяко легче дистрибутива Oracle

И в Excel-е больше народу умеют работать - поверь. Тот же Эрик Рэймонд пишет, что самый лучший путь решения - это не писать ничего, а найти средство, которое уже умеет решать нужную задачу. Если понадобиться - минимально его доработать (в случае с Excel - написать нужные макросы).


 
ANB   (2008-05-04 17:34) [475]


> И в Excel-е больше народу умеют работать - поверь. Тот же
> Эрик Рэймонд пишет, что самый лучший путь решения - это
> не писать ничего, а найти средство, которое уже умеет решать
> нужную задачу. Если понадобиться - минимально его доработать
> (в случае с Excel - написать нужные макросы).

+1. Согласен с "Эрик Рэймонд" на 100%.

У меня не получается на экселе выкрутится. Мне надо распарсенный XML в таблички разложить и хитро обработать. Но там уже много бизнес-кода.


> Всяко легче дистрибутива Oracle

Дистрибутив оракла весит примерно 260 метров. И ставится в течение 5 минут.


 
ANB   (2008-05-04 17:37) [476]


> Palladin ©   (04.05.08 17:11) [473]
>
> > ANB   (04.05.08 17:03) [469]
>
> Мой класс не является парсером, мой класс лишь представление
> данных, парсером я пользуюсь внешним... кстати MSXML...
> сейчас попробую создать большой xml файл и обработать...
>

Это не критика. Эт я пробить возможности. А то что то полезли объемы и не всегда мона отбится от XML формата обмена. Я одну дырку заткнул, где совсем падало. Но решение мне ни фига не понравилось - парсер на клиенте, XML разбираю руками, как строку. Вроде по скорости ничего - 100 тысяч чисто разбор - секунд 20. Но все вместе - полчаса. Все довольны, т.к. раньше по двое суток колбасило, без гарантии, что вообще что то получится (как правило оут оф мемори ловили).


 
Anatoly Podgoretsky ©   (2008-05-04 17:38) [477]

> ANB  (04.05.2008 16:51:43)  [463]

С Ораклом, как бы проще скачать, поставить и настроить. А когда оно сможет у человека нормально заработать?


 
Anatoly Podgoretsky ©   (2008-05-04 17:39) [478]

> ANB  (04.05.2008 17:06:52)  [472]

А вот я компьютера без Экселя не видел, а вот без Оракла сколько угодно, а точнее я вообще не видел компьютера с Ораклом.


 
Игорь Шевченко ©   (2008-05-04 17:42) [479]

ANB   (04.05.08 17:34) [475]


> Дистрибутив оракла весит примерно 260 метров


А то, что у меня 10.2.0.3 633 метра, так это просто случайность. И ставится малость подольше. Наверное машина медленная.


> У меня не получается на экселе выкрутится. Мне надо распарсенный
> XML в таблички разложить и хитро обработать. Но там уже
> много бизнес-кода.


Это уже другая задача ведь, а не та, которую ты привел ?

Я к другому - для довольно многих задач Excel вполне достаточен и умеющих им, Excel-ем пользоваться всяко больше, чем программистов всех мастей.

И для задач, подобных приведенной тобой, нет смысла соревноваться в скорости написания программы с ООП vs запрос для Oracle.


 
Игорь Шевченко ©   (2008-05-04 17:43) [480]

Anatoly Podgoretsky ©   (04.05.08 17:39) [478]


> а точнее я вообще не видел компьютера с Ораклом.


приезжай в Москву, покажу


 
Palladin ©   (2008-05-04 17:56) [481]


> ANB   (04.05.08 17:03) [469]

ага... скатина такая, парсер умер на 100 000 строках...
заменил на свой старенький (неполноценный, но в таком простом варианте сойдет)...


 
Восхищенный   (2008-05-04 18:05) [482]

> Palladin ©   (04.05.08 17:56) [481]

Тут не DOM, тут SAX нужен. DOM на больших объемах рано или поздно все равно сдохнет.


 
Восхищенный   (2008-05-04 18:07) [483]

> ANB

- Доктор, меня все игнорируют.
- Следующий!
:о)


 
ANB   (2008-05-04 18:26) [484]


> А то, что у меня 10.2.0.3 633 метра, так это просто случайность.
>  И ставится малость подольше. Наверное машина медленная.
>

Дык XE надо ставить.


 
ANB   (2008-05-04 18:33) [485]


> Тут не DOM, тут SAX нужен. DOM на больших объемах рано или
> поздно все равно сдохнет.

Дык знаю. Саксом еще не пользовался.
Во, кстати, кто пользовался - просветите, он нормально есть вложенные здоровые теги (как раз во вложенном много строчек) ?


 
Anatoly Podgoretsky ©   (2008-05-04 18:35) [486]

> ANB  (04.05.2008 17:37:56)  [476]

Это погоня за новомодными технологиями, когда их стараются воткнуть куда только получится.
Я уже рассказывал, как импортировал небольшую относительно базу на ФоксПро через XML
чеерез три дня плюнул, нажал ресет и импортировал через dbf за 30 минут.


 
Anatoly Podgoretsky ©   (2008-05-04 18:37) [487]

> Игорь Шевченко  (04.05.2008 17:43:00)  [480]

Я верю, что в Москве все есть.
Я например очень хочу купить спутниковый тюнер TeVii S420 - ближайшая точка Москва, но деньги какие то подозрительные WebMoney называются или WU
Меня же сразу в террористы запишут.


 
DVM ©   (2008-05-04 23:11) [488]


> Anatoly Podgoretsky ©   (04.05.08 18:37) [487]


> но деньги какие то подозрительные WebMoney

Чегой то вебмани подозрительными стали?  Уже лет 10 существуют.


 
Anatoly Podgoretsky ©   (2008-05-04 23:40) [489]

> DVM  (04.05.2008 23:11:08)  [488]

По моему это шаражка по отмыванию денег.


 
Германн ©   (2008-05-05 01:46) [490]


> Anatoly Podgoretsky ©   (04.05.08 18:37) [487]
>
> > Игорь Шевченко  (04.05.2008 17:43:00)  [480]
>
> Я верю, что в Москве все есть.
> Я например очень хочу купить спутниковый тюнер TeVii S420
> - ближайшая точка Москва, но деньги какие то подозрительные
> WebMoney называются или WU

В Москве всё есть. Почти как в Греции.
Так приезжай. Поможем купить за "неподозрительные" деньги.

P.S. Меня очень трудно спровоцировать на ММП. Но я бы "обязательно" принял  бы участие в  ММП, если бы в ней участвоавал бы АП!


 
Palladin ©   (2008-05-05 16:39) [491]

Продолжим.


> ANB
> Трехслойка - самое хреновое новшество от МС.

Твои доводы против ООП оказались очень убедительными :) Все они состояли из многих слов, смысл которых заключался в одной интересной аббревиатуре: ИМХО. С этим свойством доводов нет никакого смысла спорить и оспаривать. Попутно оказалось что ты тоже приверженнец ООП, да еще какой. Просто ты не считаешь, что занимаешься ООП.

Но скажи мне, чем же тебе многозвенка не угодила?


 
ANB   (2008-05-06 09:54) [492]


> Но скажи мне, чем же тебе многозвенка не угодила?

Писать много - толку мало.

Если нужен тонкий клиент (ни одного толкового не видел), то мона и классическим клиент-сервером обойтись, не плодя сущности.


 
ANB   (2008-05-06 09:56) [493]


> Попутно оказалось что ты тоже приверженнец ООП, да еще какой.
>  Просто ты не считаешь, что занимаешься ООП.

Пользование готовыми классами и возможностями среды разработки - это не ООП. Это - кнопкокидательство.
Чем я, недоразвитый такой, и занимаюсь.


 
ANB   (2008-05-06 09:58) [494]

Да, использование крэк классов - это тоже не ООП.


 
Игорь Шевченко ©   (2008-05-06 11:53) [495]


> Писать много - толку мало.


> Если нужен тонкий клиент (ни одного толкового не видел),
>  то мона и классическим клиент-сервером обойтись, не плодя
> сущности.


А эта...кругозор расширять ?


 
ANB   (2008-05-06 13:31) [496]


> А эта...кругозор расширять ?

Тады будет все равно двух-звенка клиент + аппсервер. Эт если СУБД не нужна.
А при наличии СУБД, аппсервер - лишний слой.


 
Игорь Шевченко ©   (2008-05-06 14:00) [497]

ANB   (06.05.08 13:31) [496]


> Тады будет все равно двух-звенка клиент + аппсервер. Эт
> если СУБД не нужна.
> А при наличии СУБД, аппсервер - лишний слой.


Я извиняюсь, а как же Oracle Forms, Oracle Reports - самая что ни на есть трехзвенка


 
Anatoly Podgoretsky ©   (2008-05-06 14:16) [498]


> Если нужен тонкий клиент (ни одного толкового не видел),
>  то мона и классическим клиент-сервером обойтись, не плодя
> сущности.

Неужели ни одного браузера не видел?
Очень интересно будет, в случае достаточно крупного хостера, когда он попытается выставить несколько сотен SQL серверов в Интернет.


 
ANB   (2008-05-06 14:56) [499]


> Я извиняюсь, а как же Oracle Forms, Oracle Reports - самая
> что ни на есть трехзвенка

Ну так мона и пакеты оракла в средний слой определить.


 
Игорь Шевченко ©   (2008-05-06 15:36) [500]

ANB   (06.05.08 14:56) [499]


> Ну так мона и пакеты оракла в средний слой определить.


С какой стати ?

А про Forms и Reports рекомендую почитать - много вопросов про убогость многозвенок отпадет.


 
Palladin ©   (2008-05-06 15:37) [501]

ну что"ж... теперь портрет более чем ясен... кодером ты был, им ты и останешься....


 
ANB   (2008-05-06 15:39) [502]


> Palladin ©   (06.05.08 15:37) [501]
> ну что"ж... теперь портрет более чем ясен... кодером ты
> был, им ты и останешься....

Да уж. Вот податься бы в архитекторы, а то з/п маловата :)


 
ANB   (2008-05-06 15:44) [503]


> А про Forms и Reports рекомендую почитать - много вопросов
> про убогость многозвенок отпадет.

Дык читал. Но аппсервер же ты не пишешь при этом ?

Если среда предоставляется мне комплекс, позволяющий писать код в одном месте, дык тогда хоть пятизвенка пусть будет - это уже фиолетово.

Конкретно что мне не нравится :
начинается проект, вумные архитекторы сразу грят : трехслойка круто, будем писать трехслойку. И начинается лепка хранимок, аппсервера и толстого клиента (т.к. тонкого придется писать долго до первого запуска, а заказчику надо бы чего то показать побыстрее). Нахреначивается гора кода и потом начинается ад по сопровождению и модификации. Особливо, если еще сущности, которым бы в тока в БД жить, начинают еще и в классы заворачивать.


 
Anatoly Podgoretsky ©   (2008-05-06 16:16) [504]

> ANB  (06.05.2008 15:39:22)  [502]

Да ктож его посадит, он же памятник.


 
Anatoly Podgoretsky ©   (2008-05-06 16:17) [505]

> ANB  (06.05.2008 15:44:23)  [503]

А вот за это надо убивать, из рогатки.
Это не архитекторы, а маркетологи.


 
ANB   (2008-05-06 16:57) [506]


> А вот за это надо убивать, из рогатки.
> Это не архитекторы, а маркетологи.

Ну дык у нас всегда так. Один проект, писавшийся 6 лет таким макаром практически завалили. Другой (ну там хоть понятно - мс скл), колбасит. До 15 патчей в неделю было 3 года назад. И проекту тогда было лет 7 как уже, из них 3 уже шли во всю боевые внедрения.
Я даже могу понять, когда аппсервер крутится для сложных вычислений там или еще для чего то подобного.
Я вот лепил микро - дком сервер. Но мне надо было :
1. Сделать эмулятор смарткарт отдельным приложением (чтобы руками мона было кнопки нажимать)
2. Прикрутить этот эмулятор к системе тестирования, чтобы в автомате кнопки нажимать в тестируемом приложении и при этом подсовывать ему разные карточки.
И то я дком выбрал из-за самой простой реализации интерфейса между приложениями. Если б не торопился - может и чего другого придумал бы.

А вот зачем самим писать слой между БД и клиентом - непонятно.


 
ANB   (2008-05-06 17:10) [507]


> Anatoly Podgoretsky ©   (06.05.08 16:16) [504]
> > ANB  (06.05.2008 15:39:22)  [502]
>
> Да ктож его посадит, он же памятник.

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


 
Игорь Шевченко ©   (2008-05-06 17:52) [508]

ANB   (06.05.08 16:57) [506]

Тут такой момент - если в каком-то месте что-то плохо, из этого вовсе не следует, что а) плохо повсеместно б) плохо по сути


 
Anatoly Podgoretsky ©   (2008-05-06 20:08) [509]

> ANB  (06.05.2008 16:57:26)  [506]

Так ты прилепил когда нужно было, а они ради громкого слова и больших денег.
Разницу чуешь?


 
ANB   (2008-05-07 09:55) [510]


> Тут такой момент - если в каком-то месте что-то плохо, из
> этого вовсе не следует, что а) плохо повсеместно б) плохо
> по сути

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


> Так ты прилепил когда нужно было, а они ради громкого слова
> и больших денег.
> Разницу чуешь?

Дык и я про то же.


 
Игорь Шевченко ©   (2008-05-07 09:58) [511]

ANB   (07.05.08 09:55) [510]


> Давай конкретно обсудим необходимость применении трехслойки
> при разработке обычной управленческой системы клиент-сервер
> с использованием СУБД оракл.


Давай. Начнем с ТЗ на "обычную управленческую систему".
Излагай.


 
Юрий Зотов ©   (2008-05-07 10:02) [512]

> ANB   (07.05.08 09:55) [510]

> Давай конкретно обсудим необходимость применении трехслойки при
> разработке обычной управленческой системы клиент-сервер...

Например, по соображениям безопасности заказчик выдвигает требование: прямой коннект клиента к серверу запрещен.


 
ANB   (2008-05-07 10:04) [513]


> Игорь Шевченко ©   (07.05.08 09:58) [511]

Ну хорошо. Чтобы не писать длинно : АБС. Они все работают плюс-минус одинаково.


 
ANB   (2008-05-07 10:06) [514]


> Например, по соображениям безопасности заказчик выдвигает
> требование: прямой коннект клиента к серверу запрещен.

Безопасность подключения оракла ничем не хуже подключения через апсервер. А заказчику говорим : +300 килобаксов и любой каприз за ваши деньги :)


 
ANB   (2008-05-07 10:12) [515]


> +300 килобаксов

Во. И на эти деньги пишем миниапсервер, который тупо пересылает на сервер и обратно все запросы и ответы. :)
А потом продолжаем писать классику.


 
Игорь Шевченко ©   (2008-05-07 10:22) [516]

ANB   (07.05.08 10:04) [513]

Что такое АБС и чем отличается от XYZ ?


 
ANB   (2008-05-07 10:32) [517]


> Что такое АБС и чем отличается от XYZ ?

Ой. Привычка. Автоматизированная банковская система.


 
Игорь Шевченко ©   (2008-05-07 11:07) [518]


> Автоматизированная банковская система.


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


 
Reindeer Moss Eater ©   (2008-05-07 11:18) [519]

И нужна и не нужна.
Например допофис сидит далеко от оракла на тонкой проволочке или через спутник. Канал тонкий, и пинг нестабильный. Оракл чувствителен к такой ерунде и нужна трехзвенка.


 
Reindeer Moss Eater ©   (2008-05-07 11:19) [520]

Хотя все может свестись к терминальному режиму и той же двузвенке


 
ANB   (2008-05-07 11:41) [521]


> Хотя все может свестись к терминальному режиму и той же
> двузвенке

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


 
Palladin ©   (2008-05-07 11:44) [522]

Я трехзвенку начал создавать не от хорошей жизни и не из маркетинговых соображений. Дело в том что контора специализируется на конкретном виде приложений. Если абстрагироваться, то можно выделить основные выполняемые приложениями функции. Перенести эти функции на серевер, написать к ним API. В результате написание довольно простенького приложения занимает максимум неделю. При этом оно будет уже работать в распределенной инфраструктуре, поддерживать HTTPS и работу через HTTP-прокси. И ему будет по барабану на все каскады брендмауеров, бо работает оно по HTTP, админам ничем шевелить не нужно будет, что бы все заработало,ну разве что поднапрячься если будут использовать SSL, сертификаты раздать. Второй момент, API, API - построено уже в терминах сущностей предметной области любого приложения в этом виде. В некотором роде я написал очень легкий аналог JavaBeans и его сервера приложений, но со своей спецификой. Там же (на сервере) крутится механизм автообновления приложений. Сервер может работать с любой БД, к которой существует OLE DB провайдер, так что выбор сервера БД остается за заказчиком. Он может стартовать например с jet, при необходимости абсолютно безболезненной перейти на mssql или oracle (так горяче тобой любимый), бо обращения сервера к СУБД не уходят за рамки SQL-92. Специально так делалось. Теряем конечно производительность в некоторых случаях, но приобретаем гибкость и расширяемость. Хотя на всякий случай в API введена возможность подачи SQL запроса на БД. И представляешь, я сейчас делаю первые шаги в реализации даемона для freebsd, и представляешь, решит заказчик сменить платформу на сервере и кроме смены платформы ему ничего не придется делать... плюс у сервера приложений много других приятностей, сжатие данных, сохранение клиентских сессий (в случае необходимости рестарта), автоматическое обновление приложений (пакеты обновлений могут быть залиты обновлений) и ну и так по мелочи, для сопровожденцев...

Не бывать тебе архитектором, не дай бог... загубишь все... ты сначала хотя бы программистом стань... потому что так как описано в [503] пишут кодеры...


 
Palladin ©   (2008-05-07 11:54) [523]

И вообще, задумывался ли ты, что используя браузер ты используешь как раз ту самую ненавистную тебе трехзвенную модель приложения?


 
Palladin ©   (2008-05-07 12:03) [524]

И кстати, дабы восстановить баланс, хорошего кодера, днем с огнем не сыскать, а проектировщиков, использующих пятую точку не по назначению, тьма... честно, лучше быть первоклассным кодером чем хреновым архитектором... да и ответственности меньше :)


 
ANB   (2008-05-07 12:06) [525]


> Palladin ©   (07.05.08 11:44) [522]

А чего вся эта байда полезного делает ?


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

Когда выйдешь на базу, хотя бы в половину нашего объема, заказчики тебе скажут - ну ее нафиг гибкость и расширяемость. Это вы для своего удобства прикрутили. Вы нам производительность на место верните.
Очередной уродец с независимостью от СУБД.


> обращения сервера к СУБД не уходят за рамки SQL-92. Специально
> так делалось.
И кто это придумал ?
Бедные ваши заказчики.


> Не бывать тебе архитектором, не дай бог... загубишь все.
> .. ты сначала хотя бы программистом стань... потому что
> так как описано в [503] пишут кодеры...

Да бывал я уже архитектором. И внедренных проектов написанных как лично, так и командой хватает. Могу похвастаться - у меня нет НИ ОДНОГО заваленного проекта.
Тока сейчас архитекторам чет денег дают меньше, чем кодерам.


 
ANB   (2008-05-07 12:07) [526]


> лучше быть первоклассным кодером чем хреновым архитектором.
> .. да и ответственности меньше :)

А денег больше :)


 
ANB   (2008-05-07 12:09) [527]


> И вообще, задумывался ли ты, что используя браузер ты используешь
> как раз ту самую ненавистную тебе трехзвенную модель приложения?
>

Да хоть 15-ти звенную. Главное - с точки зрения прикладного программера - это однозвенка. Если все грамотно продумано.


 
Palladin ©   (2008-05-07 12:12) [528]


> ANB   (07.05.08 12:06) [525]


> Когда выйдешь на базу, хотя бы в половину нашего объема,
>  заказчики тебе скажут - ну ее нафиг гибкость и расширяемость.
>  Это вы для своего удобства прикрутили. Вы нам производительность
> на место верните.
> Очередной уродец с независимостью от СУБД.

нафиг мне половина вашего объема? была бы половина вашего объема мне бы понадобилось другое решение :) нафиг мне размер твоей пиписки? :)


> И кто это придумал ?
> Бедные ваши заказчики.

Они очень даже счастливые :)

ты так ничего и не понял...


 
Palladin ©   (2008-05-07 12:13) [529]


> ANB   (07.05.08 12:09) [527]

ты представляешь, с точки зрения моего прикладного программиста - это тоже однозвенка, он знает только про клиент и про сервер...


 
Игорь Шевченко ©   (2008-05-07 12:44) [530]


>  хотя бы в половину нашего объема


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


 
ANB   (2008-05-07 14:32) [531]


> "половина нашего объема" - это неизвестная единица измерения.

Уточняю - наша база весит 20 террабайт. Относится к малым базам данных.
Половина - это 10 террабайт.


> Palladin ©   (07.05.08 12:13) [529]

А аппсервер никто не дорабатывает ?


> Они очень даже счастливые :)
>
> ты так ничего и не понял...

Это ты ничего пока не понял. С опытом поймешь.

По поводу универсализма (независимости от СУБД) :
решаем простенькую тестовую задачу.
Имеем 2 таблицы :
Т1
(
 ИД
,Ф1
)

Т2
(
 ИД
,Т1_ИД
,Ф2
)

Связь мастер-детал. Т.е., для примера - Т1 - список документов, Т2 - их строки.
Надо : в одной транзакции добавить документ и к нему пару строк.
И как ты извернешься с одинаковым запросом под мс скл и оракл ?

ЗЫ. Предметка так и не озвучена.


 
Игорь Шевченко ©   (2008-05-07 14:43) [532]

ANB   (07.05.08 14:32) [531]


> Уточняю - наша база весит 20 террабайт.


С картинками ?

Я к чему: объем в попугаях - ничто. Ты понимаешь, что для выхода на половину твоего объема мне достаточно залить сколько-то DVDшников в базу и гнуть пальцы, что дескать, у меня круто.

Но мы отвлеклись от темы насчет трехзвенки и автоматизированной банковской системы.

Что должна уметь твоя система, сколько народу ей должно пользоваться, как и с какой интенсивностью ?


 
ANB   (2008-05-07 15:25) [533]


> С картинками ?

Не. Документы, проводки, аналитика по договорам и счетам.

Позволять заводить документы, проталкивать их по статусам, печатать чеки на ККМ, отправлять и принимать документы из/в РКЦ.
Проводить документы, отражая проводки и остатки на счетах.
Вести учет договоров кредитов и депозитов, начислять на них проценты.
Обмениваться данными с другими системами.

Народу - у нас немного, не больше 200 человек, т.к. АБС используется в качестве бэк-офиса.
Основные процессы идут на сервере.


 
Игорь Шевченко ©   (2008-05-07 15:40) [534]

ANB   (07.05.08 15:25) [533]


> Позволять заводить документы, проталкивать их по статусам,
>  печатать чеки на ККМ, отправлять и принимать документы
> из/в РКЦ.
> Проводить документы, отражая проводки и остатки на счетах.
>
> Вести учет договоров кредитов и депозитов, начислять на
> них проценты.
> Обмениваться данными с другими системами.


Ну сам понимаешь, без трехзенки никуда :) Особенно в "проталкивании".

Мне слово "статус", "проводка", "ККМ", "РКЦ" и всякие кредиты с депозитами не говорят ничего.

Количество народу 200 человек тоже ничего не говорит, если они все сидят в одном тесном помещении, то достаточно локалки, если они равномерно распределены по планете, то локалки недостаточно - на кабеле разоришься да и сигнал затухнет, пока будет из Копена в Гаген идти.


 
ANB   (2008-05-07 15:50) [535]


> Ну сам понимаешь, без трехзенки никуда :)

Дык как то без нее обходимся. Нам тока аппсерверов для полного счастья не хватает.

ЗЫ. Куда то палладин пропал. Так и не решил задачку. Наверное, задумался об архитектуре своего монстра.


 
ANB   (2008-05-07 15:52) [536]


> Мне слово "статус", "проводка", "ККМ", "РКЦ" и всякие кредиты
> с депозитами не говорят ничего.

Статус - состояние документа (тока введен, проверен, проведен)
Проводка - тоже самое как в бухгалтерии. Дебет кредит
ККМ - хреновина, которая печатает кассовые чеки под управлением компутера
РКЦ - расчетно-кассовый центр. через них проходят наши переводы из одного банка в другой. Обмен файловый.


 
Palladin ©   (2008-05-07 15:59) [537]


> Надо : в одной транзакции добавить документ и к нему пару
> строк.

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


> ЗЫ. Предметка так и не озвучена.

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

сам назови эту область как хочешь...


> Это ты ничего пока не понял. С опытом поймешь.

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

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


 
Игорь Шевченко ©   (2008-05-07 16:17) [538]

ANB   (07.05.08 15:52) [536]

Это все конечно хорошо, только сильно напоминает одну задачку - есть на входе текстовый файл, оформленный по неким правилам, надо его прочитать и сформировать на выходе двоичный файл, тоже по неким правилам.


 
ANB   (2008-05-07 16:24) [539]


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

Большой и толстый документооборот. Напоминает АБС.
И ты хочешь сказать, что количество записей в таблицах расти не будет ?
А по задачке - я разве просил это выполнить обязательно с клиента ?
Приведи пример скрипта, который будет одинаков и для оракла и для мс скл.


>  ты не задумывался, что будучи кодером зарабатываешь больше
> чем будучи архитектором совсем не потому, что архитекторам
> меньше платят...

Задумывался. Выяснил, что архитекторам сейчас таки меньше платят. Застой на рынке ИТ.


 
ANB   (2008-05-07 16:26) [540]


> Игорь Шевченко ©   (07.05.08 16:17) [538]

Хорошо. Возьми сам любую знакомую предметку, которая требует для работы базу данных.

И озвучь, чего я не смогу сделать на оракле, чтобы понадобился аппсервер.


 
Игорь Шевченко ©   (2008-05-07 16:39) [541]


> И озвучь, чего я не смогу сделать на оракле, чтобы понадобился
> аппсервер.


Доступ с разных концов страны


 
ANB   (2008-05-07 16:51) [542]


> Игорь Шевченко ©   (07.05.08 16:39) [541]
>
> > И озвучь, чего я не смогу сделать на оракле, чтобы понадобился
>
> > аппсервер.
>
>
> Доступ с разных концов страны

Уточняем условия :
имеем 40 офисов по России и 20 за бугром. В кажном офисе от 100 до 5 человек. В головном сидит почти 1000.
Все сидят за компами и стучат клавишами - оформляют документы и пишут письма.
Задача : надо что бы все документы проходили через единую БД, но при этом работало все надежно, не тормозило и не падало, если какой то экскаваторщик в урюпинске расхреначил федеральный кабель москва-владик, у спутника связи сдохла батарея, и ближайший резервный канал связи откроется тока через 4 часа. И при этом будет безбожно тормозить.

Так пойдет ?

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


 
Palladin ©   (2008-05-07 16:58) [543]


> ANB   (07.05.08 16:24) [539]
> И ты хочешь сказать, что количество записей в таблицах расти
> не будет ?

конечно оно растет, БД коммунальных платежей за 4 года аж 9гб... НПА (норм.прав.акты) за 3 года аж до 2гб, за счет того что заказчик решил хранить приложения и документы офиса в базе... это самые крупные базы...


> А по задачке - я разве просил это выполнить обязательно
> с клиента ?
> Приведи пример скрипта, который будет одинаков и для оракла
> и для мс скл.

он не будет одинаков, как я уже сказал

> если понадобится та или иная специфика работы с БД,


 
ANB   (2008-05-07 17:08) [544]


> если понадобится та или иная специфика работы с БД,

Во. Т.е. об универсальности речь уже не идет.
Диасофт со своей поддержкой 2-х СУБД уже вешается.


> конечно оно растет, БД коммунальных платежей за 4 года аж
> 9гб... НПА (норм.прав.акты) за 3 года аж до 2гб, за счет
> того что заказчик решил хранить приложения и документы офиса
> в базе... это самые крупные базы...

Во. А говорил, что объемов нету.
И по мере развития системы они будут расти еще быстрее.
Дальше система начнет обрастать все большим и большим количеством отчетов, которые начнут тормозить на стандартном скл.
Потом вылезут ночные техпроцессы. Когда время их выполнения превысит 12 часов, единственным правильным решением будет начать переносить их на серверную логику.
И лучше этот момент продумать сразу, пока не начали стучать по голове заказчики.


 
Palladin ©   (2008-05-07 17:10) [545]


> ANB   (07.05.08 17:08) [544]

эээ... я что то не понял... ну хотя ты меня предупреждал конечно... а каким образом объем БД влияет на производительность многозвенки?


 
Palladin ©   (2008-05-07 17:12) [546]


> Дальше система начнет обрастать все большим и большим количеством
> отчетов,

ооо, отчеты есть... разной сложности... много, особенно по коммуналке.... и прикинь работают... и чет никто не жалуется...


> Во. Т.е. об универсальности речь уже не идет.

речь шла о том, что смена БД никак не повлияет на работу приложений-клиентов... а на серверную сторону повлияет лишь тем, что если есть какая то специфика, то конечно ее придется подправить...


 
Palladin ©   (2008-05-07 17:14) [547]


> Диасофт

это который банковскими операциями рулит? он оказывается отрешеннный от БД? двузвенка никогда не может быть отрешена от БД, это нонсенс. одна из задачь трехзвенки - как раз абстракция клиентского проложения от какой либо БД, всем рулит сервер...


 
Reindeer Moss Eater ©   (2008-05-07 17:24) [548]

двузвенка никогда не может быть отрешена от БД,

да лехко. или по крайней мере иногда. но никогда - "никогда".


 
Игорь Шевченко ©   (2008-05-07 17:24) [549]

ANB   (07.05.08 16:51) [542]


> надо что бы все документы проходили через единую БД, но
> при этом работало все надежно, не тормозило и не падало,
>  если какой то экскаваторщик в урюпинске расхреначил федеральный
> кабель москва-владик, у спутника связи сдохла батарея, и
> ближайший резервный канал связи откроется тока через 4 часа.
>  И при этом будет безбожно тормозить



> Решение : трехслойка нафиг тут не нужна. Ставим в кажной
> офисе локальный оракл (где потолще, где потоньше) и организуем
> репликацию.
> Репликацию пишем так, чтобы ботала при любом качестве связи
> и сама искала резервные каналы связи. Преимущество решения
> без трехслойки - мона скока угодно изгалятся с каналами
> связи и из типами, при этом клиентские приложения продолжают
> спокойно работать.


Я конечно сильно извиняюсь, но как тебе поможет репликация при требовании "что бы все документы проходили через единую БД" ?

Ты собираешься свои 20 терабайт на каждой локальной точке держать ?


 
Palladin ©   (2008-05-07 17:27) [550]


> Reindeer Moss Eater ©   (07.05.08 17:24) [548]

вообще говоря в частном случае решается конечно

и в общем тоже, но при помощи создания встроенного в приложение среднего звена :)


 
ANB   (2008-05-07 17:29) [551]


> двузвенка никогда не может быть отрешена от БД

У диасофта как раз трехзвенка. А мона сдуру и двухзвенку написать отвязанную от конкретной БД. Достаточно использовать АДО. Но я такой дурью никогда маятся не буду.


> а на серверную сторону повлияет лишь тем, что если есть
> какая то специфика, то конечно ее придется подправить...
>

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


> одна из задачь трехзвенки - как раз абстракция клиентского
> проложения от какой либо БД

Трехзвенка для этих целей ничем не круче двухзвенки.


> а каким образом объем БД влияет на производительность многозвенки?

Начнут тормозить запросы к БД.
Особенно, когда запустишь отчет "По всем документам за год".

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


 
ANB   (2008-05-07 17:31) [552]


> Ты собираешься свои 20 терабайт на каждой локальной точке
> держать ?

Зачем ? На кажной точке - тока нужные ей документы.

А уж если нужно кажный раз лазить в центральную БД, то с этим терминальный доступ справится.


 
Игорь Шевченко ©   (2008-05-07 17:31) [553]


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


А какая разница ?


 
Palladin ©   (2008-05-07 17:33) [554]


> Начнут тормозить запросы к БД.
> Особенно, когда запустишь отчет "По всем документам за год".

о как... так а это, а чего вдруг двузвенка то не будет тормозить? каким волшебным свойством она обладает то? запрос он и есть запрос, и его производительность от СУБД зависит, а не от многозвенности приложения...


> У диасофта как раз трехзвенка

честно сказать не нравится он мне... мне кажется аффтары перекурили всякой гадости...


> Ты попробуй, реши мою тестовую задачку.

какую? про xml чтоли? условия плиз исполнения, где файл лежит, кто чего получает..


>  очень плохо, когда текст скл живет в приложении

а вот тут батенька, я тебя жестоко обламаю, в приложении клиентском нет ни одного SQL скрипта


 
ANB   (2008-05-07 17:33) [555]


> и в общем тоже, но при помощи создания встроенного в приложение
> среднего звена :)

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


 
Игорь Шевченко ©   (2008-05-07 17:35) [556]

ANB   (07.05.08 17:31) [552]


> Зачем ? На кажной точке - тока нужные ей документы.


Тогда это несовместимо с требованием "что бы все документы проходили через единую БД" или ты под требованием понимаешь одно, а озвучиваешь другое.


> А уж если нужно кажный раз лазить в центральную БД, то с
> этим терминальный доступ справится.


Во-первых, терминальный доступ - это та самая многозвенка о который ты говоришь (тонким клиентом выступает Terminal Services Client), во-вторых, я не совсем понимаю, каким образом поможет терминальный доступ при локальных базах, в-третьих, я не до конца понял с репликацией - что куда реплицируется через поиск резервных каналов связи и т.п. ?


 
Palladin ©   (2008-05-07 17:35) [557]


> Достаточно написать оболочку над стандартными компонентами,
>  которые будут тягать текст запроса в зависимости от типа
> сервера.

чего чего простите делать с текстом запроса?


 
ANB   (2008-05-07 17:42) [558]


> А какая разница ?

В хранимках сразу видны ошибки в тексте запроса. На этапе компиляции. А при хранении запроса в приложении ошибки выявятся тока на тестировании при входе в эту ветку.


> запрос он и есть запрос, и его производительность от СУБД
> зависит, а не от многозвенности приложения...

Производительность запроса от его текста и размера таблиц намного больше зависит, чем от субд. На тестировании мс скл и оракл на средних обьемах ноздря в ноздрю практически по скорости идут. А вот метода оптимизации в них - разная по синтаксису.


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

Про добавление записей в две таблички при их мастер-детал связи.


> а вот тут батенька, я тебя жестоко обламаю, в приложении
> клиентском нет ни одного SQL скрипта

А аппсервер твой - это не приложение ? Где я писал, что в клиентском ?


 
Palladin ©   (2008-05-07 17:50) [559]


> ANB   (07.05.08 17:42) [558]


1. ты тему разности производительности в случае многозвенности и двузвенности не открыл
2. ты перешел на тему отчетности, отченость реализованна полностью на серверных скриптах (это не SQL скрипты, это Pascal Script"ы), это твоя любимая двухзвенность, клиенту аппсервера передается лишь данные о создании отчета и в итоге сам созданных файл
3. при работе не с отчетом, а с сущностью, я уже сказал либо используется подход встроенной совместимости с SQL-92, либо если лучше все таки отработать со спецификой БД, то пишется скрипт с синтаксисом Pascal"я, который призван отработать звеном между БД и приложением клиента...

вопросы


 
ANB   (2008-05-07 17:51) [560]


> Во-первых, терминальный доступ - это та самая многозвенка
> о который ты говоришь (тонким клиентом выступает Terminal
> Services Client), во-вторых, я не совсем понимаю, каким
> образом поможет терминальный доступ при локальных базах,
>  в-третьих, я не до конца понял с репликацией - что куда
> реплицируется через поиск резервных каналов связи и т.п.
>  ?

1. Терминал и репликация - 2 разных решения.
С терминалом - уел. Пусть будет нужна трехслойка. Хотя аппсервер здесь тоже может быть тонким и бизнес логику в него пихать смысла нету.
С другой стороны, при отсутствии связи вообще, удаленный офис не сможет работать совсем.
Репликация - процесс обмена данными между отдельными серверами. Филиалы все свои документы отправляют в центральный офис. Сами получают тока нужные им документы.
Поиск резервных каналов связи : пишется специальное приложение, которое занимается только транспортом данных от сервера к серверу.
Оно должно уметь находить запасные рабочие каналы связи при отказе основных. Есно, эти запасные каналы связи сначала надо организовать, а в приложение засунуть из параметры и научить его работать с ними.
Такая штука была реализована в "МВ офисная техника" и работала довольно продуктивно.
При использовании репликации офисы смогут ограниченно работать даже при  полном отсутствии связи с центром.


 
Reindeer Moss Eater ©   (2008-05-07 17:55) [561]

а не подеретесь


 
ANB   (2008-05-07 17:56) [562]


> отченость реализованна полностью на серверных скриптах (это
> не SQL скрипты, это Pascal Script"ы),


> либо если лучше все таки отработать со спецификой БД, то
> пишется скрипт с синтаксисом Pascal"я, который призван отработать
> звеном между БД

А скл то кто генерит ? СУБД паскаль не понимает.


 
ANB   (2008-05-07 17:56) [563]


> Reindeer Moss Eater ©   (07.05.08 17:55) [561]
> а не подеретесь

А почти подрались уже :)


 
ANB   (2008-05-07 17:58) [564]


> ANB   (07.05.08 14:32) [531]

Вот моя задачка. Палладин - ты можешь ее решить ?
Пусть будет паскалеподобный скрипт.


 
Palladin ©   (2008-05-07 17:59) [565]


> ANB   (07.05.08 17:56) [562]

Pascal Script"у от аппсервера передается объект соединения и данные поступившие от клиента и в синтаксисе PS реализуются необходимые действия для сериализации объекта. В случае смены БД, изменяется скрипт, сервер остается нетронутым.

вопросы


 
Palladin ©   (2008-05-07 18:01) [566]

в скрипте можно создавать сколь угодно объекты TADOQuery и работать с ними на всех правах, сейчас конечно придет Николай наверное, но я могу его заверить, что все объекты TADOQuery используются только во благо программинга )


 
Palladin ©   (2008-05-07 18:01) [567]


> ANB   (07.05.08 17:58) [564]

сейчас гляну


 
Palladin ©   (2008-05-07 18:02) [568]

а.. ты все про свою транзакцию... :) помоему я уже достаточно озвучил, что твоя задача не является задачей, но лишь нюанс...


 
ANB   (2008-05-07 18:05) [569]


> Palladin ©   (07.05.08 17:59) [565]

1. Скрипт хранится просто в виде текста ?
2. Кто генерит конечный скл ? Вумные слова "сериализация объекта" мне понятны, но не отвечают на вопрос.
3. Какой скл сгенерит твой паскаль скрипт по моей задачке ? Тем более наверняка она у тебя и так решается.
4. Кто у тебя проставляет хинты запросам, если поехал план выполнения запроса (фуллскан вместо индекс ранж скана или наборот) и нужно его вернуть на место или улучшить из-за выявившихся тормозов ?


 
ANB   (2008-05-07 18:07) [570]


> помоему я уже достаточно озвучил, что твоя задача не является
> задачей, но лишь нюанс...

А что в ней непонятного ?


 
Palladin ©   (2008-05-07 18:08) [571]


> 1. Скрипт хранится просто в виде текста ?

да конечно


> 2. Кто генерит конечный скл ? Вумные слова "сериализация
> объекта" мне понятны, но не отвечают на вопрос

в случае скриптовой, то человек конечно )


> 3. Какой скл сгенерит твой паскаль скрипт по моей задачке
> ? Тем более наверняка она у тебя и так решается.

паскаль ничего не сгенерит, блин, человек пишущий скрипт его сегенерит, причем в отдельном файле сохранить может, и из PS скрипта его исполнить...


> 4. Кто у тебя проставляет хинты запросам, если поехал план
> выполнения запроса (фуллскан вместо индекс ранж скана или
> наборот) и нужно его вернуть на место или улучшить из-за
> выявившихся тормозов ?

если это имеется ввиду комментарии инструмента от оракл на подобие query analizer"а, то извини ADO эти комментарии не предоставляет...


 
Palladin ©   (2008-05-07 18:15) [572]

если ты прямо хочешь так увидеть PS скрипт твое решение реализующий, то покажи как идет работа с транзакциями в оракле (я plsql не знаю) и я напишу тебе


 
ANB   (2008-05-07 18:16) [573]


> > 1. Скрипт хранится просто в виде текста ?
>
> да конечно

Во. А кто потом в них ищет синтаксические ошибки ?
И массово правит их в случае изменения структуры БД ?
Тока не надо говорить, что структура не должна так менятся, чтобы старые запросы отвалились. Все этого хотят и хрен когда так бывает.


> человек пишущий скрипт его сегенерит

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

Судя по ответу на п.4 - это не ты. Так же, судя по ответу на п.4 я не дождусь ответа на свою задачку.


> то извини ADO эти комментарии не предоставляет

АДО вообще то фиолетово синтаксис запроса. И оракловые хинты и мс склный аналог он жрет одинаково.

При этом АДО - не лучший инструмент для работы с ораклом.


 
ANB   (2008-05-07 18:20) [574]


> Palladin ©   (07.05.08 18:15) [572]

а просто коммит в конце поставить. транзакция сама стартует.
а чтобы мона было несколько операторов в один запрос засунуть, нужно писать так :
declare
 переменные
begin
 куча операторов
 commit;
end;

к синтаксису придираться не буду. Но лучше попроси дать тебе готовый кусок человека, который эти скрипты пишет.

Да. Раз ты не знаешь пл/скл, то напиши на любом диалекте скл, который знаешь.


 
Palladin ©   (2008-05-07 18:20) [575]


> Во. А кто потом в них ищет синтаксические ошибки ?
> И массово правит их в случае изменения структуры БД ?
> Тока не надо говорить, что структура не должна так менятся,
>  чтобы старые запросы отвалились. Все этого хотят и хрен
> когда так бывает.

в одном месте поправил и все. структура БД конечно меняется, например в НПА она уже раз 20 поменялась и что? я не вижу проблемы... подробней пожалуста... и причем тут многозвенность?


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

ну... один раз, при смене БД... PS скриптов не 10 тыщь, а от силы 2, но в основном всего один...


> При этом АДО - не лучший инструмент для работы с ораклом

а причем тут оракл?


 
ANB   (2008-05-07 18:20) [576]


> Так же, судя по ответу на п.4 я не дождусь ответа на свою
> задачку.

Зазвиняюсь, беру свои слова обратно.


 
ANB   (2008-05-07 18:22) [577]


> а причем тут оракл?

Эт так. до кучи. Когда на оракл будете портировать - сам узнаешь.


> а от силы 2, но в основном всего один...

Всего 2 скрипта для всех отчетов ?


 
Palladin ©   (2008-05-07 18:47) [578]


> Во. А кто потом в них ищет синтаксические ошибки ?

ты наверное имеешь в виду отладку... в качестве движка используется remobject pascal script... для этого есть все нужные инструменты...

t-sql знаю, но он блин родной для mssql... ну ладно... предполагая, что все числовое

примерно так...

Var
q:IIBQuery;
SubRecs:IIBRecords;
SQL:IStringList;
n,i:Integer;

...
SQL:=GetStringList;
SQL.Add("declare @id int");
SQL.Add("begin transaction");
SQL.Add("insert into t1 (ф1) values ("+Object.Field("F1")+")");
SQL.Add("set @id=(select @@Identity)");
If Object.GetSubRecs("t2",SubRecs) Then
For i:=0 to SubRecs.Count-1 Do
 SQL.Add("insert into t2 (т1_ид,ф2) values(@id,"+SubRecs.Field("F2")+")");
SQL.Add("commit transaction");
q:=GetQuery;
q.Exec(SQL.Text,[]);
...


 
Palladin ©   (2008-05-07 18:48) [579]


> Всего 2 скрипта для всех отчетов ?

нет 2 скрипта на одно приложение, отвечающее за сохранение/загрузку данных осущности...

если говорить про систему отчетности в системе отчетности один PS скрипт и от одного до трех максимум SQL скриптов...


 
Palladin ©   (2008-05-07 18:49) [580]


>  один PS скрипт

*на один отчет...


 
Palladin ©   (2008-05-07 18:56) [581]

упс.... еще ошибочка... в:
SQL.Add("insert into t2 (т1_ид,ф2) values(@id,"+SubRecs.Field("F2")+")");

SQL.Add("insert into t2 (т1_ид,ф2) values(@id,"+SubRecs(i).Field("F2")+")");


 
Palladin ©   (2008-05-07 19:17) [582]


> Эт так. до кучи. Когда на оракл будете портировать - сам
> узнаешь.

э... я портировать не буду, в случае перехода на оракл, портировать будет тот перец, который заморочился на отхода от SQL-92 :)

ситуация с задачей [531] возникает редко, бо на уровне аппсервера поднимается BeginTrans и CommitTrans ADOConnection для каждого сеанса сохранения сущности...

да кстати, а чей то я ступил :)... у меня же соеднинение передается тоже...
тогда еще проще...

Var
 q:IIBQuery;
 SubRecs:IIBRecords;
 n,i:Integer;

 q:=GetQuery;
 Connection.BeginTrans;
 q.Exec("insert into t1 (ф1) values (:PF1)",[Object.Field("F1")]);
 q.sql.text:="select @@Identity";
 q.Open;
 n:=q.AsInt(0);
 q.Close;
 If Object.GetSubRecs("t2",SubRecs) Then
  For i:=0 to SubRecs.Count-1 Do
   q.Exec("insert into t2 (т1_ид,ф2) values(:PT1ID,:PF2)",[n,SubRecs(i).Field("F2")]);
 Connection.CommitTrans;


 
Игорь Шевченко ©   (2008-05-07 20:22) [583]

ANB   (07.05.08 17:42) [558]


> В хранимках сразу видны ошибки в тексте запроса. На этапе
> компиляции. А при хранении запроса в приложении ошибки выявятся
> тока на тестировании при входе в эту ветку.


Это крайне сомнительное преимущество. Если писать на каждый чих процедуру, да еще и права на нее отдельно раздавать, будет такой геморрой, что мало не покажется. Если в одном месте нужен запрос, который делает нечто, нужное только в одном месте, то место этому запросу в том самом месте. А делать процедуры ради процедур или, упаси боже, тестирования, это настолько нелепое занятие, что мне даже сказать нечего.


 
Игорь Шевченко ©   (2008-05-07 20:27) [584]


> Репликация - процесс обмена данными между отдельными серверами.
>  Филиалы все свои документы отправляют в центральный офис.
>  Сами получают тока нужные им документы.


То есть, вполне может быть, что каждый филиал введет набор одних и тех же документов и выяснится это на следующее утро после того, как пьяный экскаваторщик в Усть-Констанинополе перегрыз от злости кабель ?


> При использовании репликации офисы смогут ограниченно работать
> даже при  полном отсутствии связи с центром.


На количество звеньев это вообще-то несильно влияет, с использованием briefcase-технологии подобные задачи как-то решаются.


 
MsGuns ©   (2008-05-07 23:00) [585]

>ANB   (07.05.08 10:32) [517]
>> Что такое АБС и чем отличается от XYZ ?
>Ой. Привычка. Автоматизированная банковская система.

Опана.. а щё цэ таке ?


 
Palladin ©   (2008-05-07 23:09) [586]

по моему опыту это целый зоопарк из программ, и  бедный банковский отдел IT пытается заставить все это вместе работать...


 
Германн ©   (2008-05-08 01:15) [587]

И до каких пределов может достигать любовь к спорам? Лищь бы последнее слово "осталось за мной"!
:)


 
ANB   (2008-05-08 09:34) [588]


> в одном месте поправил и все. структура БД конечно меняется,
>  например в НПА она уже раз 20 поменялась и что? я не вижу
> проблемы... подробней пожалуста... и причем тут многозвенность?
>

В одном месте ? Минимум 2 : скрипт для модификации базы и поправить ваши скл скрипты для "сериализации".
Плюс все скрипты отчетов, где используется это поле. Плюс связка "имя поля таблицы" - "имя поля в классе - обертке".

А если поле добавилось ? У вас клиент тонкий и всю инфу о полях и формах ввода тянет с аппсервера ?


> SQL.Add("set @id=(select @@Identity)");

В оракле это делается совсем по другому. Так же как в ФБ/ИБ.
И трехслойка тут все переделать никак не поможет.


> нет 2 скрипта на одно приложение, отвечающее за сохранение/загрузку
> данных осущности...

Надеюсь, не на каждую сущность отдельное приложение ?

А сколько всего таблиц нарисовать успели ?


> если говорить про систему отчетности в системе отчетности
> один PS скрипт и от одного до трех максимум SQL скриптов.
> ..

Это для всех отчетов или для каждого ?


 
ANB   (2008-05-08 09:43) [589]


> Если писать на каждый чих процедуру, да еще и права на нее
> отдельно раздавать, будет такой геморрой

А пакеты зачем ?


> портировать будет тот перец, который заморочился на отхода
> от SQL-92 :)

А теперь напиши тоже самое с использованием SQL-92.
Можно без оболочки с паскалем - чисто SQL. И мона с ошибками. Главное - принцип.


> что каждый филиал введет набор одних и тех же документов

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


> по моему опыту это целый зоопарк из программ, и  бедный
> банковский отдел IT пытается заставить все это вместе работать.
> ..

Ты успел поработать в банке ? Обалдеть.
АБС - это не зоопарк. Это всего лишь одна клетка в зоопарке.
И самое удивительное - у нас почему то весь зоопарк работает.
Может потому, что мы пишем работающие приложения, а не витаем в облаках ООП и трехслоек ?


 
Игорь Шевченко ©   (2008-05-08 10:41) [590]

ANB   (08.05.08 09:43) [589]


> А пакеты зачем ?


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


 
ANB   (2008-05-08 11:48) [591]


> но писать запросы в процедурах пакета, для того, чтобы выявить
> ошибки на этапе компиляции пакета и только для этого - это
> нонсенс

1. Легче выявляются ошибки при написании
2. Легче выявить, что сломается при изменении структуры БД
3. Легче тонко настраивать права.

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


 
Игорь Шевченко ©   (2008-05-08 11:56) [592]

ANB   (08.05.08 11:48) [591]


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


FGA не пробовал ?


> 1. Легче выявляются ошибки при написании
> 2. Легче выявить, что сломается при изменении структуры
> БД


То есть, у вас тестирование приложений отсутствует как класс или построено по приницу - запустили, не ломается, ну и ладно.
Ясно. Удачи


 
Palladin ©   (2008-05-08 12:30) [593]


> ANB   (08.05.08 11:48) [591]

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

ок? :)


 
MsGuns ©   (2008-05-08 13:11) [594]

>ANB   (08.05.08 11:48) [591]
>Пишется хранимка, в которой в зависимости от прав юзера ему подсовывается >нужный запрос. Сам юзер ни текста запроса не видит, ни откуда вообще данные >берутся.
>Хранимки складываются в один пакет и на него даются гранты общей роли.
>В самих хранимках в самом начале проверяется, имеется ли у юзера "тонкое" право на >выполнение именно этой хранимки.
>Как преимущество - хрен юзер, зайдя девелопером, сможет сделать больше, чем ему >позволяет клиентское приложение.

Читается как триллер. Особенно про юзера-трансформера.
Аффтар, пеши есчо ;)))


 
ANB   (2008-05-08 13:12) [595]


> FGA не пробовал ?

Эт чего такое ?
Знаю, что у оракла мона настроить хитро права на чтение таблиц. Но фактически это работает как обычная вьюха.
Следовательно, может невовремя вызвать жуткие тормоза.

> То есть, у вас тестирование приложений отсутствует как класс
> или построено по приницу - запустили, не ломается, ну и
> ладно.
> Ясно. Удачи

Комплексное тестирование - вообще редкость.
А качественное комплексное тестирование - эт ваще что то на грани фантастики.


 
Loginov Dmitry ©   (2008-05-08 13:13) [596]

Очевидное решение, позволяющая с помощью одного try..finally защитить сразу множество ресурсов:


procedure TForm1.Button1Click(Sender: TObject);
var
 ObjList: Contnrs.TObjectList;
 List1, List2, List3: TList;
begin
 ObjList := TObjectList.Create;
 try
   List1 := TList.Create;
   ObjList.Add(List1);

   List2 := TList.Create;
   ObjList.Add(List2);

   List2 := TList.Create;
   ObjList.Add(List2);

   {..................}

 finally
   ObjList.Free;
 end;
end;


По-моему - изящный способ, и по сравнению с присваиванием NIL записывается короче.


 
ANB   (2008-05-08 13:14) [597]


> Читается как триллер. Особенно про юзера-трансформера.
> Аффтар, пеши есчо ;)))

Милин. Ща узнаю у кореша, как его донецкий банк назывался.

У них так и сделано. + репликация в центральный офис со всей украины и уже даже россии.


 
Palladin ©   (2008-05-08 13:16) [598]


> Loginov Dmitry ©   (08.05.08 13:13) [596]

хреновое решение :) кто поинтеры в List1, List2 и List3 освобождать будет? :) пиши уж TStringList :)

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


 
ANB   (2008-05-08 13:16) [599]


>  ObjList.Add(List2);

Вместо нилов идет эта строка. + лишний объект. Единственно - в файналли строка одна.


 
Loginov Dmitry ©   (2008-05-08 13:36) [600]


> понимаешь, Дим, если бы все так было просто, что сводилось
> к освобождению лишь объектов... так ведь полным полно других
> ресурсов, требующих защитить и гарантированно освободить
> в конце работы...


Это все понятно.
Зато в файналли - одна строка и отсутсвие присваиваний NIL (это преимущества, которое я увидел в данном способе). Естественно, работает только для объектов.
Имхо, и такой подход имеет право на существования в определенных случая...


 
Palladin ©   (2008-05-08 13:37) [601]


> Имхо, и такой подход имеет право на существования в определенных
> случая...

) все на свете имеет право на существование... вот только на долго ли...


 
ANB   (2008-05-08 13:38) [602]


> Единственно - в файналли строка одна.


> хреновое решение :) кто поинтеры в List1, List2 и List3
> освобождать будет?

Мона занаследовать TList и в его деструкторе зачищать объекты в поинтерах.

Тока

> так ведь полным полно других ресурсов

рубит всю эту идею на корню.


> Palladin ©   (08.05.08 13:16) [598]

Так придумал, как решить задачку, пользуясь только SQL-92 ?
ИМХО - программер, начав использовать Т-скл - прав.
И к этому приходят все, кто пытался делать универсальные приложения под все СУБД.
Ты даже базу так просто один к одному с сервера на сервер не перетащишь, т.к. не все типы данных совпадают.


 
Palladin ©   (2008-05-08 13:39) [603]


> Так придумал, как решить задачку, пользуясь только SQL-92
> ?
> ИМХО - программер, начав использовать Т-скл - прав.
> И к этому приходят все, кто пытался делать универсальные
> приложения под все СУБД.
> Ты даже базу так просто один к одному с сервера на сервер
> не перетащишь, т.к. не все типы данных совпадают.

слухай, ну я ж сказал, моня я потом отвечу... после праздников... я не тяну время, мне просто сейчас думать лень...


 
Игорь Шевченко ©   (2008-05-08 13:48) [604]

ANB   (08.05.08 13:12) [595]


> Эт чего такое ?


Это Fine-grained access


> Знаю, что у оракла мона настроить хитро права на чтение
> таблиц. Но фактически это работает как обычная вьюха.
> Следовательно, может невовремя вызвать жуткие тормоза.


Я тебе открою страшный секрет (только не выдавай меня) - вьюхи в оракл тормозов не вызывают. Неоткуда им там взяться, тормозам при вьюхах.


> Комплексное тестирование - вообще редкость.
> А качественное комплексное тестирование - эт ваще что то
> на грани фантастики.


Это сугубо ваши личные проблемы и распространять последствия вашего бардака на парадигмы разработки - дурной признак.


 
Игорь Шевченко ©   (2008-05-08 13:49) [605]


> Очевидное решение, позволяющая с помощью одного try..finally
> защитить сразу множество ресурсов:


Разыщи портрет Оккама и повесь перед монитором, дабы он напоминал тебе - не плоди сущностей сверх необходимости.


 
ANB   (2008-05-08 16:48) [606]


> Это Fine-grained access

А. Тогда про это я читал. Знающие люди сказали, что оно того не стоит и практически никто этим не пользуется.


> Я тебе открою страшный секрет (только не выдавай меня) -
>  вьюхи в оракл тормозов не вызывают. Неоткуда им там взяться,
>  тормозам при вьюхах.

Ну надо же. И чего я дурак мучился, разбирал вьюхи на таблицы и обращался к ним напрямую, чтобы ускорить запрос с 2-х часов до 2-х секунд ?
Открою по секрету - тормозят даже вьюхи словаря, особенно в связках.


 
ANB   (2008-05-08 16:51) [607]


> Это сугубо ваши личные проблемы и распространять последствия
> вашего бардака на парадигмы разработки - дурной признак.
>

Дык он почти везде такой бардак. Чтобы провести комплекс нашей АБС, нужно около 6 человекомесяцев.

А если при этом тестер будет наступать на ошибки из-за опечаток программиста, то еще дольше.


 
MsGuns ©   (2008-05-09 03:37) [608]

>ANB   (08.05.08 16:51) [607]
>Дык он почти везде такой бардак. Чтобы провести комплекс нашей АБС, нужно около 6 человекомесяцев

Это таки да. Как и то, что для того, чтобы вкрутить лампочку надо 9 милиционеров.


 
ANB   (2008-05-12 09:54) [609]


> чтобы вкрутить лампочку надо 9 милиционеров.

И чтобы заменить 9 милиционеров на одного электрика лучше (но не обязательно :) ) писать так, чтобы ошибок было меньше. И если среда умеет ловить ошибки хотя бы синтаксические и грамматические, то хорошо этим пользоваться. Все равно еще логические ошибки отслеживать.


 
Arinyshka   (2008-05-12 12:46) [610]

Я горжусь собой... подбросить тему для такой дискуссии... :)


 
Anatoly Podgoretsky ©   (2008-05-12 13:04) [611]

> Arinyshka  (12.05.2008 12:46:10)  [610]

Дурное дело не хитрое.


 
Игорь Шевченко ©   (2008-05-12 13:10) [612]

ANB   (08.05.08 16:48) [606]


> А. Тогда про это я читал. Знающие люди сказали, что оно
> того не стоит и практически никто этим не пользуется.


"Не верь, хозяин, этому констанинопольскому ходже" (с) Габровские уловки.

Ты лучше Кайта почитай, он с картинками рассказывает, как этим пользоваться, во втором томе.


> Ну надо же. И чего я дурак мучился, разбирал вьюхи на таблицы
> и обращался к ним напрямую, чтобы ускорить запрос с 2-х
> часов до 2-х секунд ?


Вот странно. Количество таблиц не изменилось, количество связок между ними тоже, а скорость взяла и в 3600 раз увеличилась.
Станиславский тут же вспоминается.

А что тебе трассировка события 10053 рассказала ? :)


 
ANB   (2008-05-12 14:36) [613]


> Ты лучше Кайта почитай, он с картинками рассказывает, как
> этим пользоваться, во втором томе.

Я читал оригинальную доку от оракл.
И даже попробовал. Геморр еще тот. А толку - та практически таже вьюха.


> Вот странно. Количество таблиц не изменилось, количество
> связок между ними тоже, а скорость взяла и в 3600 раз увеличилась.
>
> Станиславский тут же вспоминается.

Были выброшены лишние таблицы. Именно за счет отказа от вьюх.
И за счет этого резко возрасла скорость.
Попробуй аккуратно развернуть внешние ключи таблицы (сгенерить DDL). А потом попробуй сделать это для всех таблиц в схеме.


 
Игорь Шевченко ©   (2008-05-12 14:50) [614]

ANB   (12.05.08 14:36) [613]


> Были выброшены лишние таблицы. Именно за счет отказа от
> вьюх.
> И за счет этого резко возрасла скорость.


То есть, ты сначала создаешь себе трудности, а потом их мужественно преодолеваешь ?
Бывает.

Я-то имел в виду несколько иное, когда view не содержит внутри дополнительных соединений, тогда она тормозов ну никак не создает.


 
Palladin ©   (2008-05-12 15:14) [615]


> ANB


> В одном месте ? Минимум 2 : скрипт для модификации базы
> и поправить ваши скл скрипты для "сериализации".
> Плюс все скрипты отчетов, где используется это поле. Плюс
> связка "имя поля таблицы" - "имя поля в классе - обертке".
>
>
> А если поле добавилось ? У вас клиент тонкий и всю инфу
> о полях и формах ввода тянет с аппсервера ?

И что? Причем тут собственно многозвенность? Клиент да, тонкий, он тянет только информацию о том как ему построить форму параметров отчета. Буквально 100, 200 строчек


> В оракле это делается совсем по другому. Так же как в ФБ/ИБ.
>
> И трехслойка тут все переделать никак не поможет.

опа... а кто-то тут не собирался до синтаксиса докапываться... интересный ход событий...


> Надеюсь, не на каждую сущность отдельное приложение ?
>
> А сколько всего таблиц нарисовать успели ?

причем тут таблицы? сущность, в рамках архитектуры, это более сложное понятие чем ты думаешь...


> Это для всех отчетов или для каждого ?

для каждого


> Ты успел поработать в банке ? Обалдеть.

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


> А теперь напиши тоже самое с использованием SQL-92.
> Можно без оболочки с паскалем - чисто SQL. И мона с ошибками. Главное - принцип.
> Так придумал, как решить задачку, пользуясь только SQL-92
> ?

хем... а собственно зачем? на кой мне это надо если это решается PS?

При работе через SQL-92 идет Connection.BeginTrans/Commit на каждый вызов... про это я уже писал...


> ИМХО - программер, начав использовать Т-скл - прав.
> И к этому приходят все, кто пытался делать универсальные
> приложения под все СУБД.
> Ты даже базу так просто один к одному с сервера на сервер
> не перетащишь, т.к. не все типы данных совпадают.

ну молодец значит, выпишем ему премию...

а вот теперь скажи, о ярый решатель всего с использованием оракла, при чем здесь многозвенка?

единственное слабое место, это да, ситуевина с мастер-детаил в транзакции... в прочем, это так, нюанс...


 
Palladin ©   (2008-05-12 15:17) [616]

конкретно,

1. мне не совсем понятна связь между объемом БД и многозвенностью
2. мне не совсем понятна связь между меняющейся структурой каких либо таблиц и SQL/PS скриптов для обработки данных, многозвенность то тут причем... двузвенное приложение подобными проблемами не обладает?


 
Palladin ©   (2008-05-12 15:30) [617]

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


 
ANB   (2008-05-12 16:30) [618]


> Я-то имел в виду несколько иное, когда view не содержит
> внутри дополнительных соединений, тогда она тормозов ну
> никак не создает.

А как тогда права проверять ?


 
ANB   (2008-05-12 16:46) [619]


>
> опа... а кто-то тут не собирался до синтаксиса докапываться.
> .. интересный ход событий...

А я до него и не докапывался.
Я хотел доказать тебе, что на SQL-92 написать нормально НЕВОЗМОЖНО.
Самая простая проблема - получить ID только что сгенеренной записи ставит тебя в тупик.
Она легко решается использованием особенностей диалекта конкретной СУБД.


> на кой мне это надо если это решается PS?

Судя по приведенному коду, это таки решается через Т-СКЛ. Или раз пишешь не ты - то значит нет проблем ? Надо и коллегах думать.


> многозвенность то тут причем... двузвенное приложение подобными
> проблемами не обладает?

А аппсервер тебе эти проблемы решил ?

Вот скажи, какие проблемы ты конкретно решил, написав толстый аппсервер с засунутой внутрь бизнес-логикой ? И какие - применив обертку ООП над реляционной моделью (пользуясь при этом реляционной СУБД) ?


> мне не совсем понятна связь между объемом БД и многозвенностью

С многозвенностью - никак не связана. Тормоза вызовет именно обертка ООП.


> Клиент да, тонкий, он тянет только информацию о том как
> ему построить форму параметров отчета.

А формы для ввода данных он тоже сам рисует ? На основе присланных аппсервером метаданных ?

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

Фактически осталось 2 слоя, которые надо править.

Вот только в таком случае можно оставить ОДНО место, пойдя чуток дальше и перенеся бизнес-логику на сервер СУБД.
И работать будет быстрее. И писать проще.


> (костыли в виде DCOM и пр)

А зачем ораклу эти костыли ?


 
Игорь Шевченко ©   (2008-05-12 16:52) [620]

ANB   (12.05.08 16:30) [618]


> А как тогда права проверять ?


Права надо не проверять, а раздавать. После раздачи их проверяет сервер. Грубо говоря - если тебе дали доступ к объекту, ты можешь выполнять некие операции с ним. Если нужна настройка прав на уровне строк, то добро пожаловать в FGA.

В противном случае ты сам занимаешься разработкой имитации FGA на PL/SQL, в то время как он написан на С и выполняется слегка быстрее...


 
ANB   (2008-05-12 17:08) [621]


> > Надеюсь, не на каждую сущность отдельное приложение ?
> >
> > А сколько всего таблиц нарисовать успели ?
>
> причем тут таблицы? сущность, в рамках архитектуры, это
> более сложное понятие чем ты думаешь...

Я спрашивал про количество таблиц, а не сущностей.


 
ANB   (2008-05-12 17:09) [622]


> Если нужна настройка прав на уровне строк, то добро пожаловать
> в FGA.

И чем он ФГА будет отличаться по результата от вьюхи с заджойненной таблицей прав ?


 
Игорь Шевченко ©   (2008-05-12 17:15) [623]

ANB   (12.05.08 17:09) [622]

Ну зачем я тебе буду Кайта пересказывать, его же можно прочитать, том 2, глава 21, "Тщательный контроль доступа".


 
Palladin ©   (2008-05-12 17:44) [624]


> ANB

извини, но ты опять понес какую то пургу...


> А я до него и не докапывался.
> Я хотел доказать тебе, что на SQL-92 написать нормально
> НЕВОЗМОЖНО.
> Самая простая проблема - получить ID только что сгенеренной
> записи ставит тебя в тупик.
> Она легко решается использованием особенностей диалекта
> конкретной СУБД.

ну хорошо, пусть невозможно, пусть решается на уровене PS, что дальше? пусть придется поменять PS на аппсервере при уходе от t-sql

ладно, хорошо, истинной, идеальной независимости от БД не получается, так же как и в двузвенке...


> Вот скажи, какие проблемы ты конкретно решил, написав толстый
> аппсервер с засунутой внутрь бизнес-логикой ? И какие -
> применив обертку ООП над реляционной моделью (пользуясь
> при этом реляционной СУБД) ?

да как бы давно уже сказал... читать нужно внимательней... или ты не читал и мне тебе указать конкретные номера постов?


>С многозвенностью - никак не связана. Тормоза вызовет именно обертка ООП.

конкретней, пожалуйста. в чем они будут заключатся?


> А формы для ввода данных он тоже сам рисует ? На основе
> присланных аппсервером метаданных ?

да


>  Ну и начинается изобретение собственной IDE.

а представь себе, да, она, иснтументалка низкого уровня, для разработчиков более высокого уровня и предназначена, мне уже все уши прожжужали этим: "человек, делающий отчеты, не должен знать о GetMem/FreeMem", а я куда денусь, партия сказала - значит надо


> Вот только в таком случае можно оставить ОДНО место, пойдя
> чуток дальше и перенеся бизнес-логику на сервер СУБД.
> И работать будет быстрее. И писать проще.

я этого никогда не сделаю, и не собираюсь, бизнес логика на аппсервере куда более абстрактна от ее же реализации на конкретной СУБД...


> А зачем ораклу эти костыли ?

ужо забыл про своё [506]?


 
ANB   (2008-05-12 18:06) [625]


> Ну дык у нас всегда так. Один проект, писавшийся 6 лет таким
> макаром практически завалили. Другой (ну там хоть понятно
> - мс скл), колбасит. До 15 патчей в неделю было 3 года назад.
>  И проекту тогда было лет 7 как уже, из них 3 уже шли во
> всю боевые внедрения.
> Я даже могу понять, когда аппсервер крутится для сложных
> вычислений там или еще для чего то подобного.
> Я вот лепил микро - дком сервер. Но мне надо было :
> 1. Сделать эмулятор смарткарт отдельным приложением (чтобы
> руками мона было кнопки нажимать)
> 2. Прикрутить этот эмулятор к системе тестирования, чтобы
> в автомате кнопки нажимать в тестируемом приложении и при
> этом подсовывать ему разные карточки.
> И то я дком выбрал из-за самой простой реализации интерфейса
> между приложениями. Если б не торопился - может и чего другого
> придумал бы.
>
> А вот зачем самим писать слой между БД и клиентом - непонятно.
>

Где здесь DCOM - костыль к ораклу ?


 
ANB   (2008-05-12 18:13) [626]


> Palladin ©   (12.05.08 17:44) [624]

Изобретение второй 1С.
Так ее бы сразу и поставил. Тем более 8-ка - уже любимая тобой трехслойка.
Будет такая же тормозная.


> конкретней, пожалуйста. в чем они будут заключатся?

Лишние телодвижения, приводящие к тормозам на массовых операциях.


> я этого никогда не сделаю, и не собираюсь, бизнес логика
> на аппсервере куда более абстрактна от ее же реализации
> на конкретной СУБД...

Чем абстрактнее, тем тормознее. Тем более ты так и не избавился от зависимости от конкретной СУБД. Все равно все под МС СКЛ заточено.

Давай рассмотрим конкретную задачу : нужно изменить статус у около 100 000 документов по некоему фильтру (пусть будет по дате). Причем все в одной транзакции.

На оракле (и на мс скл) я все это решаю одним оператором. А так как это один оператор, то даже с транзакциями не надо заморачиваться - он либо выполниться, либо нет.

А как это сделаешь ты (включая неявное выполнение PS скриптов) ?


 
ANB   (2008-05-12 18:16) [627]


> В противном случае ты сам занимаешься разработкой имитации
> FGA на PL/SQL, в то время как он написан на С и выполняется
> слегка быстрее...

Послезавтра приду на работу и не поленюсь протестить.
Но что то мне говорит, что хранимка отработает быстрее.


 
Игорь Шевченко ©   (2008-05-12 20:21) [628]

ANB   (12.05.08 18:13) [626]


> Тем более ты так и не избавился от зависимости от конкретной
> СУБД


Я конечно сильно извиняюсь, что не по теме, но мысли об избавлении от зависимости от конкретной СУБД нужно гнать из головы, не дожидаясь, пока они там возникнут.


 
MsGuns ©   (2008-05-13 00:03) [629]

>ANB   (12.05.08 16:46) [619]
>Я хотел доказать тебе, что на SQL-92 написать нормально НЕВОЗМОЖНО.

Плохому танцору ?

>Самая простая проблема - получить ID только что сгенеренной записи ставит тебя в тупик.

Где это, что-то не припоминаю

>Она легко решается использованием особенностей диалекта конкретной СУБД.

Зачем использовать диалекты там, где можно общаться на обычном языке ?

>Вот скажи, какие проблемы ты конкретно решил, написав толстый аппсервер с засунутой внутрь бизнес-логикой ?

Очень странные у тебя представления об "аппсерверах"


 
ANB   (2008-05-14 09:51) [630]


> Я конечно сильно извиняюсь, что не по теме, но мысли об
> избавлении от зависимости от конкретной СУБД нужно гнать
> из головы, не дожидаясь, пока они там возникнут.

А у меня они и не возникают. Посмотри описание проекта палладина, где как одно из достоинств применения трехслойки он заявляет о независимости от типа СУБД.


> >Самая простая проблема - получить ID только что сгенеренной
> записи ставит тебя в тупик.
>
> Где это, что-то не припоминаю

Узнать искусственный первичный ключ записи при вставке для того, чтобы использовать его во вставке дочерних записей.


> Очень странные у тебя представления об "аппсерверах"

Ну дык палладин написал аппсервер с бизнес-логикой внутри и оберткой в виде классов над сущностями БД.


 
Игорь Шевченко ©   (2008-05-14 11:28) [631]


> Узнать искусственный первичный ключ записи при вставке для
> того, чтобы использовать его во вставке дочерних записей


Э...а нафига ? Я до сих пор считал, что сущность как бы передается единым целым со всем ейными потрохами...


 
ANB   (2008-05-14 11:33) [632]


> Я до сих пор считал, что сущность как бы передается единым
> целым со всем ейными потрохами...

Куда передается ?


 
Palladin ©   (2008-05-14 11:38) [633]


> ANB

если ты задался вопросом, как же я получаю значение счетчика в рамках SQL-92, то расскажу тебе страшную тайну, PK поле в бд - не счетчик...


 
ANB   (2008-05-14 12:01) [634]


> PK поле в бд - не счетчик...

Гуид что ли ?


 
Palladin ©   (2008-05-14 12:08) [635]

и не гуид, обыкновенный int, без свойств identity/autoincrement, он не СУБД генерируется...


 
Игорь Шевченко ©   (2008-05-14 12:19) [636]

ANB   (14.05.08 11:33) [632]


> Куда передается ?


Промеж клиентом и сервером, скорее всего.


 
MsGuns ©   (2008-05-14 12:20) [637]

>ANB   (14.05.08 09:51) [630]
> >Самая простая проблема - получить ID только что сгенеренной
>> записи ставит тебя в тупик.
>> Где это, что-то не припоминаю

>Узнать искусственный первичный ключ записи при вставке для того, чтобы использовать его во вставке дочерних записей.

Я не припоминаю, где эта "проблема" ставила его "в тупик"


 
ANB   (2008-05-14 13:13) [638]


> Промеж клиентом и сервером, скорее всего.

каким сервером ? СУБД или приложений.

> Я не припоминаю, где эта "проблема" ставила его "в тупик"

А ответа так и не было. А тот, что был - был с использованием T-SQL.
А сейчас выясняется, что все ключи генерятся на аппсервере.


 
Palladin ©   (2008-05-14 13:19) [639]


> ANB   (14.05.08 13:13) [638]

обождите, ты мне задачу давал с чем? именно в этом был подвох то, в PK поле обладающим св-вом identity/autoincrement, а иначе задача твоя изюминкой никакой не обладает и никаких нюансов нет...

ты дал условия, я к этим условиям приспособил PS... эти нюансы в структуре БД, в принципе допустимы, в контексте аппсервера, но не рекомендуемы...


 
ANB   (2008-05-14 13:33) [640]


> обождите, ты мне задачу давал с чем? именно в этом был подвох
> то, в PK поле обладающим св-вом identity/autoincrement,
> а иначе задача твоя изюминкой никакой не обладает и никаких
> нюансов нет...
>
> ты дал условия, я к этим условиям приспособил PS... эти
> нюансы в структуре БД, в принципе допустимы, в контексте
> аппсервера, но не рекомендуемы...

Я просил изобразить, как в контексте твоего приложения, ты получаешь ID записи после/перед вставкой, чтобы потом использовать его дальше (например, для вставки дочерней записи).
В случае использования автоинкремента эта задача с использованием только SQL-92 не решается. Во всяком случае, корректно.
Однако, выясняется, что генерацией ключей занимается не СУБД, а аппсервер.
Гы. Ну, когда я писал на клиппере, у меня тоже ИД генерились на клиенте, но там просто не было другого способа.
А вот зачем использовать костыли при наличии нормальных серверов с генераторами ?


 
Palladin ©   (2008-05-14 13:40) [641]


> А вот зачем использовать костыли при наличии нормальных
> серверов с генераторами ?

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

нужно, станут использовать конкретные специфики конкретных серверов, это не запрещается, если заказчик не предполагает никуда уходить с mssql или с oracla...

в случае неопределенности с СУБД никто не будет в зравом уме использовать какие либо конкретные возможности какой либо конкретной СУБД...


 
ANB   (2008-05-14 13:50) [642]


> в случае неопределенности с СУБД никто не будет в зравом
> уме использовать какие либо конкретные возможности какой
> либо конкретной СУБД...

В случае неопределенности с СУБД никто в здравом уме не возьмется разрабатывать приложение, т.к. этот вопрос должен быть решен еще на стадии планирования. Т.к. даже архитектура приложения может иметь из-за этого различия. Да и личность архитектора от этого зависит.


 
Palladin ©   (2008-05-14 13:52) [643]


> ANB   (14.05.08 13:50) [642]

с твоими религиозными убеждениями я спорить уже давно перестал...


 
Игорь Шевченко ©   (2008-05-14 14:43) [644]

ANB   (14.05.08 13:13) [638]


> каким сервером ? СУБД или приложений.


СУБД очевидно, так как понятие ID записи имеет смысл только при общении с базой данных, нес па ?


 
Игорь Шевченко ©   (2008-05-14 14:46) [645]

ANB   (14.05.08 13:33) [640]


> Я просил изобразить, как в контексте твоего приложения,
> ты получаешь ID записи после/перед вставкой, чтобы потом
> использовать его дальше (например, для вставки дочерней
> записи).


В конктесте приложения (того, которое общается с AppServer-ом) нет нужды знать про какие-то ID, какие-то дочерние записи и т.п.

В контексте приложения есть нужда знать про сущности предметной области целиком (или про html-странички)

В контексте AppServer-а, в зависимости от СУБД и может возникнуть нужда обрабатывать "записи" поодиночке, а может и не возникнуть, если, опять же, сущности могут безболезненно путешествовать между СУБД и сервером приложений.


 
ANB   (2008-05-14 15:07) [646]


> В конктесте приложения (того, которое общается с AppServer-
> ом)

Я не имел ввиду под словом "приложение" клиента. Я имел ввиду сам аппсервер. Или он уже не приложение ?


 
Игорь Шевченко ©   (2008-05-14 15:19) [647]

ANB   (14.05.08 15:07) [646]

Про Аппсервер я тоже написал.

"В контексте AppServer-а, в зависимости от СУБД и может возникнуть нужда обрабатывать "записи" поодиночке, а может и не возникнуть, если, опять же, сущности могут безболезненно путешествовать между СУБД и сервером приложений."


> Я не имел ввиду под словом "приложение" клиента. Я имел
> ввиду сам аппсервер. Или он уже не приложение ?


Было бы замечательно, если бы ты сразу указывал, что ты имеешь в виду


 
ANB   (2008-05-15 11:31) [648]


> Было бы замечательно, если бы ты сразу указывал, что ты
> имеешь в виду

Ну дык у палладина "тонкий" клиент и про базу и ее структуру вообще ничего не знает.
Кстати, хорошая идея. Я тоже собираю материал, чтобы занятся реализацией. Только камней подводных много.


 
Игорь Шевченко ©   (2008-05-15 11:40) [649]

ANB   (15.05.08 11:31) [648


> Ну дык у палладина "тонкий" клиент и про базу и ее структуру
> вообще ничего не знает.


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


 
ANB   (2008-05-15 16:52) [650]


> И правильно делает, что не знает.

Дык я разве против ?
Я считаю, что клиент и без аппсервера ничего про структуру базы знать не должен.


 
Palladin ©   (2008-05-16 12:14) [651]


> ANB   (15.05.08 16:52) [650]

но ведь кто-то же должен... кто же...


 
ANB   (2008-05-16 15:23) [652]


> Palladin ©   (16.05.08 12:14) [651]

У тебя аппсервер знает. Через скрипты.

Мне больше нравится механизм, что знать должен только сам сервер СУБД.
А клиент только должен вызывать хранимки. Причем это тоже должно управляться сервером.

Короче, моя идея отличается от твоей в том, что бизнес слой и метаданные я хочу разместить прямо на сервере СУБД, а ты разместил это все на аппсервере.



Страницы: 1 2 3 4 5 6 7 8 9 
10 11 12 13 14 15 16 17 вся ветка

Форум: "Начинающим";
Текущий архив: 2008.06.08;
Скачать: [xml.tar.bz2];

Наверх





Память: 2.6 MB
Время: 0.063 c
2-1210761565
Vinum
2008-05-14 14:39
2008.06.08
StringGrid+datetimepicker


2-1208440152
grav
2008-04-17 17:49
2008.06.08
Ввод данных в две таблицы из одной формы


15-1209030623
TUser
2008-04-24 13:50
2008.06.08
X-сервер для ХР


2-1210838343
Вася
2008-05-15 11:59
2008.06.08
FireBird и Year()


2-1210854738
Tommy
2008-05-15 16:32
2008.06.08
MySQL и Delphi





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский