Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.12.02;
Скачать: CL | DM;

Вниз

EExternalException..   Найти похожие ветки 

 
pathfinder ©   (2007-11-09 11:10) [0]

Добрый день.
Есть форма на которой edit и label. При изменении значения в edit-e оно должно меняться и label-е. Попытался сделать это с помощью шаблона Наблюдатель. Взял его реализацию из BDS2006. В методе NotifyObservers возникает EEXternalException при попытке вызвать метод Update элемента списка. Подскажите пожалуйста, в чем моя ошибка?

Код самой программы:
var
 ProgParams: TProgParams;
 ProgView: TProgView;
begin
 ProgParams := TProgParams.Create;
 ProgView := TProgView.Create(ProgParams);
 ProgView.Show;
end.

Реализация классов:
type
 TSubject = class;

 IObserver = interface
   procedure Update(ASubject :TSubject);
 end;

 TSubject = class
 strict private var
   FObservers:TList;
 strict protected
   procedure NotifyObservers;
 public
   constructor Create;
   procedure Attach(AObserver :IObserver);
   procedure Detach(AObserver :IObserver);
 end;

 TProgParams = class(TSubject)
 strict private
   FTest: string;
 public
   function GetParam(const Name: string): string;
   procedure SetParam(const Name: string);
 end;

 TProgView = class(TInterfacedObject, IObserver)
 strict private
   FSubject: TProgParams;
   FViewForm: TViewForm;

   procedure Refresh;
   procedure OnSetParam(Sender: TObject);
 public
   constructor Create(ASubject: TProgParams);
   destructor Destroy;

   procedure Show;

   procedure Update(ASubject :TSubject);
 end;

implementation

constructor TSubject.Create;
begin
 inherited Create;
 FObservers := TList.Create;
end;

procedure TSubject.Attach(AObserver :IObserver);
begin
 FObservers.Add(@AObserver);
end;

procedure TSubject.Detach(AObserver :IObserver);
var
 idx :Integer;
begin
 idx := FObservers.IndexOf(@AObserver);
 If idx <> -1 Then
 begin
   FObservers.Delete(idx);
 end;
end;

procedure TSubject.NotifyObservers;
var
 Current :^IObserver;
begin
 for Current in FObservers do
   Current.Update(self);
end;

constructor TProgView.Create(ASubject: TProgParams);
begin
 FSubject := ASubject;
 FSubject.Attach(self);
 FViewForm := TViewForm.Create(nil);
 FViewForm.edtTest.OnChange := OnSetParam;
end;

destructor TProgView.Destroy;
begin
 FSubject.Detach(self);
 FViewForm.Free;
end;

procedure TProgView.OnSetParam(Sender: TObject);
begin
 FSubject.SetParam(FViewForm.edtTest.Text);
end;

procedure TProgView.Refresh;
var
 s: string;
begin
 s := FSubject.GetParam("");
 FViewForm.edtTest.Text := s;
 FViewForm.lblTest.Caption := s;
end;

procedure TProgView.Show;
begin
 FViewForm.ShowModal;
end;

procedure TProgView.Update(ASubject :TSubject);
begin
 Refresh;
end;

{ TProgParams }

function TProgParams.GetParam(const Name: string): string;
begin
 Result := FTest;
end;

procedure TProgParams.SetParam(const Name: string);
begin
 FTest := Name;
 NotifyObservers;
end;


 
Dib@zol ©   (2007-11-09 11:15) [1]

> [0] pathfinder ©   (09.11.07 11:10)
> Добрый день.
> Есть форма на которой edit и label. При изменении значения в edit-e оно должно меняться и label-е.

И ради ЭТОГО нужен был весь тот код???
/me Потерял сознание


 
pathfinder ©   (2007-11-09 11:18) [2]


> И ради ЭТОГО нужен был весь тот код???


Скорей наоборот.


 
Ega23 ©   (2007-11-09 11:19) [3]


unit Unit1;

interface

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

type
 TForm1 = class(TForm)
   Edit1: TEdit;
   Label1: TLabel;
   procedure Edit1Change(Sender: TObject);
   procedure FormCreate(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Edit1Change(Sender: TObject);
begin
 Label1.Caption := Edit1.Text;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Edit1.Text := "";
end;

end.


Всё.


 
pathfinder ©   (2007-11-09 11:22) [4]


> Ega23 ©   (09.11.07 11:19) [3]
>
>


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


 
ЮЮ ©   (2007-11-09 11:22) [5]

> [3] Ega23 ©   (09.11.07 11:19)


> Всё.


Не стыдно, это же "батонокидательство"!
А тут речь о Наблюдателе.
З.Ы. Не зря наблюдение за наблюдающим стоит дороже :)


 
Dib@zol ©   (2007-11-09 11:24) [6]

А нафика изобретать велосипед с треугольными колёсами? Поищи лучше в гугле задачи на применение этого шаблона, и не майся дурью. ЗЫ Мне аж плохо стало, когда я все эти навороты увидал...


 
Ega23 ©   (2007-11-09 11:24) [7]


> Не стыдно, это же "батонокидательство"!


