views:

120

answers:

2

maybe i dont know delphi all that well, however i wish to ask you:

at this site : http://blogs.teamb.com/joannacarter/2004/06/30/690 i found an implemetation of observer pattern based on iterface.

when doing attach , there is a call to this:

procedure TSubject.Attach(Observer: IObserver);
begin
    if fObservers = nil then
      fObservers := TInterfaceList.Create;
    fObservers.Add(AObserver);
    Notify;
end;

and in the detach it has the code

procedure TSubject.Detach(Observer: IObserver);
begin
   if fObservers <> nil then
    begin
      fObservers.Remove(AObserver);
      if fObservers.Count = 0 then
        fObservers := nil;
    end;
end;

should it be :

procedure TSubject.Detach(Observer: IObserver);
begin
   if fObservers <> nil then
    begin
      fObservers.Remove(AObserver);
      if fObservers.Count = 0 then begin
        fObservers.Free; 
        fObservers := nil;
      end;
    end;
end;
+5  A: 

There is no need to add fObservers.Free; statement. IInterface will take care of adding and releasing the fObservers .

Delphi uses _AddRef and _Release to manage the lifetime of interfaced objects.

When you assign an interface reference to an interface variable, Delphi automatically calls _AddRef.

When the variable goes out of scope, Delphi automatically calls _Release.

For more info go through this link.

Bharat
OMG it has a garbage collector? why didn't they implement it all, and all around?
none
Delphi is not a complete garbage collection language, user-defined types should be manually allocated and deallocated. It only provide automatic collection, for a few built-in types, such as strings, dynamic arrays and interfaces for ease of use.
Bharat
@none You can get similar results to garbage collection by liberal use of interfaces. This means all your classes would need to implement at least one interface: `TMyClass = class(TInterfacedObject, IMyInterface)`... and all references should be interface references: `MyObject: IMyInterface`. Note that circular references can cause problems with reference counting.
codeelegance
@none: two reasons: because it is not garbage collection, but reference counting, just like COM and other languages that implement interfaces like COM does. The Delphi object model is older than the Delphi interface implementation (COM got wildly popular after the introduction of ActiveX, which postdates Delphi 1 and 2). The Delphi team could not afford to rewrite the VCL/RTL from scratch to be fully interface based (like Microsoft never did that with MFC for the same reasons). Furthermore, reference counting also has problems that garbage collection does not have. Ask a new question for that.
Jeroen Pluimers
@Jeroen reference counting is a garbage collector algorithm. there for Delphi has garbage collector. and @codeelegance having problem with reference counting is a "not well implement" garbage collector, well at least that is my opinion. and garbage collection over the stack is not garbage collection.
none
@none: Wow, even though the drawbacks, reference counting is indeed considered Garbage Collection (http://en.wikipedia.org/wiki/Reference_counting); I learned something new today, thanks! I think your "not well implemented" statement is to harsh; the reason reference counts can fail is usually because programmers fiddle with the mechanism (by either adding/removing references on purpose, or by mixing interfaces with manually freed objects). It is also the reason there are lots of problems in the COM world outside of Delphi: playing by the reference counting rules is hard for a lot of people.
Jeroen Pluimers
@Jeronen, well, it was harsh of me claiming "not well implemented", as its a problem with reference counting and not with there implementation. thanks :)
none
+6  A: 

No, it shouldn't, because as Bharat said, IInterface will take care of that. Note that fObservers is declared as IInterfaceList in the example you're reffering to. It's an interface. Interface variables in Delphi are akin to smart pointers in C++, they call _Addref and _Release on assignments automatically.

If fObservers was declared as TInterfaceList, on the other hand, then it would be an object, and objects don't do anything special on assignment, so it would have been correct to call Free.

himself
+1 for the remark *if fObservers was declared as TInterfaceList*.
The_Fox