示例:Smalltalk/V的应用结构 说明: Windows下的Smalltalk/V的应用结构基于中介者结构。在这个环境中,一个应用由一个包含一组窗格(pane)的窗口组成。ViewManager类负责窗格间的协调工作。ViewManager是一个中介者,而每一个窗格只知道它的viewmanager,它被看作该窗格的"主人"。窗格不直接互相引用。Smalltalk/V的Pane-ViewManager通信使用一种事件机制。 下面的对象图显示了一个应用运行时刻的情景。 代码: unit uPane; interface uses Classes,Dialogs, Contnrs; type TViewManager = class; TPane = class private FOwner: TViewManager; FPaneName: string; public constructor Create(const APaneName: string;AOwner: TViewManager); //--- property PaneName: string read FPaneName write FPaneName; end; TTextPane = class(TPane) private FOnChanged: TNotifyEvent; FText: string; procedure SetText(const Value: string); public property Text: string read FText write SetText; property OnChanged: TNotifyEvent read FOnChanged write FOnChanged; end; TListBox1 = class(TPane) private FOnChanged: TNotifyEvent; public procedure Add(s: string); //--- property OnChanged: TNotifyEvent read FOnChanged write FOnChanged; end; TButton1 = class(TPane) private FOnClick: TNotifyEvent; public procedure Click; //--- property OnClick: TNotifyEvent read FOnClick write FOnClick; end; TListPane = class(TPane) private FOnSelect: TNotifyEvent; public procedure Select; property OnSelect: TNotifyEvent read FOnSelect write FOnSelect; end; TViewManager = class private FPanes:TObjectList; public constructor Create; destructor Destroy; override; //--- procedure AddSubPane(APane:TPane); end; TConcreteViewManager = class(TViewManager) private FTextPane: TTextPane; FListBox: TListBox1; FButton: TButton1; FListPane: TListPane; procedure ListSelect(Sender: TObject); procedure TextChanged(Sender: TObject); procedure ListBoxChanged(Sender: TObject); procedure ButtonClick(Sender: TObject); public constructor Create; //--- procedure Test; end; procedure Test; implementation procedure Test; var AViewManager: TConcreteViewManager; begin AViewManager := TConcreteViewManager.Create; AViewManager.Test; AViewManager.Free; end; procedure TTextPane.SetText(const Value: string); begin FText := Value; if Assigned(FOnChanged) then FOnChanged(self); end; procedure TListBox1.Add(s: string); begin if Assigned(FOnChanged) then FOnChanged(self); end; procedure TButton1.Click; begin if Assigned(FOnClick) then FOnClick(self); end; { TListPane } procedure TListPane.Select; begin if Assigned(FOnSelect) then FOnSelect(self); end; constructor TPane.Create(const APaneName: string;AOwner: TViewManager); begin FOwner := AOwner; FPaneName := APaneName; end; procedure TConcreteViewManager.ButtonClick(Sender: TObject); begin ShowMessage(FButton.PaneName); end; constructor TConcreteViewManager.Create; begin inherited; //--- FTextPane := TTextPane.Create('myTextPane',self); FTextPane.OnChanged := self.TextChanged; self.AddSubPane(FTextPane); //--- FListBox := TListBox1.Create('myListBox',self); FListBox.OnChanged := self.ListBoxChanged; self.AddSubPane(FListBox); //--- FButton := TButton1.Create('myButton',self); FButton.OnClick := self.ButtonClick; self.AddSubPane(FButton); //--- FListPane := TListPane.Create('myListPane',self); FListPane.OnSelect := self.ListSelect; self.AddSubPane(FListPane); end; procedure TConcreteViewManager.ListBoxChanged(Sender: TObject); begin ShowMessage(FListBox.PaneName); end; procedure TConcreteViewManager.ListSelect(Sender: TObject); begin ShowMessage(FListPane.PaneName); end; procedure TViewManager.AddSubPane(APane: TPane); begin FPanes.Add(APane); end; constructor TViewManager.Create; begin FPanes := TObjectList.Create; end; destructor TViewManager.Destroy; begin FPanes.Free; //--- inherited; end; procedure TConcreteViewManager.Test; begin FTextPane.Text := '123'; end; procedure TConcreteViewManager.TextChanged(Sender: TObject); begin ShowMessage(FTextPane.Text); end; end.