悟透delphi 第十章 操作界面与操作逻辑
生活随笔
收集整理的這篇文章主要介紹了
悟透delphi 第十章 操作界面与操作逻辑
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
本書原著李戰(zhàn)(leadzen)大牛,由tingsking18整理,本人blog發(fā)布的版本經(jīng)過戰(zhàn)哥同意,轉(zhuǎn)載請(qǐng)著名出處和原作者!第十章 操作界面與操作邏輯
我們?cè)谇懊娴脑?jīng)討論過,用戶界面與商業(yè)邏輯分離的好處。這樣的分離可以讓軟件體系結(jié)構(gòu)更加合理,結(jié)構(gòu)易于理解,從而增強(qiáng)軟件的靈活性和可維護(hù)性。
正如我談到過,我們討論的目的是為了尋找將軟件結(jié)構(gòu)從混沌歸于有序的實(shí)用方法,這是編寫本書的主要目的之一。有序的東西易于理解,易于理解就便于掌握,掌握之后你將會(huì)發(fā)現(xiàn)其背后的哲理是那樣的簡單,從而升華到更高的境界去感受良好軟件結(jié)構(gòu)的協(xié)調(diào)美。
本章的話題將重點(diǎn)討論如何將客戶端的程序有序化,希望我們的討論對(duì)所有的軟件同行和朋友都有所幫助。第一節(jié) 分離操作界面與操作邏輯
怎樣設(shè)計(jì)友好的軟件操作界面,是人機(jī)工程學(xué)研究的一個(gè)重要課題。好用的軟件都有清秀可愛的面容,不但布局勻稱合理,對(duì)你的操作意圖也是善解人意,并且處理大方得體,就連對(duì)你的回答也體貼入微。如果,你編寫的軟件象這樣將關(guān)鍵字重復(fù)的錯(cuò)誤告訴你的用戶:“親愛的,你以前已經(jīng)輸入了編號(hào)為991028的出庫單,不可重復(fù)輸入。是否想查看以前的出庫單呢?”,你的軟件一定會(huì)銷量大增。可能當(dāng)年IBM的OS2就是因?yàn)檎f了很多用戶看不懂的廢話,才被用戶遺棄,失去民心,而被Bill Gates一統(tǒng)天下。
我們今天不打算討論怎樣打扮軟件的容顏,而要談?wù)勗谄恋慕缑婧竺?#xff0c;應(yīng)該如何更好地組織軟件結(jié)構(gòu),大大方方地處理用戶的操作命令。
假如,你已經(jīng)規(guī)劃好軟件初步的操作模式,用帶圖標(biāo)的菜單作為用戶發(fā)號(hào)司令的工具,并在MenuItem的OnClick事件中編寫完成業(yè)務(wù)處理的過程語句。一切都不錯(cuò),而商業(yè)的邏輯處理也是放到服務(wù)器端的RemoteDataMoudle中處理的,經(jīng)典的三層體系結(jié)構(gòu)。可是你的老板不喜歡菜單,他對(duì)按鈕情有獨(dú)鐘,于是你需要將Menu換成Button,然后將操作實(shí)現(xiàn)代碼移到Button的OnClick事件過程中,或者將Button的OnClick事件指向原來的MenuItemClick事件處理過程。軟件提交用戶試用之后,用戶強(qiáng)烈要求將軟件修改為Microsoft Word 2000那樣的界面,既有菜單又有按鈕,而且還能提供鍵盤的快捷鍵輸入(因?yàn)樗麄兊睦峡偭?xí)慣了原來DOS下那套老程序的鍵盤輸入方式)。于是,你又不得不修改軟件的界面控件,并再次將操作處理代碼調(diào)整,以便每種命令輸入方式都能被響應(yīng)。最后,歷經(jīng)千辛萬苦終于能完成整個(gè)軟件界面的修改工作。
由此可見,不同的人有不同的愛好和需求,他們各自都有操作軟件的習(xí)慣。但是他們使用軟件的目的是相同的,就是,向你的軟件發(fā)出指定的操作指令,使用該操作所代表的軟件功能!
在種種不同的用戶的需求之中,搞清所有用戶的最終目的之后,我們應(yīng)該仔細(xì)地想一想,不同的用戶為了達(dá)到相同目的,使用了不同的手段。哦!原來目的和手段是兩回事,只不過每個(gè)人用不同的手段達(dá)到相同的目的。
因此,我們應(yīng)該將操作界面與操作邏輯分離,應(yīng)該首先分清手段和目的,然后將手段與目的聯(lián)系起來。這樣,操作界面的更改將不會(huì)影響到操作邏輯,手段是手段,目的是目的。為了達(dá)到目的,可以不擇手段,就是這個(gè)道理!
說道這里,也許有人會(huì)說:這個(gè)道理誰都懂。那么,如果在我們開發(fā)軟件的過程中,多運(yùn)用這些淺顯的道理,就不難設(shè)計(jì)出簡單而又實(shí)用的軟件結(jié)構(gòu)。
操作界面與操作邏輯的分離可以為我們帶來哪些好處呢?
1. 易于理解
你可以在編寫業(yè)務(wù)操作代碼時(shí),不關(guān)心軟件的界面操作模式,而在美化你的軟件時(shí),只考慮界面的美學(xué)問題。外表是外表,內(nèi)心是內(nèi)心,只有你知道,外表美觀的界面連接著精巧內(nèi)秀的操作代碼,表里如一。你的朋友們既可欣賞到漂亮的軟件外表,也容易讀懂你的內(nèi)心。2. 易于維護(hù)
不管將來流行什么軟件界面,是時(shí)新HomePage式樣還是OutLook的經(jīng)典面版。你可以只修改與界面有關(guān)的部分,就可滿足要求。也可將你的軟件徹底改頭換面,以嶄新的面容出現(xiàn)。甚至,可表演川劇名家傳內(nèi)不傳外傳男不傳女的獨(dú)門絕技-變臉。但軟件還是軟件,軟件的內(nèi)在功能邏輯并未改變。不過,由于滿足了用戶喜新厭舊,追逐流行時(shí)尚的習(xí)慣,將使軟件公司的老板們的腰包越來越鼓。3. 可擴(kuò)充性強(qiáng)
人機(jī)工程學(xué)不斷取得的新突破,將為軟件使用者提供更多的命令輸入方式。現(xiàn)在,語音識(shí)別技術(shù)已逐漸商用化。你已經(jīng)可以利用IBM ViaVoice提供的語音識(shí)別支持模塊,開發(fā)能識(shí)別語音命令的控件。將這樣的控件加入你的軟件中,并與你以前編寫的操作邏輯關(guān)聯(lián),你的軟件就象長了耳朵,有了靈氣,可以傾聽你的述說。我也相信,總有一天可編寫一種可以看懂你的表情的控件,那么,軟件將可以根據(jù)你的情緒對(duì)你撫以不同冷暖的關(guān)懷。但軟件的靈魂還是原來的操作邏輯代碼!4. 適合大規(guī)模軟件開發(fā)
大規(guī)模軟件開發(fā)講求分工協(xié)作,各盡其才。如果你是軟件公司的老板,那么,在系統(tǒng)分析設(shè)計(jì)人員完成軟件設(shè)計(jì)之后,你可以找一批時(shí)裝設(shè)計(jì)師為你的軟件設(shè)計(jì)漂亮性感的界面,請(qǐng)精于編碼的程序員編寫操作邏輯。而你可以輕松地管理和控制各道工序的質(zhì)量,而且責(zé)任分明。盡管天涯海角的吹了一通,但我們還得回到我們主題。操作界面與操作邏輯的分離,到底要遵循哪些方法和原則呢?
首先,你應(yīng)當(dāng)歸納整理當(dāng)前模塊要向用戶提供的功能,劃分出明確的操作命令集。也就是說,設(shè)計(jì)可提供給用戶的命令,這有點(diǎn)象老式命令行程序的可用命令清單列表。記住,這些命令集體現(xiàn)的是用戶執(zhí)行操作的目的。
然后,在根據(jù)命令集中的每一命令規(guī)劃操作邏輯代碼,按照編寫程序的一般原則編制操作邏輯代碼。有關(guān)編寫程序的一般原則,可參閱《初戀DELPHI》一書。
最后,要提醒一點(diǎn)的就是,操作命令有時(shí)是受程序狀態(tài)控制的。有的程序員為了實(shí)現(xiàn)在某中狀態(tài)下禁止用戶發(fā)出指定的操作命令,想盡辦法控制菜單、按鈕等命令控件的屬性,封殺和打壓所有可執(zhí)行命令的控件。但是,你想禁止的是命令,而不是控件!
下面我們將會(huì)討論在分離操作界面和操作邏輯方面,DELPHI為我們提供的很有價(jià)值的東西,即TActionList和TAction。第二節(jié) 使用TActionList和TAction
“Action”一詞的含義是行為、行動(dòng)或動(dòng)作,TAction就是抽象了用戶想要通過軟件界面表現(xiàn)的行為、開展的行動(dòng)或執(zhí)行的動(dòng)作,而TActionList就描述了動(dòng)作的命令清單。你可以將一個(gè)TActionList元件加入到你的Form、Frame或DataModule中,雙擊此元件可定義需要的TAction對(duì)象。
締造DELPHI大廈的設(shè)計(jì)師和工程師們,為絕大多數(shù)命令控件(如TButton,TMenuItem等等)設(shè)計(jì)了Action屬性,并且常常碰巧出現(xiàn)在Object Inspecter窗口屬性頁面的第一項(xiàng)上,由此可見他們的用心良苦。但不管怎樣,他們?yōu)槲覀兲峁┝艘粋€(gè)簡單的方法,將命令控件的Action屬性與TActionList元件中定義的TAction對(duì)象關(guān)聯(lián)。
由于,在TAction對(duì)象的OnExecute事件中編寫的操作邏輯代碼可自動(dòng)被關(guān)聯(lián)的命令控件調(diào)用,因此,更換命令控件的類型,不用修改或調(diào)整操作邏輯代碼。這樣就可將操作界面與操作邏輯分開。
如果在某些狀態(tài)下你要禁止用戶執(zhí)行某種操作,可設(shè)置相關(guān)TAction對(duì)象的Enabled屬性為FALSE,則相關(guān)的命令控件將通通被冷凍,該變白臉的變臉白,該變灰臉的變灰臉,而不管他是生旦凈末丑。
再次感謝締造DELPHI的大師們,是他們?cè)谂_(tái)后為我們做了一切,而且還將他們的九陰真經(jīng)放到Source\VCL\ActnList.pas單元中。
既然有大師們的九陰真經(jīng),我們就應(yīng)該拿來修煉,增強(qiáng)我們的內(nèi)功。
首先,在ActnList單元中,TActionList是這樣聲明的:TActionList = class(TCustomActionList)publishedproperty Images;property OnChange;property OnExecute;property OnUpdate;end;
TActionList只發(fā)表了TCustomActionList的一些屬性和事件。其實(shí),TActionList就是用來裝TAction的容器,并提供了管理TAction的方法。有關(guān)TActionList的詳細(xì)用法,我們將在隨后開發(fā)的TActionManager控件中討論。再來看看TAction的聲明的:TAction = class(TCustomAction)publishedproperty Caption;property Checked;property Enabled;property HelpContext;property Hint;property ImageIndex;property ShortCut;property Visible;property OnExecute;property OnHint;property OnUpdate;end;
TAction是從TCustomAction類繼承的,與前面一樣,只不過將父類的一些特征發(fā)表。我不想逐一解讀TAction的各個(gè)類層次的原代碼,相信讀過《初戀DELPHI》一書的朋友都能夠解讀這些代碼。我只想討論TAction發(fā)表給我們的這些特性,能為我們提供什么功能。由于還有一些特性是在TAction的父輩類中發(fā)表的,在討論時(shí)也將一起談到,不過一些不重要的特性就不再廢話了。
Caption屬性:填寫此屬性,你可以用簡短的標(biāo)題向用戶說明命令操作的含義。此屬性將自動(dòng)更新相關(guān)命令控件的Caption屬性,所以按鈕和菜單的Caption屬性要在此輸入。
Category屬性:操作命令的類別,主要是為了方便你分類管理你的操作命令集。此屬性是在TAction的爺爺輩TContainedAction中發(fā)表的,在我們隨后開發(fā)的TActionManager控件中,你將看到如何此屬性管理操作命令。
Enabled屬性:控制命令操作是否可執(zhí)行,可自動(dòng)控制關(guān)聯(lián)命令控件是否允許執(zhí)行。封殺命令控件應(yīng)該從這里下手。
ImageIndex屬性:表示操作命令的圖標(biāo)索引,與TActionList的Images聯(lián)系。有圖標(biāo)的命令控件可以享受到他的恩惠。
ShortCut屬性:用鍵盤發(fā)出操作命令的快捷鍵,為喜好鍵盤操作的人們帶來的福音。
Visible屬性:控制Enabled可以讓命令控件變灰,控制此屬性可以讓命令控件消失在用戶面前。注意,雖然命令控件消失,但用戶仍可通過快捷鍵發(fā)出操作命令,而Enabled才可真正封殺命令。
OnExecute事件:可以在此事件中編寫操作邏輯代碼,用戶觸發(fā)相關(guān)的命令控件時(shí),將自動(dòng)調(diào)用此事件的操作邏輯代碼。
其他的特性就自己查看DELPHI的聯(lián)機(jī)幫助吧!
初步了解TActionList和TAction之后,我們將開始實(shí)踐。下面的PRETTYPOEM程序演示了TActionList和TAction的基本用法,很簡單。如果你不想浪費(fèi)時(shí)間可直接跳到后面的MULTIFACE程序,看看如何表演川劇的絕活兒-變臉。
你可以在隨書所附的光盤中找到此程序的原代碼。文件PRETTYPOEM.DPRprogram PRETTYPOEM;usesForms,Main in 'Main.pas' {fMain};{$R *.RES}beginApplication.Initialize;Application.CreateForm(TfMain, fMain);Application.Run;
end.文件Main.pas
unit Main;interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,Menus, ActnList, ComCtrls, ToolWin, StdCtrls, ImgList;typeTfMain = class(TForm)MainMenu: TMainMenu;ActionList: TActionList;actGuCheng: TAction;actXiMuRong: TAction;actLiQingZhao: TAction;actSuShi: TAction;N1: TMenuItem;N2: TMenuItem;N3: TMenuItem;N4: TMenuItem;N5: TMenuItem;N6: TMenuItem;ToolBar1: TToolBar;ToolButton1: TToolButton;ToolButton2: TToolButton;ToolButton3: TToolButton;ToolButton4: TToolButton;Button1: TButton;Button2: TButton;Button3: TButton;Button4: TButton;cbDisableLiQingZhao: TCheckBox;actDisableLiQingZhao: TAction;actHideLiQingZhao: TAction;cbHideLiQingZhao: TCheckBox;ImageList: TImageList;labPoem: TLabel;labShadow: TLabel;procedure actGuChengExecute(Sender: TObject);procedure actXiMuRongExecute(Sender: TObject);procedure actDisableLiQingZhaoExecute(Sender: TObject);procedure actHideLiQingZhaoExecute(Sender: TObject);procedure actSuShiExecute(Sender: TObject);procedure actLiQingZhaoExecute(Sender: TObject);private{ Private declarations }procedure RecitePoem(Poem:string);public{ Public declarations }end;varfMain: TfMain;implementation{$R *.DFM}
procedure TfMain.RecitePoem(Poem: string);
beginlabPoem.Caption:=Poem;labShadow.Caption:=Poem;
end;procedure TfMain.actGuChengExecute(Sender: TObject);
beginRecitePoem('黑夜給我黑色的眼睛 我卻用她尋找光明');
end;procedure TfMain.actXiMuRongExecute(Sender: TObject);
beginRecitePoem('溪水急著要流向大海 而浪潮卻渴望重歸土地');
end;procedure TfMain.actSuShiExecute(Sender: TObject);
beginRecitePoem('人有悲歡離合 月有陰晴圓缺');
end;procedure TfMain.actLiQingZhaoExecute(Sender: TObject);
beginRecitePoem('生當(dāng)做人杰 死亦為鬼雄');
end;procedure TfMain.actDisableLiQingZhaoExecute(Sender: TObject);
beginactLiQingZhao.Enabled:=not cbDisableLiQingZhao.Checked;
end;procedure TfMain.actHideLiQingZhaoExecute(Sender: TObject);
beginactLiQingZhao.Visible:=not cbHideLiQingZhao.Checked;
end;end.文件Main.dfmobject fMain: TfMainLeft = 192Top = 107Width = 442Height = 195BorderIcons = [biSystemMenu, biMinimize]Caption = '談古論今'Color = clBtnFaceFont.Charset = GB2312_CHARSETFont.Color = clWindowTextFont.Height = -12Font.Name = '宋體'Font.Style = []Menu = MainMenuOldCreateOrder = FalsePixelsPerInch = 96TextHeight = 12object labShadow: TLabelLeft = 17Top = 41Width = 380Height = 20Caption = '古今詩詞名句欣賞,請(qǐng)選擇你喜愛的詩人。'Font.Charset = GB2312_CHARSETFont.Color = clBlackFont.Height = -20Font.Name = '隸書'Font.Style = []ParentFont = FalseTransparent = Trueendobject labPoem: TLabelLeft = 16Top = 40Width = 380Height = 20Caption = '古今詩詞名句欣賞,請(qǐng)選擇你喜愛的詩人。'Font.Charset = GB2312_CHARSETFont.Color = clBlueFont.Height = -20Font.Name = '隸書'Font.Style = []ParentFont = FalseTransparent = Trueendobject ToolBar1: TToolBarLeft = 0Top = 0Width = 434Height = 26AutoSize = TrueButtonWidth = 63Caption = 'ToolBar'EdgeBorders = [ebTop, ebBottom]Flat = TrueImages = ImageListList = TrueShowCaptions = TrueTabOrder = 0object ToolButton1: TToolButtonLeft = 0Top = 0Action = actGuChengendobject ToolButton2: TToolButtonLeft = 63Top = 0Action = actXiMuRongendobject ToolButton3: TToolButtonLeft = 126Top = 0Action = actSuShiendobject ToolButton4: TToolButtonLeft = 189Top = 0Action = actLiQingZhaoendendobject Button1: TButtonLeft = 12Top = 80Width = 75Height = 25Action = actGuChengTabOrder = 1endobject Button2: TButtonLeft = 116Top = 80Width = 75Height = 25Action = actXiMuRongTabOrder = 2endobject Button3: TButtonLeft = 12Top = 112Width = 75Height = 25Action = actSuShiTabOrder = 3endobject Button4: TButtonLeft = 116Top = 112Width = 75Height = 25Action = actLiQingZhaoTabOrder = 4endobject cbDisableLiQingZhao: TCheckBoxLeft = 232Top = 116Width = 81Height = 17Action = actDisableLiQingZhaoTabOrder = 5endobject cbHideLiQingZhao: TCheckBoxLeft = 328Top = 116Width = 81Height = 17Action = actHideLiQingZhaoTabOrder = 6endobject MainMenu: TMainMenuImages = ImageListLeft = 332Top = 4object N1: TMenuItemCaption = '現(xiàn)代情懷'object N2: TMenuItemAction = actGuChengendobject N3: TMenuItemAction = actXiMuRongendendobject N4: TMenuItemCaption = '古典風(fēng)范'object N5: TMenuItemAction = actSuShiendobject N6: TMenuItemAction = actLiQingZhaoendendendobject ActionList: TActionListImages = ImageListLeft = 360Top = 4object actGuCheng: TActionCategory = '現(xiàn)代情懷'Caption = '顧城'ImageIndex = 0ShortCut = 16455OnExecute = actGuChengExecuteendobject actXiMuRong: TActionCategory = '現(xiàn)代情懷'Caption = '席慕容'ImageIndex = 1ShortCut = 16472OnExecute = actXiMuRongExecuteendobject actSuShi: TActionCategory = '古典風(fēng)范'Caption = '蘇軾'ImageIndex = 2ShortCut = 16467OnExecute = actSuShiExecuteendobject actLiQingZhao: TActionCategory = '古典風(fēng)范'Caption = '李清照'ImageIndex = 3ShortCut = 16460OnExecute = actLiQingZhaoExecuteendobject actDisableLiQingZhao: TActionCategory = '控制'Caption = '禁止李清照'OnExecute = actDisableLiQingZhaoExecuteendobject actHideLiQingZhao: TActionCategory = '控制'Caption = '隱藏李清照'OnExecute = actHideLiQingZhaoExecuteendendobject ImageList: TImageListLeft = 388Top = 4end
end此程序運(yùn)行之后,你可以通過菜單、工具條、按鈕和快捷鍵調(diào)出你喜歡的詩句。Action的標(biāo)題和圖標(biāo)都自動(dòng)反映在菜單、工具條和按鈕上,細(xì)心的朋友會(huì)發(fā)現(xiàn),菜單上還同時(shí)將我們定義的快捷鍵顯示出來,可見VCL的開發(fā)者所做的工作比我們想象的還要多。至于菜單名后的熱鍵字符,是由MainMenu的AutoHotKeys屬性引起的。
你可以用選擇框禁止或隱藏李清照的名字,不過只隱藏李清照的名字時(shí),仍然可通過Ctrl+L調(diào)出她的詩句。
休息一下,在我們開始討論運(yùn)行時(shí)更改軟件界面的話題之前,先來感受以下詩人們的情懷。詩人們的詩句是美麗的,但詩句中隱含的哲理才是他們內(nèi)心所追求的境界。編寫程序也是如此。本文來自CSDN博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/tingsking18/archive/2009/11/05/4772231.aspx
轉(zhuǎn)載于:https://www.cnblogs.com/keycode/archive/2010/10/15/1852423.html
總結(jié)
以上是生活随笔為你收集整理的悟透delphi 第十章 操作界面与操作逻辑的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 超级usb万能启动盘
- 下一篇: mojoportal学习——文章翻译之多