最近閱讀了一套ERP開發框架的源代碼,對開發框架的理解又深入一層,也為其將知識點運用的如此靈活而自嘆不如。
郎咸平教授說,國際金融炒家對國際金融知識的理解與運用程序,是不可想像的。1997年的亞洲金融危機,國際金融炒家對香港的攻擊是賣空港幣,但是最后卻反應到股票市場,慘敗。同理,開發高手將系統的知識點,運用的相當靈活,你完全沒有想過可以按這種方式做出程序,靈活簡便,維護方便。
1 .NET組件自動重命名
在Windows Forms開發,經常遇到一件頭疼的事情是一個Form界面有很多控件,而這些控件的名稱(Name)很難維持命名統一。比如,開發規范里面說,要給所有的Button命名為以btn開發。如果界面中有二個按鈕,確定和取消,那么可以按照規范,為之命名為btnOK,btnCancel。再擴展到其它的控件,都應該遵守這樣的前綴命名法。
經過整理,形成下面的表格規范
控件 | 前綴 | 舉例 |
Button | btn | btnOK |
ListView | lst | lstProject |
Label | lbl | lblUserName |
Combox | cmb | cmbProjectType |
TextBox | txt | txtUserId |
CheckBox | chk | chkEnable |
GridView | grid | gridProduct |
當一個頁面中有很多控件時,如何保證控件命名,還是這樣的規范呢?
一種辦法是有專門的代碼檢查,俗稱Review,經常的花時間去改善代碼,維護代碼。從基本的命名上檢查,修改,以符合規范。另一種方法就是我從高手的代碼中學到的,解釋如下。
當你給一個按鈕綁定資料庫字段或是修改它的Label/Text/Caption屬性時,加入設計時支持,用這個名字來替換無規律的命名。比如,拖一個按鈕Button控件到窗體中,它的名稱是Button1, 這時修改它的Text=OK, 回車確認。這里我截獲了控件的屬性修改事件,於是修改控件Button1的名字為btnOK。數據綁定屬性也是一樣,截獲綁定的數據成員的名稱,再依據它來修改控件的名稱,比如下面的一段代碼所示
private Foundation.WinUI.Misc.Label lblDbPassword; private Foundation.WinUI.Editors.TextEditor txtDbUser; private Foundation.WinUI.Misc.Label lblDbUser; private Foundation.WinUI.Editors.TextEditor txtDbDatabase; private Foundation.WinUI.Misc.Label lblDbDatabase; private Foundation.WinUI.Editors.TextEditor txtDbServer; private Foundation.WinUI.Misc.Label lblDbServer; private Foundation.WinUI.Misc.GroupBox grpConnectionParameter1; private Foundation.WinUI.Editors.Grid grid;
對這些控件的名稱,我沒有任何的修改,只是對它綁定數據屬性,框架會自動根據數據源的屬性名稱,進行修改,所以看起來規范程度高,完全不需要人為的來執行規范。設想一下,當系統中的窗體很多,控件數量大的時候,這種智能的命名方法是多么的有效率,將代碼規范貫徹到底。
這則技巧的實現方法是注冊組件改變事件(ComponentChanged),如下面的代碼所示
this.Site.GetService(typeof(IComponentChangeService)) as IComponentChangeService
2 .NET Remoting 服務器端對象自動化配置
先來看一下,基本的.NET Remoting是如何配置開發的。
先開發服務器對象,即是要暴露給客戶端的對象
public class MyObject:MarshalByRefObject { public int Add(int a,int b) { return a+b; } }
服務器端把它激活,供客戶端連接進來調用
[STAThread] static void Main(string[] args) { RemotingConfiguration.Configure("RemoteServer.exe.config"); Console.ReadLine(); }
因為這樣的代碼很節省,所以還需要在配置文件中作出如下的配置
<configuration> <system.runtime.remoting> <application name="RemoteServer"> <service> <wellknown type="RemoteObject.MyObject,RemoteObject" objectUri="RemoteObject.MyObject" mode="Singleton" /> </service> <channels> <channel ref="tcp" port="9999"/> </channels> </application> </system.runtime.remoting> </configuration>
客戶端代碼,調用.NET Remoting服務
[STAThread] static void Main(string[] args) { RemoteObject.MyObject app = (RemoteObject.MyObject)Activator.GetObject(typeof(RemoteObject.MyObject),System.Configuration.ConfigurationSettings.AppSettings["ServiceURL"]); Console.WriteLine(app.Add(1,2)); Console.ReadLine(); }
同樣,還是需要作出配置才能使上面的代碼生效。
<configuration> <appSettings> <add key="ServiceURL" value="tcp://localhost:9999/RemoteObject.MyObject"/> </appSettings> </configuration>
我提出問題,如果要增加一個服務器端對象MyObjectB,對上面的代碼,需要修改幾個地方?
增加代碼(服務實現和服務接口的調用)是必須的部分,不可少,另外需要修改的地方:
1 服務器端的配置文件,增加服務接口
2 客戶端的配置文件,增加對服務的引用
但是,開發高手給的答案是零修改,增加一個服務,對服務端或客戶端不需要作出任何的修改。
如何做到這一點呢,著名的.NET通訊組件RemObjects ,它提供了一個通用的GUI工具,用於根據服務端的接口,生成客戶端的代碼,依照這一點思路。我們可以考慮做一個工具。增加一個服務器端對象后,為了讓它暴露出來可用,要修改的地方是兩個配置文件,所以,我只需要當有新的服務器端對象要暴露出來時,運用這個GUI工具,自動完成二個配置文件的修改,即可達到零修改。而且用工具的好處是不會出錯,即方便又有效率。
我以為這兩個思路確實不錯,能讓系統的可讀性增強,又提高工作效率。