由于Delphi不支持多重继承,在实现Observer模式的时候,TObserver就只能从TComponent或者从某个具体的可视控件(例如TStringGrid)继承下来。这样的问题是,如果从TComponent继承下来,可以复用会更方便些,可是,这也意味着需要自己重新写用于显示的控件;如果直接从某个具体的控件继承下来,那样复用又会受到影响,对于每一个风格的控件,需要不同的父控件。
如果使用接口来模拟多重继承来解决上面的问题,在实现的时候,总是有些问题,甚至很不好弄。请求哪位达人指点一下如何实现。
如果使用接口来模拟多重继承来解决上面的问题,在实现的时候,总是有些问题,甚至很不好弄。请求哪位达人指点一下如何实现。
解决方案 »
- 问个问题 mapxtreme 支持哪个版本的delphi
- 给数据值字段赋空值
- TDataclass在哪个单元里呀?
- 请问如何相隔很远的两个分厂的数据如何即时更新。。。。。。。。。另诚交长期兼职DELPHI+MSSQL程序员
- 关于查询的小问题!!!指出下列程序的错误之处?
- 关于显示特大字体的问题
- 在Delphi6中怎么样让adoquery控件识别Unicode呢?(请具体举例子)分不够再加!
- WebServer 与 Application Server 的通讯问题。请问这是不是控件的缺陷?
- Delphi Int128 问题求助
- 怎样往combobox的items里添加项目?
- 求区域填充的八联通算发?
- 请问如何获得组合控件上某个控件的句柄
可以很肯定地说,必须使用接口。
////
由于Delphi不支持多重继承,在实现Observer模式的时候,TObserver就只能从TComponent或者从某个具体的可视控件(例如TStringGrid)继承下来。这样的问题是,如果从TComponent继承下来,可以复用会更方便些,可是,这也意味着需要自己重新写用于显示的控件;如果直接从某个具体的控件继承下来,那样复用又会受到影响,对于每一个风格的控件,需要不同的父控件。
如果使用接口来模拟多重继承来解决上面的问题,在实现的时候,总是有些问题,甚至很不好弄。请求哪位达人指点一下如何实现。
////
您的以上感觉我不知道是从何来的?给我的感觉是您不仅仅对模式没有概念,对OO也没有一点概念(请包涵我的措辞)。不过还是就事论事各您一个完整的答案。unit Pattern.SubjectIntf;interfaceuses
Pattern.ObserverIntf;type
ISubject = interface
['{13BF13FC-09A5-4321-888C-9A29BD0AE893}']
procedure Attach(const Observer: IObserver);
procedure Detach(const Observer: IObserver);
procedure BeginUpdate;
procedure EndUpdate;
procedure Notify;
end;implementationend.unit Pattern.ObserverIntf;interfacetype
IObserver = interface
['{D8BC1C6F-074A-40F6-AD00-05A16159C26C}']
procedure Update(const Subject: IInterface);
end;implementationend.unit Pattern.SubjectImpl;interfaceuses
Classes, Pattern.SubjectIntf, Pattern.ObserverIntf;type
TSubject = class(TInterfacedObject, ISubject)
private
FObservers: IInterfaceList;
FController: Pointer;
FUpdateCount: Integer;
function GetController: IInterface;
protected
//ISubject
procedure Attach(const Observer: IObserver);
procedure Detach(const Observer: IObserver);
procedure BeginUpdate;
procedure EndUpdate;
procedure Notify;
public
constructor Create(const Controller: IInterface); virtual;
destructor Destroy; override;
end;implementation{ TSubject }procedure TSubject.Attach(const Observer: IObserver);
begin
if FObservers = nil then
FObservers := TInterfaceList.Create;
if FObservers.IndexOf(Observer) < 0 then
FObservers.Add(Observer);
end;procedure TSubject.BeginUpdate;
begin
Inc(FUpdateCount);
end;constructor TSubject.Create(const Controller: IInterface);
begin
inherited Create;
FController := Pointer(Controller);
FUpdateCount := 0;
end;destructor TSubject.Destroy;
begin
inherited;
end;procedure TSubject.Detach(const Observer: IObserver);
begin
if FObservers <> nil then
begin
if FObservers.IndexOf(Observer) >= 0 then
begin
FObservers.Remove(Observer);
if FObservers.Count = 0 then
FObservers := nil;
end;
end;
end;procedure TSubject.EndUpdate;
begin
Dec(FUpdateCount);
if FUpdateCount = 0 then
Notify;
end;function TSubject.GetController: IInterface;
begin
Result := IInterface(FController);
end;procedure TSubject.Notify;
var
Idx: Integer;
begin
if FObservers <> nil then
for Idx := 0 to Pred(FObservers.Count) do
if FObservers[Idx] <> nil then
(FObservers[Idx] as IObserver).Update(GetController);
end;end.unit Frame.BizWindowsObserverFrame;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Pattern.ObserverIntf;
type
TBizWindowsObserverFrame = class(TFrame, IObserver)
private
//IObserver
procedure IObserver.Update = ObserverUpdate;
procedure ObserverUpdate(const Subject: IInterface);
procedure ObserverRegister;
procedure ObserverUnRegister;
protected
public
end;
...................