Как правильно работать с динамическим количеством классов ?

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Как правильно работать с динамическим количеством классов ?

Сообщение nic1982 » 29.10.2015 23:41:08

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

Абстрактный смысл такой:
есть фирма - программа;
есть директор - обработчик нажатия кнопки в программе;
есть менеджер подчиненный директору - TMyDynArrayClass;
есть работник подчиненный менеджеру - TMyClass.
Директор не общается с работником.

Правильно ли я поступаю с динамическим количеством классов ?
Какие есть еще варианты ?

Пример:
Код: Выделить всё
TMyClass = class
  private   
    str : string;
  public
    procedure write_str(tmp : string);
    function  read_str : string;
end;

procedure TMyClass.write_str(tmp : string);
begin
  str:= tmp;
end;

function TMyClass.read_str : string;
begin
  result:= str;
end;


Код: Выделить всё
TMyDynArrayClass = class
  private
    DynArrayClass : array of TMyClass; // обратите внимание сюда!
  public
    procedure run;
end;

procedure TMyDynArrayClass.run;
begin

  SetLength(DynArrayClass, 3);

  DynArrayClass[0]:= TMyClass.Create;
  DynArrayClass[1]:= TMyClass.Create;
  DynArrayClass[2]:= TMyClass.Create;

  DynArrayClass[0].write_str('000');
  DynArrayClass[1].write_str('111');
  DynArrayClass[2].write_str('222');

  ShowMessage('N0 = ' + DynArrayClass[0].read_str);
  ShowMessage('N1 = ' + DynArrayClass[1].read_str);
  ShowMessage('N2 = ' + DynArrayClass[2].read_str);

end;


Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var MyDynArrayClass : TMyDynArrayClass;
begin

  MyDynArrayClass:= TMyDynArrayClass.Create;

  MyDynArrayClass.run;

end;
nic1982
новенький
 
Сообщения: 48
Зарегистрирован: 17.05.2011 16:34:05

Re: Как правильно работать с динамическим количеством классо

Сообщение CynicRus » 30.10.2015 00:24:27

Я бы использовал список для этого, точнее обёртку с generic-списком для этих классов. А уже этот класс-обёртку использовал бы для работы с TMyClass. Типа - TMyClassManager.
CynicRus
постоялец
 
Сообщения: 106
Зарегистрирован: 28.06.2012 14:31:11

Re: Как правильно работать с динамическим количеством классо

Сообщение Sharfik » 30.10.2015 01:12:43

Код: Выделить всё

procedure TMyDynArrayClass.run;
begin

  SetLength(DynArrayClass, 3); // Count=3? или от 1...до 1000000? Тормозить будет, если второй вариант. Либо заранее выделять больше, либо TList использовать.

  DynArrayClass[0]:= TMyClass.Create;
  DynArrayClass[1]:= TMyClass.Create;
  DynArrayClass[2]:= TMyClass.Create;
.....
end;
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 809
Зарегистрирован: 20.07.2013 01:04:30

Re: Как правильно работать с динамическим количеством классо

Сообщение Tango » 05.11.2015 20:50:36

А почему не TList?
Аватара пользователя
Tango
постоялец
 
Сообщения: 162
Зарегистрирован: 31.05.2012 17:07:30

Re: Как правильно работать с динамическим количеством классо

Сообщение Снег Север » 05.11.2015 21:23:53

TObjectList, TClassList...
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3053
Зарегистрирован: 27.11.2007 16:14:47

Re: Как правильно работать с динамическим количеством классо

Сообщение fgcsDenis » 06.11.2015 19:07:59

А ещё, для решения ряда задач (особенно рекурсивных) вам сможет понадобиться ссылочный список (linked list), Допустим у вашего класса TMyClass есть свойство NextLinked того же типа TMyClass и методы AddLink, DeleteLink. При создании первого экземпляра TMyClass внешним кодом в вашей программе, свойство NextLinked возвращает ссылку на экземпляр из которого оно и вызвано или nil в зависимости от ваших задач. При добавлении экземпляров через метод AddLink в свойство NextLinked записывается ссылка на созданный дочерний экземпляр, а в дочернем экземпляре в том же свойстве записывается ссылка, которая была у экземпляра-родителя. Так список элементов содержит сам себя, не нуждается в объекте-коллекции. Он может быть однонаправленным, может быть двунаправленным. Может быть зацикленным. Может быть многомерным. Обожаю ссылочные списки! :roll:
Аватара пользователя
fgcsDenis
незнакомец
 
Сообщения: 2
Зарегистрирован: 06.11.2015 18:12:07

Re: Как правильно работать с динамическим количеством классо

Сообщение vitaly_l » 06.11.2015 22:10:41

Sharfik писал(а):// Count=3? или от 1...до 1000000? Тормозить будет, если второй вариант. Либо заранее выделять больше, либо TList использовать.

