Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Процедуры и функции как метод класса, или... Процедуры и функции как метод класса, и 
:(
    Опции темы
Pcrepair
Дата 3.9.2013, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 16.1.2011

Репутация: нет
Всего: нет



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

Для улучшения восприятия кода(и удаления повторов кода Ф и П) в принципе можно вынести процедуры и функции в отдельный модуль
(подключив CoInitialize(nil); код CoUninitialize; с учетом вызова подпрограмм из потоков)

Вопрос: как правильно сделать? оставить подпрограммы методами классса или вынести в отдельный модуль? наверняка есть какието косяки
--------------------
Сборник рабочего кода Процедур и Функций DelPhi     http://validcoderepo.narod.ru/
PM MAIL WWW   Вверх
Illusion Dolphin
Дата 3.9.2013, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 5
Всего: 63



Цитата

в отдельный модуль
(подключив CoInitialize(nil); код CoUninitialize; с учетом вызова подпрограмм из потоков)

CoInitialize/CoUninitialize лучше делать в потоке, имхо

Цитата

ставить подпрограммы методами классса или вынести в отдельный модуль?

Зависит от логики. Если классы большие то лучше разбивать.


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Poseidon
Дата 3.9.2013, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 9
Всего: 133



Цитата(Pcrepair @  3.9.2013,  15:20 Найти цитируемый пост)
как правильно сделать? оставить подпрограммы методами классса или вынести в отдельный модуль?
Если все сделано правильно, то оба варианта имеют право на существование. Но если мы бьемся за улучшение восприятия кода, то лучше (на мой взгляд) все подпрограммы, которые связаны с работой нити, оставить в методах нити.



--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Pcrepair
Дата 3.9.2013, 19:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 16.1.2011

Репутация: нет
Всего: нет



вопрос был: наверняка есть какието косяки???

так значит, косяков нет? 
просто обложить вызов процедуры CoInitialize(nil); CoUninitialize;(ну там используется АКтивХ и вызов Mlang.dll), а если нет АктивХ то можно обойтить и без(если компиллятор не скажет что нужно)

ту кое кто кое где утверждал идею о том что лучше чтоб все подпрограммы были методами класса

другие же утверждают: неважно где лежит подпрограмма, важно откуда она вызывается, что входит в противоречие с первым высказыванием

кто имеет опыт по этому вопросу?
--------------------
Сборник рабочего кода Процедур и Функций DelPhi     http://validcoderepo.narod.ru/
PM MAIL WWW   Вверх
Illusion Dolphin
Дата 3.9.2013, 21:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 5
Всего: 63



Если работа идёт с ActiveX то каждый поток должен вызвать CoInitialize до работы с АКтивХ  и CoUninitialize после. Это лучше оставить в потоке, избавив функции он необходимости "думать" о том, стоит или не стоит делать CoInitialize. Остальное можно (<> нужно) выносить в любый другие модули. Конкретное решение о выносе кода принимается исходя из личного опыта и архитектуры программы, логики кода. 


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Poseidon
Дата 4.9.2013, 07:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

Репутация: 9
Всего: 133



Цитата(Pcrepair @ 3.9.2013,  19:17)
ту кое кто кое где утверждал идею о том что лучше чтоб все подпрограммы были методами класса

другие же утверждают: неважно где лежит подпрограмма, важно откуда она вызывается, что входит в противоречие с первым высказыванием

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

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

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


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Pcrepair
Дата 4.9.2013, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 16.1.2011

Репутация: нет
Всего: нет



Цитата(Illusion Dolphin @ 3.9.2013,  21:08)
Если работа идёт с ActiveX то каждый поток должен вызвать CoInitialize до работы с АКтивХ  и CoUninitialize после.

что это значит? сейчас так:

Код

(*тут организация класса потока*)
implementation

function TLoader.LoadURL(const AUrl: String):string;
var
ServerCharset:string;
Buffer: RawByteString;
Lst:TStringList;
begin
  FIdHttp := TIdHTTP.Create(nil);                   (*создаем загрузчик*)
  FSSL := TIdSSLIOHandlerSocketOpenSSL.Create;      (*создаем секретный сокет*)
  FStream := TMemoryStream.Create;
  Lst:=TStringList.Create;
  try
    try
      FIdHttp.IOHandler:=FSSL;                
      (*---------настройка параметров закачки-----------*)
      FIdHttp.Request.UserAgent:=GetRandomUserAgent;
      FIdHttp.ConnectTimeout:=10000;
      FIdHttp.ReadTimeout:=10000;
      FIdHttp.HandleRedirects:=True;
      FIdHttp.Request.Connection :='keep-alive';
      FIdHttp.HTTPOptions:=FIdHttp.HTTPOptions+[hoNoParseMetaHTTPEquiv];
      FIdHttp.Get(AUrl,FStream);     
      FStream.Position:=0;            
      Lst.LoadFromStream(FStream);
      Buffer:=Lst.Text;

      CoInitialize(nil);                (*вызов нужен для использования в потоке СОМ-объектов*)
        Result:=DelJS(CodePageConvert(Buffer));
      CoUninitialize;

    except
      Result:=AnsiLowerCase(AUrl+(' = Total Error'));
      if (FIdHttp.Response.ResponseCode = 200)
      then
      Push(AUrl);                               
      Exit;                                          
    end;
  finally
    FreeAndNil(FIdHttp);
    FreeAndNil(FSSl);
    FreeAndNil(FStream);
    FreeAndNil(Lst);
  end;
end;


function TLoader.CodePageConvert(const Page:RawByteString):string;
var Charset: Cardinal;
begin
  try
    Charset := DetectHTMLCharset(Page);  (*это уже в отдельном модуле вне класса и работает с Mlang.dll*)
  except
    Charset:=1251;
  end;
  Result:= AnsiLowerCase(RawHTMLToHTML(Page, Charset));  (*это уже в отдельном модуле вне класса и работает с Mlang.dll*)
end;

то есть CoInitialize - CoUninitialize обложено только вызов функции использующей АктивХ
есть какие то другие варианты?
--------------------
Сборник рабочего кода Процедур и Функций DelPhi     http://validcoderepo.narod.ru/
PM MAIL WWW   Вверх
Illusion Dolphin
Дата 4.9.2013, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1198
Регистрация: 3.5.2003

Репутация: 5
Всего: 63



Если TLoader это поток, то это значит, что можно сделать так:

Код

TLoader.Execute;
begin
  CoInitialize(nil);
  try
    // тут всё остальное, в том числе LoadURL итд и это можно вынести куда угодно забыв про CoInitialize/CoUninitialize
  finally
    CoUninitialize;
  end;
end;


В таком случае если функции АктивХ вызываются несколько раз не тратятся ресурсы за поднятие и остановку АктивХ. В таком случае всё остальное можно вынести в другие модули и забыть об инициализации и остановке АктивХ. 

P.S. Возможны проблемы если АктивХ должен быть инициализирован по-разному (см. CoInitializeEx) для разных функций, а если всем хватает обычного CoInitialize от и нет проблем.


--------------------
В мире всего две бесконечности: вселенная и человеческая глупость... На счёт вселенной я не уверен.
Шифрование и организация фотографий - Photo Database 4.5
PM MAIL WWW ICQ   Вверх
Pcrepair
Дата 4.9.2013, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 209
Регистрация: 16.1.2011

Репутация: нет
Всего: нет



теперь стало понятнее. спасибо
--------------------
Сборник рабочего кода Процедур и Функций DelPhi     http://validcoderepo.narod.ru/
PM MAIL WWW   Вверх
mes
Дата 4.9.2013, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 1
Всего: 250



Цитата(Poseidon @  4.9.2013,  06:41 Найти цитируемый пост)
Поэтому лично мен мнение - класс должен быть единым целым и его составляющие должны быть внутри его

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



--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0521 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.