Страница 1 из 1

академический вопрос по работе с объектом

СообщениеДобавлено: 04.11.2014 01:08:18
Фишер
Мир дому Вашему!
Спасибо, всем кто помог разобраться в прошлом вопросе, теперь созрел новый... возможно на него ответ известен давно в каком-нибудь паттерне, но я разобраться не смог, требуется наиболее красивое/изящное решение, итак к сути... чтобы предметно говорить приведу код, есть модуль A:
Код: Выделить всё
unit A;

interface
Ta = class
public
  procedure Work;
end;

implementation
procedure Ta.Work;
begin
   while is_something_happened do;
end;
end.     

и соответственно приложение
Код: Выделить всё
Uses A;
var
  myobject:Ta;

procedure myfunc();
begin
end;

begin
  myobject:=ta.create;
  while something do myobject.work;
  myobject.free;
end. 


Вопрос, собственно такой, в модуле A, где описан класс по is_something_happened проверяется наступление некого внешнего события (по ожиданию его прихода), которое гарантированно случиться, при этом пока происходит ожидание хотелось бы выполнять свою функцию myfunc из области видимости программы, в которой гарантированно не нагруженные функции (например Application.ProccessMessages, просчёт прогрессбара или что-то своего), как изящнее всего это сделать? мне в голову пришёл только вариант с указателем на процедуру, вот привожу пример рабочего кода, как я эту идею реализовал на простом примере:

Код: Выделить всё
unit A;
interface
type
pfunc = procedure();

Ta = class
  myfunc:pfunc;
  constructor a(test:pfunc);
public
  procedure Work;
end;

implementation

constructor Ta.a(test:pfunc);
begin
     myfunc:=test;
end;


procedure Ta.Work;
begin
      myfunc;
end;
       

-----------------------------------------       

Uses A;
var
  myobject:Ta;
  tmp:byte=0;

procedure myfunc();
begin
  inc(tmp);
  writeln(tmp);
end;

begin
  myobject:=ta.a(@myfunc);
  while tmp<100 do myobject.work;
  myobject.free;
  Readln();
end.   


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

Re: академический вопрос по работе с объектом

СообщениеДобавлено: 06.11.2014 12:44:44
Дож
Ещё есть такое красивое слово как «нить» («thread» aka «поток). Можно запускать функции в двух разных тредах.

Ожидать сообщение можно в неблокирующем режиме и выполнять myfunc по частям:
Код: Выделить всё
while True do
  if myobject.Пришло_Соощение then begin
    myobject.Work;
  end else begin
    Выполнить следующую часть в myfunc;
  end;

Re: академический вопрос по работе с объектом

СообщениеДобавлено: 06.11.2014 14:15:17
hinst
ну раз уж речь о красивых-изящных решениях и паттернах, могу сказать что Application.ProcessMessages это просто ужас, использовать эту "фичу" крайне не рекомендуется, надо засунуть деятельность в отдельный поток, а трогать Application.ProcessMessages нельзя потому что это антипаттерн

Re: академический вопрос по работе с объектом

СообщениеДобавлено: 10.11.2014 16:28:40
ger0strat
Не знаю, чем вам не нравится ваше решение, но как вариант:
Код: Выделить всё
unit A;
interface
type
  Ta = class
  protected
    procedure DoSometh();virtual;
  public
    procedure Work;
  end;

implementation

procedure Ta.Work;
begin
  DoSometh();
end;

procedure Ta.DoSometh();
begin
  //do nothing
end;

end.
       

-----------------------------------------       

Uses A;
type
  TMyA=class(Ta)
  protected
    procedure DoSometh();override;
  end;

var
  myobject:TMyA;
  tmp:byte=0;

procedure TMyA.DoSometh();
begin
  inc(tmp);
  writeln(tmp);
end;

begin
  myobject:=TMyA.Create();
  while tmp<100 do myobject.work;
  myobject.free;
  Readln();
end.