Про: TList TObjectList, TClassList и NextLinked - понятно.
Но почему она будет тормозить, если 1 000 000 - непонятно?
Или точнее почему она не будет тормозить в TList когда 1 000 000 ?
Или ещё точнее в каких конкретно ситуациях?


.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Как правильно работать с динамическим количеством классо

Сообщение tema » 07.11.2015 02:44:57

Код: Выделить всё
begin
......
  ShowMessage('N0 = ' + DynArrayClass[0].read_str);
  ShowMessage('N1 = ' + DynArrayClass[1].read_str);
  ShowMessage('N2 = ' + DynArrayClass[2].read_str);
  DynArrayClass[0].free;
  DynArrayClass[1].free;
  DynArrayClass[2].free;

end;
tema
постоялец
 
Сообщения: 376
Зарегистрирован: 24.03.2011 20:19:27

Re: Как правильно работать с динамическим количеством классо

Сообщение zub » 07.11.2015 12:23:00

vitaly_l
в случае большого количества однотипных данных стоит посмотреть в сторону от классов, те же рекорды или объекты автоматически дадут выигрыш в производительности из за несколько другого внутреннего устройства
>>Или точнее почему она не будет тормозить в TList когда 1 000 000 ?
Любая линейная структура начинает тормозить при увеличении количества элементов, TList имеет свойство Capacity что позволяет ему перераспределять память пореже чем простому массиву, но это спасает только при заполнении массива. При дальнейшей работе тормозить будут одинаково - например поиск нужного элемента будет одинаково медленным
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: Как правильно работать с динамическим количеством классо

Сообщение vitaly_l » 07.11.2015 13:09:54

zub писал(а):TList имеет свойство Capacity что позволяет ему

Спасибо, круто Capacity - вкусный "орешек", пойду разгрызу...
zub писал(а):например поиск нужного элемента будет одинаково медленным

Спасибо - после этого вопросы исчезли сами собой, но Capacity я всё равно разгрызу...
Всем хорошего настроения!
.
Аватара пользователя
vitaly_l
долгожитель
 
Сообщения: 3333
Зарегистрирован: 31.01.2012 16:41:41

Re: Как правильно работать с динамическим количеством классо

Сообщение nic1982 » 11.11.2015 23:53:14

Хочу отчитаться о проделанной работе.

Динамический массив с классами оправдал себя в простом случае, описание ниже.
Есть некая территория, эта территория разбита на несколько районов, в каждом районе несколько филиалов.
Необходимо было создавать отчеты по районам, чуть меньше 10 разных типов отчетов.
Некоторые отчеты простые, другие же более сложные.
Простые это те в которых сводная информация по всем филиалам в районе.
Сложные же те в которых информация по каждому филиалу отдельно.
В простых одна страница или несколько страниц если отчет длинный.
В сложных несколько страниц, страница на филиал или несколько страниц если отчет длинный.
Количество филиалов колеблется в зависимости от районов, филиалов максимум несколько десятков, минимум пару штук.
Все классы рождаются и умирают вместе, если бы это было не так то динамический массив с классами не подошел бы.
Почему я выбрал классы а не рекорды ?
Потому что проще, разделить по отчет или филиал-отчет.
Разделение чисто для своего удобства на данные и алгоритмы которые их обрабатывают.
ООП все таки очень удобно, когда имеешь дело с со сложными и большими вещами.
Я люблю рекорды и использую их внутри классов.
Плюсом можно реализовать многопоточность.
Абстракция: на рекордах получились бы бараки,
на классах получились индивидуальные квартиры (у кого многоэтажный дом, у кого просто дом).
В будущем добавятся новые типы отчетов.

Сейчас программа выглядит так (псевдокод):
Код: Выделить всё
Модуль Отчет1
ТОтчет1=класс
  данные
  методы

Модуль Отчет2_по_филиалу
ТОтчет2_по_филиалу=класс
  данные
  методы

Модуль Отчет2
ТОтчет2=класс
  данные : динамический массив ТОтчет2_по_филиалу // вот и он динамический массив классов
  методы

Модуль Главный
   Отчет1 : ТОтчет1
   Отчет2 : ТОтчет2

   Отчет1:=ТОтчет1.Создать
   Отчет2:=ТОтчет2.Создать

   Отчет1.СобратьДанные
   Отчет2.СобратьДанные   
   
   Отчет1.СохранитьПоказатьРаспечататьОтчет 
   Отчет2.СохранитьПоказатьРаспечататьОтчет
   
   Отчет1.Удалить
   Отчет2.Удалить
nic1982
новенький
 
Сообщения: 48
Зарегистрирован: 17.05.2011 16:34:05


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 225

Рейтинг@Mail.ru