很多朋友看了上次我寫的「創建良好設計的程式碼(基於Delphi/VCL)」後,對我說感覺上可以接受其中的觀點,但似乎說得太簡單,不夠具體;也有的朋友對其中的一個小例子有些異議。因此便有了此文。
上次,我舉的例子是這樣的:假設要從某處獲得一個字串列表,然後顯示於TListBox 中,我所推崇的程式碼是:
ObjectXXX := TObjectXXX.Create;
ListBox1.Items := ObjectXXX.GetStringList;
ObjectXXX.Free;
的確,我承認,單純從這三行程式碼來看,似乎有了「濫用物件」之嫌。也許是例子過於簡單,給人的感覺是TObjectXXX只有GetStringList這一個public成員函數,如果真的這樣的話,那可真是「濫用物件」了。類別是物件的抽象,而物件是由狀態和操作(也就是資料和對資料的操作)的集合組成。因此,沒有狀態的物件不是物件!沒有私有資料成員的類別的設計是失敗的設計(那不是類,而是介面了)。
好,下面我就舉一個詳細的例子來說明,如何將介面程式碼和功能程式碼分開。
假設我要做一個簡單的個人通訊錄管理軟體,很顯然,整個軟體分為兩部分:一部分是面像用戶的,也就是所謂界面部分,我可以提供四個按鈕(分別為“添加”、“刪除」、「修改」、「尋找」)和一個編輯框(顯示通訊錄資訊和接受使用者輸入)用於和使用者互動;另一部分是功能化的,也就是軟體內部的對於通訊錄的存取操作。
於是,有了一個TAddrBook類,它是功能化部分的抽象。
TAddrBook = class
PRivate
//一些私有成員
public
constructor Create;
destructor Destroy;override;
GetCount: Integer;
FindRecord(strString): Integer;
GetRecord(nIndex:Integer): String;
SetRecord(nIndex:integer; strRec:String): Boolean;
AddRecord(strRec:String): Boolean;
DelRecord(nIndex): Boolean;
//其它共有成員函數
end;
私有成員之所以無法確定,主要取決於這個類別的實作。
如此,可以將對通訊錄的存取操作的邏輯封裝。而介面部分的程式碼不會涉及這些存取邏輯。介面部分程式碼如下:
var
Form1: TForm1;
AddrBook: TAddrBook;
nCurRec: Integer;
implementation
procedure TForm1.FormCreate(Sender: TObject);
begin
AddrBook := TAddrBook.Create;
nCurRec := AddrBook.GetCount;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
AddrBook.Free;
end;
//新增按鈕
procedure TForm1.Button1Click(Sender: TObject);
begin
if not AddrBook.AddRecord(memo1.Text) then
ShowMessage("error");
end;
//刪除按鈕
procedure TForm1.Button2Click(Sender: TObject);
begin
if not AddrBook.DelRecord(nCurRec) then
ShowMessage("error");
end;
//修改按鈕
procedure TForm1.Button3Click(Sender: TObject);
begin
if not AddrBook.SetRecord(nCurRec, memo1.Text) then
ShowMessage("error");
end;
//找按鈕
procedure TForm1.Button4Click(Sender: TObject);
begin
memo1.Text := AddrBook.GetRecord(AddrBook.FindRecord(memo1.Text));
end;
以上介面部分的程式碼,不涉及任何存取邏輯,每個模組的程式碼簡單,易懂,方便維護。而實際上,該通訊錄是使用資料庫保存還是用文字檔案來保存,介面程式碼都不知道;使用資料庫的話,是透過ODBC還是ADO還是BDE存取資料庫,介面程式碼也不知道。實際上,這些存取邏輯的東西取決於TAddrBook類別的實現,TAddrBook類別的實作可以單獨的放在一個.pas檔案中,對TAddrBook類別的實現的任何更改,都不會影響介面部分。維護程式碼的時候,將更改局限於某一個模組中的做法是非常明智的。
Nicrosoft([email protected]) 於2001.7.14