Это наиболее быстрый и дешёвый способ решения КОНКРЕТНОЙ проблемы.
Остальное - побоку.


 
pathfinder ©   (2007-11-09 11:25) [8]


> А нафика изобретать велосипед с треугольными колёсами? Поищи
> лучше в гугле задачи на применение этого шаблона, и не майся
> дурью. ЗЫ Мне аж плохо стало, когда я все эти навороты увидал.
> ..


Так какая разница какая задача? Вопрос-то в реализации..


 
Dib@zol ©   (2007-11-09 11:27) [9]

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


 
pathfinder ©   (2007-11-09 11:28) [10]


> Попробуй измерить время выполнения твоего алгоритма и предложенного
> товаришшем Ega23. Последний будет работать на порядок быстрее.
>  Не для того этот шаблон создавался, чтоб на нём такое вытворяли.
>


Я же говорю, что это не реальная задача, а просто для примера.


 
pathfinder ©   (2007-11-09 11:30) [11]

И потом вопрос ведь не в том, как оптимальней решить ЭТУ задачу, а что не так в реализации?


 
icWasya ©   (2007-11-09 12:51) [12]

а почему так
FObservers.Add(@AObserver);

а не так
FObservers.Add(AObserver);
???


 
Anatoly Podgoretsky ©   (2007-11-09 12:55) [13]


> Я же говорю, что это не реальная задача, а просто для примера.

Тренируйся на кошках.


 
pathfinder ©   (2007-11-09 12:57) [14]


> Anatoly Podgoretsky ©   (09.11.07 12:55) [13]


Большое спасибо! Это самый ценный совет.


 
pathfinder ©   (2007-11-09 12:57) [15]


> icWasya ©   (09.11.07 12:51) [12]
>
> а почему так
> FObservers.Add(@AObserver);
>
> а не так
> FObservers.Add(AObserver);
> ???


[Pascal Error] Unit2.pas(60): E2010 Incompatible types: "Pointer" and "IObserver"


 
Сергей М. ©   (2007-11-09 13:01) [16]


> pathfinder ©   (09.11.07 12:57) [15]


Ну так сделай FObservers типа TInterfaceList, бо на то этот тип и предназначен.
Или приводи явно интерфейсный тип к указательному.


 
Anatoly Podgoretsky ©   (2007-11-09 13:04) [17]

> pathfinder  (09.11.2007 12:57:14)  [14]

Конечно, надо делать более реальную задачу.


 
pathfinder ©   (2007-11-09 13:05) [18]


> Конечно, надо делать более реальную задачу.


Не хотелось браться за сложное, если даже с простым не получается.


 
pathfinder ©   (2007-11-09 13:07) [19]


> Сергей М. ©   (09.11.07 13:01) [16]
>
>
> > pathfinder ©   (09.11.07 12:57) [15]
>
>
> Ну так сделай FObservers типа TInterfaceList, бо на то этот
> тип и предназначен.
> Или приводи явно интерфейсный тип к указательному.


Так здесь то вроде все нормально..

Ошибка здесь:
TSubject.NotifyObservers;
Current.Update(self);


 
Сергей М. ©   (2007-11-09 13:14) [20]


> здесь то вроде все нормально


Как же нормально, если при компиляции процитированных тобой в [15] строк компилятором обнаружена тобой же процитированная ошибка ?


 
pathfinder ©   (2007-11-09 13:19) [21]


> Как же нормально, если при компиляции процитированных тобой
> в [15] строк компилятором обнаружена тобой же процитированная
> ошибка ?
>


Это если так FObservers.Add(AObserver);

А если FObservers.Add(@AObserver); то все ок.


 
Сергей М. ©   (2007-11-09 13:31) [22]


> если FObservers.Add(@AObserver); то все ок


С т.з. компилятора - да.
А с т.з. происходящего при этом в ран-тайм - это полная фигня, о чем тебе и сообщает возникшее при этом исключение.

Так что вопрос к тебе в [12] вполне резонен.


 
pathfinder ©   (2007-11-09 13:37) [23]


> Так что вопрос к тебе в [12] вполне резонен.


Это готовая реализация этого шаблона из делфи. Получается они неправильно сделали?


 
pathfinder ©   (2007-11-09 13:46) [24]


> Сергей М. ©   (09.11.07 13:01) [16]
>
> Или приводи явно интерфейсный тип к указательному.


Воспользовался вашим советом и все заработало:)

Всем спасибо!



Страницы: 1 вся ветка

Текущий архив: 2007.12.02;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.023 c
4-1179507014
Bacardi
2007-05-18 20:50
2007.12.02
Очередь печати


8-1170431716
Jimmy
2007-02-02 18:55
2007.12.02
Не работает пунктир для толстых линий.


15-1194252709
andreoman
2007-11-05 11:51
2007.12.02
программка фиксирующа обращение к порту ПК


15-1194247275
Juice
2007-11-05 10:21
2007.12.02
В чем вести проект программисту


2-1194000155
Ega23
2007-11-02 13:42
2007.12.02
как такой AV ловить?