形式一."見兔撒鷹". 例:
1publicclassCompany{
2privateListmembers=null; 3 4publicvoidaddMember(Membermember){ 5if(members=null){ 6members=newArrayList(); 7} 8 9members.add(member); 10} 11} 12 |
|
異曲同工的另外一個例子:
1publicclassSingleton{
2privatestaticSingletoninstance=null; 3 4publicstaticsynchronizedSingletongetInstance(){ 5//要用的時候再把Singleton建立起來 6if(instance==null){ 7instance=newSingleton(); 8} 9 10returninstance; 11} 12} 13 形式二."只管結果,不顧過程" 題設:有個數不定元素的列表(allTodoes),需要從中取N個,起始位置不限,你怎麼編寫程序. 很多人開始進行越界的判斷,出來一堆if else,有時還需要在紙上寫好思路,完畢後還有多方測試,生怕出錯,即使編寫好後其他人維護起來也是小心翼翼的.其實沒必要這麼麻煩. 例.
1intstart=pageIndex*pageSize;
2intend=start+pageSize; 3 4for(inti=start;i<end;i++){ 5try{ 6todoResult.addTodo((Todo)allTodoes.get(i)); 7} 8catch(Exceptionex){ 9continue; 10} 11} 題外話:分支和循環語句天生就不容易理解,尤其是在嵌套較深的時候,因爲這是機器的思維特性.還是try...catch...比較貼近人類思維.
需求:從公司的職員列表中,找出男性且年齡大於22的成員. 傳統寫法:
1Listallmembers=company.getMembers();//取得所有成員
2Listresults=newArrayList();//結果列表 3 4for(Iteratorit=allmembers.iterator();it.hasNext();){ 5Membermember=(Member)it.next(); 6 7if(member.getAge()>22&&member.isMale()){//篩選,這裏是把查詢條件和遴選過程融合在一起,條件一變立即就得加個分支. 8results.add(member); 9} 10} 11 這種寫法沒有錯,但是不是面向對象的寫法,它有以下缺陷: 真正符合OO的查詢應該是這樣:
1MemberFilterfilter1=newMemberFilter(){
2publicbooleanaccept(Membermember){ 3returnmember.isMale()&&member.getAge()>22; 4} 5}; 6 7Listls=company.listMembers(filter1); 這段代碼成功的把查詢條件作爲一個接口分離了出去,接口代碼如下:
1publicinterfaceMemberFilter{
2publicbooleanaccept(Membermember); 3} 而類Company增加了這樣一個函數:
1publicListlistMembers(MemberFiltermemberFilter){
2Listretval=newArrayList(); 3 4for(Iteratorit=members.iterator();it.hasNext();){ 5Membermember=(Member)it.next(); 6 7if(memberFilter.accept(member)){ 8retval.add(member); 9} 10} 11 12returnretval; 13} 這就把模板代碼歸結到了類內部,外面不會重複書寫了.Company也同時擁有了數據和行爲,而不是原來的數據容器了. 形式四."化繁爲簡" 原始代碼(VB代碼,但應該不妨礙理解):
1Dimcount1
2count1=salary.Value+USA.Value*Drate+JAN.Value*Jrate-4000 3Ifcount1<500Then 4tax.Value=count1*0.05 5ElseIfcount1<2000Then 6tax.Value=count1*0.1-25 7ElseIfcount1<5000Then 8tax.Value=count1*0.15-125 9ElseIfcount1<20000Then 10tax.Value=count1*0.2-375 11ElseIfcount1<40000Then 12tax.Value=count1*0.25-1375 13ElseIfcount1<60000Then 14tax.Value=count1*0.3-3375 15Else 16tax.Value=count1*0.3-3375 17EndIf 變換如下:
1publicclassTaxItem{
2floatlimit;//月薪界限 3floatratio;//稅率 4floatdiscount;//折扣 5 6publicTaxItem(floatlimit,floatratio,floatdiscount){ 7this.limit=limit; 8this.ratio=ratio; 9this.discount=discount; 10} 11 12publicTaxItem(){ 13this(0.0f,0.0f,0.0f); 14} 15 16publicfloatgetDiscount(){ 17returndiscount; 18} 19 20publicfloatgetLimit(){ 21returnlimit; 22} 23 24publicfloatgetRatio(){ 25returnratio; 26} 27} 28 29
1publicclassTaxCaculator{
2privatestaticArrayListlist=newArrayList(); 3 4publicTaxCaculator(){ 5//這裏把各個等級加入到鏈表中,注意添加順序是由小到大 6list.add(newTaxItem(500.0f,0.05f,0.0f)); 7list.add(newTaxItem(2000.0f,0.1f,25.0f)); 8list.add(newTaxItem(5000.0f,0.15f,125.0f)); 9list.add(newTaxItem(20000.0f,0.2f,375.0f)); 10list.add(newTaxItem(40000.0f,0.25f,1375.0f)); 11list.add(newTaxItem(60000.0f,0.3f,3375.0f)); 12} 13 14//這個函數用來計算所得稅 15publicfloatgetTax(floatsalary){ 16TaxItemitem=newTaxItem(); 17 18for(inti=0;i<list.size();i++){ 19item=(TaxItem)list.get(i); 20 21if(salary>item.getLimit()){ 22continue; 23} 24else{ 25break; 26} 27} 28 29//返回最終結果,當然,這個公式也可以放在TaxItem類中,這裏就見仁見智了。 30returnsalary*item.getRatio()-item.getDiscount(); 31} 32}
1TaxCaculatortaxCaculator=newTaxCaculator();
2 3floatsalary=1000.f; 4System.out.println("Salary="+salary+"Tax="+taxCaculator.getTax(salary)); 5 6salary=2000.f; 7System.out.println("Salary="+salary+"Tax="+taxCaculator.getTax(salary)); 8 9salary=3000.f; 10System.out.println("Salary="+salary+"Tax="+taxCaculator.getTax(salary));
舉例如下: if(命令==”AAA”){ 這種方法在命令較少時是有效的,當命令衆多時,if語句和相關的函數將會形成一個巨集,給檢查,維護和擴充帶來了很大的不便,久而久之將會成爲系統性能提升的瓶頸。 一個成功的軟件程序必須儘可能簡單並易於重構和擴展,在命令模式和Java反射機制的幫助下,我們可以從容解決上述問題,達到簡單並易於重構和擴展的要求。以下將簡要說明解決方案。 1. 製作一個命令的抽象接口.
1publicinterfaceCommand{
2publicabstractvoidexecute(String[]args); 3} 2. 讓每種命令都實現這個接口.
1//命令一
2publicclassCommandType01implementsCommand{ 3publicvoidexecute(String[]args){ 4System.out.println("\ncommandType01start!"); 5System.out.print("\tcommandType01Length="+args.length); 6System.out.println("\ncommandType01End!"); 7} 8} 9 10//命令二 11publicclassCommandType02implementsCommand{ 12publicvoidexecute(String[]args){ 13System.out.println("\ncommandType02start!"); 14 15System.out.print("\tcommandType02is:"); 16for(Stringitem:args){ 17System.out.print("\t"+item); 18} 19 20System.out.println("\ncommandType02End!"); 21} 22} 23 24//命令三 25publicclassCommandType03implementsCommand{ 26publicvoidexecute(String[]args){ 27System.out.println("\ncommandType03start!"); 28System.out.print("\tcommandType03lastNation="+args[args.length-1]); 29System.out.println("\ncommandType03End!"); 30} 31} 32 33
3. 將命令防置到命令中心中去
1publicclassMediation{ 2Commandcmmd;//命令對象的引用 3String[]cmmdArgs;//參數列表 4 5publicMediation(){ 6 7} 8 9publicvoidfetchCommand(StringstrCmmd){ 10cmmdArgs=strCmmd.split("\s+");//分析原始命令 11 12StringclassName="Command"+cmmdArgs[0];//根據分析後命令的第一個參數得到類名 13 14try |
爲你的程序錦上添花的五種程序組織形式
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.