Конференция "Начинающим" » Наследники TList
 
  • Добежал (24.09.08 18:19) [0]
    Думаю, в любом крупном проекте используется TList, так как постоянно возникает необходимость хранить списки с некоей информацией. И тут возможны два подхода:

    1) когда о содержимом TList знает только "вышестоящий" класс, он и типизирует информацию:

    TMySuperClass = class(...)
    ...
     FClientList: TList;
    ...
    end;



    Реализация:

    constructor TMySuperClass.create;
    begin
    ...
     FClientList := TList.Create;
    ...
    end;

    destructor TMySuperClass.destroy;
    var
     i: integer;
    begin
    ...
     for i:=0 to FClientList.Count - 1 do
       Dispose(PClientInfo(FClientList[i]));
     FClientList.Free;
    end;



    Можно немного продвинутей писать (продвинутей ли?), если в классе происходит удаление какого-то клиента во время работы, то ввести функцию DeleteClientByPos:

    function DeleteClientByPOS(iPos: integer): boolean;
    begin
     if (iPos >=0) and (iPos < FClientList.Count) then
     begin
       Dispose(FClientList[iPos]);
       FClientList.delete(iPos);
       Result := true;
     end
     else Result := false;
    end;



    Тогда деструктор поменять можно на:

    for i:=FClientList.Count-1 downto 0 do
     DeleteClientByPOS(i);



    суть не меняется.

    2) второй же вариант - это написание каждый раз наследника TList, который будет уметь работать именно с типизированными указателями нужной структуры.

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

    Кто как делает? Еще фишка в том, что половина модуля может состоять потом из реализаций TList'ов. Выносить в отдельный модуль uData? Или uLister какой-нибудь ;)

    А наверняка еще и парадигма мож какая имеется на эту тему? Жду отзывов кто как делает ;)
  • Ega23 © (24.09.08 18:25) [1]
    Наследника. Надо типизированного - пиши типизированного.

    for i:=0 to FClientList.Count - 1 do
      Dispose(PClientInfo(FClientList[i]));


    Перекрыть Notify в наследнике.


     TGUIDList = class (TList)
     private
       function GetItem(Index: Integer): TGUID;
     protected
       procedure Notify(Ptr: Pointer; Action: TListNotification); override;
     public
       function Add(Item : TGUID) : Integer;
       procedure Clear; override;
       property Items[Index : Integer] : TGUID read GetItem; default;
       function LoadFromStream(ms : TMemoryStream; const BuffLength : Cardinal) : Boolean;
       function SaveToStream(const TagID : Integer; ms : TMemoryStream) : Boolean;
     end;

    { TGUIDList }

    //*****************************************************************************

    function TGUIDList.Add(Item: TGUID): Integer;
    var
     p : PGUID;
    begin
     New(p);
     p^ := Item;
     Result := inherited Add(p);
    end;

    //*****************************************************************************

    procedure TGUIDList.Clear;
    var
     i : Integer;
     p : Pointer;
    begin
     for i:=0 to Count-1 do
     begin
       p := Get(i);
       Dispose(PGUID(p));
     end;
     inherited;
    end;

    //*****************************************************************************

    function TGUIDList.GetItem(Index: Integer): TGUID;
    begin
     Result := PGUID(Get(Index))^;
    end;

    //*****************************************************************************

    function TGUIDList.LoadFromStream(ms: TMemoryStream;
     const BuffLength: Cardinal): Boolean;
    var
     guid : TGUID;
     i, cnt : Integer;
     recSize : Cardinal;
    begin
     try
       Result := True;
       Clear;
       recSize := SizeOf(TGUID);
       cnt := BuffLength div recSize;
       if cnt=0 then Exit;
       for i:=1 to cnt do
       begin
         ms.ReadBuffer(guid, recSize);
         Add(guid);
       end;
     except
       Clear;
       Result := False;
     end;
    end;

    //*****************************************************************************

    procedure TGUIDList.Notify(Ptr: Pointer; Action: TListNotification);
    begin
     inherited;
     if Action in [lnExtracted, lnDeleted] then
       Dispose(PGUID(Ptr));
    end;

    //*****************************************************************************

    function TGUIDList.SaveToStream(const TagID: Integer;
     ms: TMemoryStream): Boolean;
    var
     i : Integer;
     BuffLen : Cardinal;
     guid : TGUID;
    begin
     try
       ms.WriteBuffer(TagId, 4);
       BuffLen := Count*SizeOf(TGUID);
       ms.WriteBuffer(BuffLen, 4);
       for i:=0 to Count-1 do
       begin
         guid := Items[i];
         ms.WriteBuffer(guid, SizeOf(TGUID));
       end;
       Result := True;
     except
       Result := False;
     end;
    end;

    //*****************************************************************************


  • Ega23 © (24.09.08 18:26) [2]
    А в целом - есть TObjectList, который прекрасно вызывает деструкторы своих объектов, если надо.
  • Поросенок Винни-Пух © (24.09.08 18:26) [3]
    Третий вариант. Радикальный.
    Вообще отказаться от листов с рекордами. Что я и сделал.
  • oldman © (24.09.08 18:28) [4]

    > А ведь таких списков может быть десятки, сотни... тысячи.


    Ты чего там пишешь?
  • Поросенок Винни-Пух © (24.09.08 18:34) [5]
    Кроме третьего варианта есть еще дав с половиной.
    Если вся загвоздка в типе для диспоза, то ведь сам тип можно сделать параметром и передавать в десруктор элемента списка
  • Sergey Masloff (24.09.08 21:05) [6]
    Почему не нужно наследоваться от TList написано у Бакнела. У меня нет доводов которые я могу ему противопоставить.
  • Добежал (24.09.08 21:08) [7]

    > А в целом - есть TObjectList, который прекрасно вызывает
    > деструкторы своих объектов, если надо


    понятно, но это если хранить классы. У меня зачастую хранятся именно структуры аля:

    TClientInfo = record
     Name:
     Family:
     Date
    bla bla
    end;



    С другой стороны каждую структуру можно сделать классом... Будет такой аля java подход ;)


    > Вообще отказаться от листов с рекордами. Что я и сделал


    типа такая попытка вызвать интерес и нарваться на вопрос уточняющий. А я не буду задавать вопрос. Отказался - и молодец ;)
  • guav © (24.09.08 21:14) [8]
    уже ж появились дженерики, нет ? ;)
  • DVM © (24.09.08 21:32) [9]
    Я за первый вариант.
  • guav © (24.09.08 21:44) [10]
    Удаление из середины вообще нужно ? А констатное время доступа к элементу по его номеру в списке ?

    > Жду отзывов кто как делает ;)

    Я не писал наследников, использовал TObjectList напрямую.
  • jack128_ (24.09.08 21:56) [11]

    > Да и шаблоны дельфи не поддерживает.

    Ну собственно
    > уже ж появились дженерики
    это я только вернувшись к семинара..
  • Eraser © (24.09.08 23:39) [12]
    > [8] guav ©   (24.09.08 21:14)

    +1 )
  • MsGuns © (24.09.08 23:52) [13]
    Я вообще не понял к чему сабж. Это типа "Чуваки, я завязал кушать мясо и чувствую себя зашибись !" ?
  • Ega23 © (25.09.08 00:10) [14]

    > Я не писал наследников, использовал TObjectList напрямую.


    Напрямую не всегда удобно, приводить Items[i] всегда надо.
  • guav © (25.09.08 00:52) [15]
    > [14] Ega23 ©   (25.09.08 00:10)


    > Напрямую не всегда удобно, приводить Items[i] всегда надо.

    Ага. А ещё в обработчики событий Sender приходит как TObject, приводить его к нужному типу неудобно. В Делфи даункастинг - норма.
  • Германн © (25.09.08 01:21) [16]

    > А ещё в обработчики событий Sender приходит как TObject,
    >  приводить его к нужному типу неудобно.

    Устойчивая привычка проверять и приводить типы закладывается довольно быстро.
  • Real © (25.09.08 01:43) [17]

    > Ага. А ещё в обработчики событий Sender приходит как TObject

    Согласен, раздражало(ет) это всегда
  • Германн © (25.09.08 01:48) [18]

    > Real ©   (25.09.08 01:43) [17]
    >
    >
    > > Ага. А ещё в обработчики событий Sender приходит как TObject
    >
    > Согласен, раздражало(ет) это всегда
    >

    И чем раздражало?
  • brother © (25.09.08 03:18) [19]
    > И чем раздражало?

    Лишние телодвижения? ;)
  • GrayFace © (25.09.08 05:09) [20]
    Еще вариант - использовать GetMem/FreeMem, а у списка сдалать свойство ItemSize. Хотя для record'ов лучше массив.
  • korneley © (25.09.08 06:33) [21]
    Я как-то не заморачивался, делал, типа:

     TRange = class
      ipStart,
      ipEnd   : TAddr;
      Checked : boolean;
     end;

     TRangeList = class(TObjectList)
       function GetItem(Index: Integer): TRange;
       procedure SetItem(Index: Integer; AObject: TRange);
     public
       property Items[Index: Integer]: TRange read GetItem write SetItem; default;
     end;
    ...
    { TRangeList }

    function TRangeList.GetItem(Index: Integer): TRange;
    begin
     Result := TRange(inherited Items[Index]);
    end;

    procedure TRangeList.SetItem(Index: Integer; AObject: TRange);
    begin
     inherited Items[Index] := AObject;
    end;


    Ибо, что ещё "впихнуть" в рекорд (который вдруг становится классом) понадобится - не всегда заранее известно.
  • Медвежонок Пятачок © (25.09.08 08:09) [22]
    я отказался от TList с рекордами вообще.
    использую ixmldomdocument2.
    сразу убивается целое стадо зайцев.
  • Добежал (25.09.08 11:24) [23]

    > Почему не нужно наследоваться от TList написано у Бакнела.
    >  У меня нет доводов которые я могу ему противопоставить


    эээ... TList специально сделан, чтобы от него удобно было наследоваться по идее то...

    А можно таки узнать, почему не нужно наследоваться от TList?
  • Поросенок Винни-Пух © (25.09.08 11:31) [24]
    потому что рано или поздно начинаешь задаваться над вопросом:
    "а зачем мне постоянно убивать время на поддержку многочисленных классов рекордов, что нет занятий более интересных, чем эта рутина?"
  • Palladin © (25.09.08 11:35) [25]

    > А можно таки узнать, почему не нужно наследоваться от TList?

    ну не знаю как там другие, но, лично я, никогда не наследуюсь от TList и всегда создаю класс его агрегирующий, что позволяет всегда, прозрачно для программиста-клиента, заменить его на какой либо другой контейнер
  • MsGuns © (25.09.08 11:38) [26]
    >Добежал   (25.09.08 11:24) [23]
    >А можно таки узнать, почему не нужно наследоваться от TList?

    Потому же, почему не имеет смысл изобретать модификации зубила. Оно само по себе достаточно функционально, а если приспичило сверлить или закручивать гайки, то для этого имеются другие, более пригодные инструменты. О чем здесь Вам талдычат два десятка постов
  • Поросенок Винни-Пух © (25.09.08 12:15) [27]
    берешь xml документ.
    придумывешь иерархию узлов для хранения своих многочисленных структур.
    создаешь один раз на всю оставшуюся жизнь несколько библиотечных функций  для извлечения данных.
    все.

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

    никаких многочисленных TMyRecord = record end;
    никаких тысяч и тысяч строк рутинного кода каждый раз когда нужна новая структура.

    Все есть, юзай-не хочу.

    Не хочется обрабатывать на клиенте - отдал xml sql серверу и наоборот.
    От возможностей глаза разбегаются.
    Туча времени высвобождается на решение действительно творческих задач.
  • guav © (25.09.08 12:42) [28]
    Что вообще нужно от контейнера ?
    Удаление из середины вообще нужно ?
    А констатное время доступа к элементу по его номеру в списке ?
    Нужен ли полиморфизм (подозреваю что нет, т.к. речь о рекордах) ?
    Нужна ли сортировка ?
  • Добежал (25.09.08 12:53) [29]

    > берешь xml документ.
    > придумывешь иерархию узлов для хранения своих многочисленных
    > структур.
    > создаешь один раз на всю оставшуюся жизнь несколько библиотечных
    > функций  для извлечения данных.
    > все.
    >
    > доспуп к данным превращается из императивного в декларативный.
    >
    > удобно хранить, просто сериализировать, легко визуализировать
    > и редактировать. гибкость просто на высоте.
    >
    > никаких многочисленных TMyRecord = record end;
    > никаких тысяч и тысяч строк рутинного кода каждый раз когда
    > нужна новая структура.


    выглядит привлекательно, но я не понял. Можно пример?

    to guav, не могу тебе ответить на твои вопросы. Речь идет не о конкретной разработке, а вообще о подходах...
  • Поросенок Винни-Пух © (25.09.08 14:09) [30]
    Для примера нужен пример задачи
  • Добежал (25.09.08 16:50) [31]

    > Для примера нужен пример задачи


    не могу придумать пример, не зная всех прелестей технологии. Наверное, тебе легче составить пример задачи, реализация которой во всей красе выявит гибкость подхода.
  • Ega23 © (25.09.08 16:55) [32]

    > выглядит привлекательно, но я не понял. Можно пример?


    Не надо, он фанат xml. Он бы на самом xml всё писал, если бы тот ЯП был.
  • Поросенок Винни-Пух © (25.09.08 17:02) [33]
    не могу придумать пример, не зная всех прелестей технологии.

    прелести я покажу, но нужен пример. у меня их своих конечно куча, но доходчивей будет если, задача будет не моя.
  • KSergey © (25.09.08 17:19) [34]
    > Поросенок Винни-Пух ©   (25.09.08 12:15) [27]
    > берешь xml документ.

    Это все прикольно, когда вообще нет требований по скорости, да и по объему не особо. Зато надо визуализировать/редактировать/серилизовать (ёпрс! всегда любил это слово за возможность описки)

    Во всех других случаях это совершенно неподходящее решение.
  • Поросенок Винни-Пух © (25.09.08 17:25) [35]
    Во всех других случаях это совершенно неподходящее решение.

    да не надо ля-ля.
    Ну есть сто тысяч элементов списка по тридцать три поля.

    Что я загоню все в xml, что вы насоздаете все сто тысяч экземпляров рекордов.
  • Поросенок Винни-Пух © (25.09.08 17:28) [36]
    если бы тот ЯП был

    В некотором смысле он и есть яп.
    особенно xsl
  • Sapersky (25.09.08 19:49) [37]
    Еще вариант - использовать GetMem/FreeMem, а у списка сдалать свойство ItemSize. Хотя для record'ов лучше массив.

    Можно сделать универсальный список/массив и с New/Dispose (точнее, system._Initialize/_Finalize), будет поддержка длинных строк и прочих автоматически финализируемых элементов в записях.
  • DVM © (25.09.08 21:08) [38]

    > Что я загоню все в xml, что вы насоздаете все сто тысяч
    > экземпляров рекордов.

    особенно бинарные данные там хорошо будут смотреться особенно в плане скорости добавления/удаления
  • Ega23 © (25.09.08 21:12) [39]

    > особенно бинарные данные там хорошо будут смотреться особенно
    > в плане скорости добавления/удаления


    Зато это не ini-файлы и xPath есть.
    Ничего ты не понимаешь.
  • DVM © (25.09.08 21:19) [40]

    > Ничего ты не понимаешь.

    Я действительно не понимаю зачем пихать всюду XML, заменяя им все и вся и пытаясь прикрутить его вместо удобных и проверенных временем вещей.
  • Ega23 © (25.09.08 21:36) [41]
    Ну человек - фанат хмл. Я вот Sepultura люблю, он - хмл.
  • guav © (25.09.08 22:02) [42]
    > Речь идет не о конкретной разработке, а вообще о подходах...

    подходы бывают разные.
    1. array of TRecord.
    2. TList как есть. А лучше сделать классами и TObjectList, тоже как есть.
    3. Написать генерилку и нагенерячить.
    http://www.torry.ru/authorsmore.php?id=1994
    4. Связный список. Кстати, в WinAPI есть lock-free реализация односвязного списка.
    5. Частичная иммитация С++овской STL тоже возможна
    http://sourceforge.net/projects/dclx
    6. Convert absolutely everything to XML
    http://www.bitschubser.com/HowToRTFM/Q209354%20-%20HOWTO.htm
    ...
  • Медвежонок Пятачок © (25.09.08 22:05) [43]
    Я действительно не понимаю зачем пихать всюду XML

    Многие многого не понимают.
    Я вот не понимаю проблем автора ветки.
  • Медвежонок Пятачок © (25.09.08 22:08) [44]
    Я действительно не понимаю зачем пихать всюду XML

    А зачем всюду пихать циклы for/while и иф/елс?
    Типа тоже вопрос.
  • DVM © (25.09.08 22:11) [45]

    > А зачем всюду пихать циклы for/while и иф/елс?

    но ими же не пытаются заменить XML :)
  • guav © (25.09.08 22:16) [46]
    > [44] Медвежонок Пятачок ©   (25.09.08 22:08)

    Зачем вообще циклы ? Надо что-то сделать с кучей рекордов ? Ну если входные данные в XML и выходные в XML, не круче ли будет написать XSL ?
  • Медвежонок Пятачок © (25.09.08 22:26) [47]
    > особенно бинарные данные там хорошо будут смотреться особенно
    > в плане скорости добавления/удаления


    Рассказываю про бинарные данные.
    Есть у меня дистрибутив программы. Коробочная штука. После инсталла полностью готова к работе. Кроме одной вещи, которую в инсталл не засунешь. Это контейнеры приватных ключей и хранилище сертификатов.
    Для каждого нового клиента генерируется свой комплект.
    При создании учетки для нового клиента создается xml документ куда кроме прочих параметров, используемых при инициализации чистой бд добавляются те самые ключи и сертификаты в b64 виде в узлах cdata.

    Объемы разумеется не гигабайтные, но никаих проблем со скоростью никто не имеет. Одни сплошные удобства. При запуске с параметрами все данные переезжают в бд, все файлы декодируются из xml и ложаться куда надо.
  • Ega23 © (25.09.08 23:13) [48]

    > Медвежонок Пятачок ©   (25.09.08 22:26) [47]


    ну и че? Ну нормальное и вполне разумное применение xml.
    А вот когда пишешь, ну не знаю, очередь какую-нибудь, причем не простую FIFO, а похитрее - что, тоже XML надо использовать?
    Проблема его в том, что это, как ни крути  - суть строка. Да, можно дополнительно извернуться и написать такой парсер, который потом в нодах будет хранить именно те типы данных, которые требуются. Но в целом - строка, как ни крути. И ты, как человек весьма не плохо разбирающийся в БД, прекрасно знаешь, что такое "сравнение по строке" vs "сравнение по числу".

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

    Малой саперной лопаткой, к примеру, можно не только копать. Её можно вполне сносно в цель метать. Мы ей и консервы открывали, и дрова рубили и хлеб даже как-то резали. Но буть уверен, что если ьы в тот момент был топор - дрова рубили бы топором. :)
  • Медвежонок Пятачок © (25.09.08 23:19) [49]
    Ега, ты лучше автору расскажи как ему его листы с множественными типами рекордов пополиморфеестее обрабатывать и поинкапсулеестее проектировать.
    Скоро полсотни постов, а у него все еще оргазм не наступил.

    Обжект лист и объекты для чисто тупо под контейнер полей использовать - так я тоже начну песню петь про тяжести и избыточности.
  • Ega23 © (26.09.08 10:45) [50]

    > Ега, ты лучше автору расскажи как ему его листы с множественными
    > типами рекордов пополиморфеестее обрабатывать и поинкапсулеестее
    > проектировать.


    А никак. Если рекорд - то я вообще не вижу сильно большого смысла TList перекрывать. Ну разве Notify, чтобы удалялось по Clear.

    Тысячи различных рекордов? Ну пусть, рекоды-же он описывает? почему там же и лист не описать?
    Хотя да, в данной ситуации без шаблонов тяжеловато - многа букаф получаецца.
  • Поросенок Винни-Пух © (26.09.08 10:50) [51]
    вот поэтому-то я как-то и решил, что ну его в баню.
    заменил лист на ixmdonnodelist а рекорд на ixmldomnode

    при этом структуры разные, а типов всего два на все про все.
  • Добежал (26.09.08 12:50) [52]
    Поросенок Винни-Пух, а какие средства используешь для работы с XML? Что-то дельфовое или стороннее?
    WinApi?
  • Ins © (26.09.08 12:56) [53]
    Если версия Delphi от 2005 до 2007, то можно использовать что-то подобное такому Code Template, облегчающему написание потомков от TList/TObjectList:

    <?xml version="1.0" encoding="utf-8" ?>
    <codetemplate xmlns="http://schemas.borland.com/Delphi/2005/codetemplates" version="1.0.0">
      <template name="SafeObjectList" invoke="manual">
         <description>
    Safe type TObjectList
         </description>
         <author>
            Ins
         </author>
         <point name="listclass">
            <text>
    TMyObjectList
            </text>
            <hint>
    List class name
            </hint>
         </point>
         <point name="itemclass">
            <text>
    TMyObject
            </text>
            <hint>
    Item class name
            </hint>
         </point>
         <code language="Delphi" delimiter="|"><![CDATA[|*||listclass| = class(TObjectList)
    |*|protected
    |*||*|function GetItem(Index: Integer): |itemclass|;
    |*||*|procedure SetItem(Index: Integer; const Value: |itemclass|);
    |*|public
    |*||*|function Add(AObject: |itemclass|): Integer;
    |*||*|function Extract(Item: |itemclass|): |itemclass|;
    |*||*|function Remove(AObject: |itemclass|): Integer;
    |*||*|function IndexOf(AObject: |itemclass|): Integer;
    |*||*|procedure Insert(Index: Integer; AObject: |itemclass|);
    |*||*|function First: |itemclass|;
    |*||*|function Last: |itemclass|;
    |*||*|property Items[Index: Integer]: |itemclass| read GetItem write SetItem; default;
    |*|end;

    { |listclass| }

    function |listclass|.Add(AObject: |itemclass|): Integer;
    begin
    |*|Result := inherited Add(AObject);
    end;

    function |listclass|.Extract(Item: |itemclass|): |itemclass|;
    begin
    |*|Result := |itemclass|(inherited Extract(Item));
    end;

    function |listclass|.First: |itemclass|;
    begin
    |*|Result := |itemclass|(inherited First);
    end;

    function |listclass|.GetItem(Index: Integer): |itemclass|;
    begin
    |*|Result := |itemclass|(inherited Items[Index]);
    end;

    function |listclass|.IndexOf(AObject: |itemclass|): Integer;
    begin
    |*|Result := inherited IndexOf(AObject);
    end;

    procedure |listclass|.Insert(Index: Integer; AObject: |itemclass|);
    begin
    |*|inherited Insert(Index, AObject);
    end;

    function |listclass|.Last: |itemclass|;
    begin
    |*|Result := |itemclass|(inherited Last);
    end;

    function |listclass|.Remove(AObject: |itemclass|): Integer;
    begin
    |*|Result := inherited Remove(AObject);
    end;

    procedure |listclass|.SetItem(Index: Integer; const Value: |itemclass|);
    begin
    |*|inherited Items[Index] := Value;
    end;]]>
         


      </template>
    </codetemplate>
  • Поросенок Винни-Пух © (26.09.08 12:59) [54]
    project->import type library->microsoft xml,v4.0 /6.0 ->create unit
  • sniknik © (26.09.08 14:14) [55]
    крылья, ноги... хвост, вот что главное! © ящерица из мультфильма

    > У меня зачастую хранятся именно структуры аля:
    >  TClientInfo = record
    >    Name:
    >    Family:
    >    Date
    >    bla bla
    >  end;



    это естественным образом это ложится в рекордсет, либо таблицу, каждый рекорд ака запись в таблице, переменная - поле. автоматом получаем индексы, поиск, сортировки, скорость обработки данных (особенно если записей много). т.е. удобства работы с данными, до которого xml далеко (имхо, и не надо приводить примеры сложных но относительно маленьких структур, и др. где xml действительно к месту), а уж список с рекордами вообще можно не рассматривать, несравнимо.
  • sniknik © (26.09.08 14:18) [56]
    > А ведь таких списков может быть десятки, сотни... тысячи.
    а это уже полноценная база данных, и немаленькая... раз счёт таблиц на тысячи идёт.
  • Поросенок Винни-Пух © (26.09.08 14:18) [57]
    индексы в списке рекордов?
    автоматом поиск?
    автоматом сортировка?

    а! понял. речь шла про скл сервер. понял. заменить списки таблицами оракла
  • Правильный$Вася (26.09.08 16:03) [58]

    > Поросенок Винни-Пух ©   (26.09.08 14:18) [57]

    не обазятально
    можно воспользоваться чем-то вроде ClientDataSet, оторванного (вернее, не прилепленного) от базы
  • Поросенок Винни-Пух © (26.09.08 16:30) [59]
    можно.
    ситуация: пустой датасет и его пока не из чего загружать.
    нужно создать надот из трех записей по три поля.
    считаем телодвижения:
    1. проинициализировать филдефс
    2. создать поля.
    3. вставить три записи

    или ситуация:
    есть уже пакет из трех полей.
    требуется четвертое.
    снова считаем телодвижения ....
  • Правильный$Вася (26.09.08 16:34) [60]

    > снова считаем телодвижения

    и что, пальцев на руке не хватает?

    зато все уже сделано внутри, все методы и свойства, только пользуйся
    и никаких внешних библиотек тянуть не надо
    + быстрый индексный доступ
    + опять же возможность выгрузить в xml для любителей
  • Поросенок Винни-Пух © (26.09.08 16:38) [61]
    и что, пальцев на руке не хватает?

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

    хотя пальцев на руке и у него и у меня хватает.
  • sniknik © (26.09.08 17:42) [62]
    > считаем телодвижения:
    в десигне ложим рекордсет на форму (клиентский или ado-шный), добавляем нужные поля, 3 или 4 неважно.
    в рантайме делаем вызов CreateDataset();
    готово к работе.

    > 3. вставить три записи
    LoadFromFile()/Stream , 3 записи или 3 000 неважно.

    > требуется четвертое.
    внезапно, прямо посреди работы программы? или время на перекомпиляцию все таки есть? тогда добавить в десигне к датасету еще поле, или десять, это не проблема. вот с сохранёнными данными, если сохранял в таком формате, уже не поработаешь, это будет проблемой (не очень большой), придётся перекладывать данные в новую структуру.
    но с mxl ситуация та же, тем более рекордсет можно выгрузить в формат xml. проще добавлять поля в нем? добавляй. после загрузишь обратно и оно будет "как родное".

    > я ему рассказал, как реально перестать париться с рутиной
    завязываясь на xml? странные у вас понятия о простоте. имхо, автор именно над самим xml/dom обьектом  и будет больше всего "париться". т.е. пока не поймет будет "парится", а после уже будет жалко бросать им пользоваться, наработки, т.к. тогда придётся признать, что куча времени "коту под хвост".

    кстати не пробовал json? из мира линукса аналогичный (текстовый) формат, имхо, намного удобнее и проще xml, при аналогичных достоинствах (сложные структуры держать).
    http://www.json.org/
    http://ru.wikipedia.org/wiki/JSON
  • Eraser © (26.09.08 17:43) [63]

    var
     List: TList<TGUID>;

  • Ega23 © (26.09.08 17:46) [64]

    > кстати не пробовал json?


    Я чуть-чуть пробовал.
  • Ega23 © (26.09.08 17:46) [65]

    > кстати не пробовал json?


    На sorceforge даже pas-овский парсер есть.
  • Поросенок Винни-Пух © (26.09.08 17:48) [66]
    кстати не пробовал json? из мира линукса аналогичный (текстовый) формат, имхо, намного удобнее и проще xml, при аналогичных достоинствах (сложные структуры держать).

    Честно говоря я только по первости рассматривал xml как чудной текстовый файл с тегами. Сегодня он мне интересен постольку поскольку. Будет он бинарным или еще каким - мне уже по барабану.
    Мне важнее те средства и технологии которые он мне дает в руки.
    А F3 в фаре я на нем все реже и реже нажимаю.

    в десигне ложим рекордсет на форму (клиентский или ado-шный), добавляем нужные поля, 3 или 4 неважно.
    в рантайме делаем вызов CreateDataset();


    Это если есть объект БД, то да. А если его нет, но нужна структура?
  • Ega23 © (26.09.08 17:50) [67]

    > Это если есть объект БД, то да.


    И если есть и если нет - то да.
  • Поросенок Винни-Пух © (26.09.08 17:51) [68]
    странные у вас понятия о простоте

    этот спор бесконечным может быть. пока не появится реальная задача и несколько вариантов её решения, один из которых будет мой.
    вот тогда можно будет предметно говорить о простоте, объеме кода и тормозах.
  • Поросенок Винни-Пух © (26.09.08 18:01) [69]
    И если есть и если нет - то да.

    ок, я правильно понял, нет бд, но есть адодатасет и есть клиентдадасет?
  • Ega23 © (26.09.08 18:07) [70]

    > ок, я правильно понял, нет бд, но есть адодатасет и есть
    > клиентдадасет?


    или.

    есть ADODataSet или ClientDataSet.
    Только в этом случае у них CreateDataSet метод надо вызвать.
  • Поросенок Винни-Пух © (26.09.08 18:10) [71]
    замечательно. и эти люди мне говорят про тяжесть и избыточность xml. а про адо.ртл они как бы не вспоминают для программы, которой вообще к бд нет необходимости обращаться
  • Ega23 © (26.09.08 18:14) [72]

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


    Это тебе sniknik © говорит; я ini-файлы использую...  :)
  • Поросенок Винни-Пух © (26.09.08 18:15) [73]
    да я помню, помню :)
  • Ega23 © (26.09.08 18:17) [74]

    > да я помню, помню :)


    Это шутка была.
  • sniknik © (26.09.08 18:18) [75]
    > которой вообще к бд нет необходимости обращаться
    сколько раз повторять, что и для этих рекогдсетов нет этой необходимости. данные рекордсеты, это самодостаточные обьекты для работы с данными.
    ещё раз - НИКАКИХ БД НЕ ТРЕБУЕТСЯ. но и не помешают если возникнет необходимость в более серьезной обработке данных.
  • Поросенок Винни-Пух © (26.09.08 18:20) [76]
    я не про необходимость бд и говорю.

    скажи тип своего рекордсета и фамилию dpk который ко мне при этом прикомпилится.
  • Правильный$Вася (26.09.08 18:28) [77]

    >  ко мне при этом прикомпилится

    тесно?
    для CDS это midaslib размером всего около 300к
    зато всегда с собой и никаких заморочек с отсутствием на чужом компе
  • Поросенок Винни-Пух © (26.09.08 18:32) [78]
    для CDS это midaslib размером всего около 300к

    Мне не тесно. Это я на тему изыточности и тяжести, про которую мен рассказывают.

    про кдс снова повторяюсь - сколько телодвижений надо сделать для создания датасета на пустом месте?

    + про тип рекордсета и его пакет хотелось бы узнать до кучи.
  • sniknik © (26.09.08 20:18) [79]
    > для CDS это midaslib размером всего около 300к
    для ADO это такой же внешний COM сом обьект как и DOM xml, к программе конечно что то добавится, что то же пишется естественно при работе с данными (а типа с xml не так).  

    > сколько телодвижений надо сделать для создания датасета на пустом месте?
    одно.  читай sniknik ©   (26.09.08 17:42) [62]  
    все что делается мастером, не считаем, это не "телодвижения", это "движение носа".

    > + про тип рекордсета и его пакет хотелось бы узнать до кучи.
    какая тебе разница на тип? берешь любой из указанных двух. работа ведется практически одинаково. различия есть конечно, но чтобы начинать на них ориентироваться, тем более использовать... это не сразу будет и в большинстве случаев не нужно.
    и какая разница на пакет? раз тебе все одно "не тесно". и разговор был не о "тяжести" выраженной в килобайтах, а о необходимости "парится" (не знаю что это у тебя значит, только повторяю за тобой...).
    ты, имхо, уводишь "спор" в другое русло, несущественными вопросами. зачем?
    все, что нужно чтобы проверить уже сказано. просто повторить по шагам (в обратку проверять работу с xml мне нет нужды, я с ним работал, потому и могу сравнивать).
  • Медвежонок Пятачок © (26.09.08 22:58) [80]
    в таком случае больше не надо приводить мне аргументы про "избыточность" и "тяжеловесность" xml.

    все что делается мастером, не считаем, это не "телодвижения", это "движение носа".

    Ну а все таки. Есть пустой рекордсет. Загружать пока не из чего, но структуру создать надо. Я в хмл создам ее за меньшим количеством кода.
  • sniknik © (26.09.08 23:52) [81]
    > Ну а все таки. Есть пустой рекордсет. Загружать пока не из чего, но структуру создать надо.
    вот мы её и создаем, заодно открываем рекордсет командой CreateDataset, сколько повторять, ну ладно уговорил полный код приведу раз непонятно ->

    type
     TForm1 = class(TForm)
       ADODataSet1Field1: TIntegerField;
       ADODataSet1Field2: TIntegerField;
       ADODataSet1Field3: TStringField;
       procedure FormCreate(Sender: TObject);
     private
     public
     end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      ADODataSet1.CreateDataSet;
    end;



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

    > Я в хмл создам ее за меньшим количеством кода.
    а я угадаю с семи нот! нашёл чем хвастать... делать больше нечего как только создавать структуры и радоваться этому.
    говорили, же про работу с данными. создание структуры только малая ее часть... тем более, что для xml структура продолжает создаваться на протяжении всего вноса данных, т.к. "размазана" по всему объему массива данных, и вносится вместе с ними.
    а то что ты собирался показать, это только начало, подготовка т.сказать (по аналогии с рекордсетом это будет аналогом "ложения" его на форму).
  • Медвежонок Пятачок © (26.09.08 23:55) [82]
    ну ладно уговорил полный код приведу раз непонятно ->

    мда. по ходу дела непонятно не мне, а тебе.
  • Игорь Шевченко © (27.09.08 00:30) [83]
    у...а я вот наследников от TList пишу уже много лет...И жив пока, несмотря на грозного Бакнелла. Да и Борланды их, наследников, тоже пишут. Наверно они не читали, почему от него нельзя наследоваться.
  • sniknik © (27.09.08 00:35) [84]
    > мда. по ходу дела непонятно не мне, а тебе.
    а то. трудно понять человека который разговаривает лозунгами (о крутизне xml), туманными фразами (вроде вот этой на которую отвечаю, вроде сказал что мне что то не понятно, а сказать что непонятно с его точки зрения? это объяснить? я то стараюсь...), и обещаниями о том что там де легко все и просто (это в общем по топику).

    давай еще раз о структуре (я же говорил, я стараюсь), что ты понимаеш по этим?
    вот давая переведем все в понятный тебе  xml, т.е. добавим в показаный код после ADODataSet1.CreateDataSet; ещё ADODataSet1.SaveToFile('D:\xml.xml'); (сохраним как xml, без данных, т.е. "чистую" структуру) получим
    <xml xmlns:s="uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:rs="urn:schemas-microsoft-com:rowset" xmlns:z="#RowsetSchema">
    <s:Schema id="RowsetSchema">
    <s:ElementType name="row" content="eltOnly" rs:updatable="true">
    <s:AttributeType name="Field1" rs:number="1" rs:nullable="true" rs:write="true">
     <s:datatype dt:type="int" dt:maxLength="4" rs:precision="0" rs:fixedlength="true" />
     </s:AttributeType>
    <s:AttributeType name="Field2" rs:number="2" rs:nullable="true" rs:write="true">
     <s:datatype dt:type="int" dt:maxLength="4" rs:precision="0" rs:fixedlength="true" />
     </s:AttributeType>
    <s:AttributeType name="Field3" rs:number="3" rs:nullable="true" rs:write="true">
     <s:datatype dt:type="string" rs:dbtype="str" dt:maxLength="50" rs:precision="0" />
     </s:AttributeType>
     <s:extends type="rs:rowbase" />
     </s:ElementType>
     </s:Schema>
     <rs:data />
     </xml>


    это не структура? нет? а что же ты тогда имел в виду говоря это слово?
  • Медвежонок Пятачок © (27.09.08 00:38) [85]
    а я знаю людей, которые много лет подряд открывают serialnum.txt в блокноте и глядя на буквы и цифры вводят вручную в поле регистации длиннющие номера. попеременно переключаясь с блокнота на сетап.

    :)
  • Медвежонок Пятачок © (27.09.08 01:28) [86]
    это не структура? нет? а что же ты тогда имел в виду говоря это слово?

    with TClientDataSet.Create(nil) do
    begin
     .....
    end;

    Вот так наконец понятно?
    Или все еще нет?
    Если нет, то я пас.
  • Германн © (27.09.08 01:49) [87]
    Увязли в болоте. :)
  • sniknik © (27.09.08 02:18) [88]
    > Вот так наконец понятно?
    теперь дошло... ты хочешь чтобы я с датасетом повторил те же "телодвижения", что ты делаешь с dom объектом... объект другой, работают с ним по другому (и изначально объяснялся именно правильный вариант работы, но тогда ты это игнорировал), преимущества проявляются именно при сравнении с нормальной работой, поэтому давайте заставим других извращаться также как и ты, и сразу станет понятно насколько твое извращение легче и удобнее.
    именно такой подход к работе с xml мне и не нравится, конкретно вот это и этому подобное я и считаю "запарками" в работе.

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

    > Увязли в болоте. :)
    ну так, очень старались...
  • Германн © (27.09.08 03:05) [89]

    > > Увязли в болоте. :)
    > ну так, очень старались...
    >

    А я и не сомневался. :)
    Ну это наша исконно русская черта. :)
    Кто-бы блин сомневался :)
  • Тын-Дын © (27.09.08 14:16) [90]
    А можно Бакнелла процитировать?
  • Тын-Дын © (29.09.08 01:52) [91]

    > Sergey Masloff   (24.09.08 21:05) [6]
    > Почему не нужно наследоваться от TList написано у Бакнела.
    >  У меня нет доводов которые я могу ему противопоставить.
    >


    Нашел я место у Бакнелла, где написано про TList. Но не нашел довод за его позицию.

    Основной аргумент против использования наследования от TList - замедление работы TList.

    Аргумент практически не выдерживает критики.
    Бакнелл утверждает, что после того, как добавлен пустой метод Notify, удаление элементов из массива происходит гораздо медленнее(цитата от автора).
    Это значительное снижение скорости, как утверждает автор, происходит за счет вызова метода Notify.
    Но насколько может замедлить работу единственный вызов пустого метода при удалении одного элемента? На время выполнения нескольких машинных инструкции?

    Поэтому вряд ли оправдана его рекомендация не использовать TList для создания произвдных классов.

    Для упрощения работы с массивом я бы посоветовал автору использовать не структуры данных, а классы. В этом случае не будет стоять проблема приведения типов при удалении объектов.
    Испольование классов приведет к незначительному увеличению времени обработки и увеличении используемой памяти, но облегчит разработку и повысит прозрачность кода.
Есть новые Нет новых   [134444   +21][b:0.001][p:0.006]