形式一."见兔撒鹰". 例:
1publicclass
Company{ 2privateListmembers=null ; 3 4publicvoid addMember(Membermember){ 5if(members=null ){ 6members=new ArrayList(); 7 } 8 9 members.add(member); 10 } 11 } 12 | |
异曲同工的另外一个例子:
1publicclass
Singleton{ 2privatestaticSingletoninstance=null ; 3 4publicstaticsynchronized SingletongetInstance(){ 5//要用的时候再把Singleton建立起来 6if(instance==null ){ 7instance=new Singleton(); 8 } 9 10return instance; 11 } 12 } 13 形式二."只管结果,不顾过程" 题设:有个数不定元素的列表(allTodoes),需要从中取N个,起始位置不限,你怎么编写程序. 很多人开始进行越界的判断,出来一堆if else,有时还需要在纸上写好思路,完毕后还有多方测试,生怕出错,即使编写好后其他人维护起来也是小心翼翼的.其实没必要这么麻烦. 例.
1intstart=pageIndex*
pageSize; 2intend=start+ pageSize; 3 4for(inti=start;i<end;i++ ){ 5try { 6 todoResult.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()){//筛选,这里是把查询条件和遴选过程融合在一起,条件一变立即就得加个分支. 8 results.add(member); 9 } 10 } 11 这种写法没有错,但是不是面向对象的写法,它有以下缺陷: 真正符合OO的查询应该是这样:
1MemberFilterfilter1=new
MemberFilter(){ 2publicboolean accept(Membermember){ 3returnmember.isMale()&&member.getAge()>22 ; 4 } 5 }; 6 7Listls=company.listMembers(filter1); 这段代码成功的把查询条件作为一个接口分离了出去,接口代码如下:
1publicinterface
MemberFilter{ 2publicboolean accept(Membermember); 3} 而类Company增加了这样一个函数:
1public
ListlistMembers(MemberFiltermemberFilter){ 2Listretval=new ArrayList(); 3 4for(Iteratorit= members.iterator();it.hasNext();){ 5Membermember= (Member)it.next(); 6 7if (memberFilter.accept(member)){ 8 retval.add(member); 9 } 10 } 11 12return retval; 13} 这就把模板代码归结到了类内部,外面不会重复书写了.Company也同时拥有了数据和行为,而不是原来的数据容器了. 形式四."化繁为简" 原始代码(VB代码,但应该不妨碍理解):
1Dim
count1 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 变换如下:
1publicclass
TaxItem{ 2floatlimit;//月薪界限 3floatratio;//税率 4floatdiscount;//折扣 5 6publicTaxItem(floatlimit,floatratio,float discount){ 7this.limit= limit; 8this.ratio= ratio; 9this.discount= discount; 10 } 11 12public TaxItem(){ 13this(0.0f,0.0f,0.0f ); 14 } 15 16publicfloat getDiscount(){ 17return discount; 18 } 19 20publicfloat getLimit(){ 21return limit; 22 } 23 24publicfloat getRatio(){ 25return ratio; 26 } 27 } 28 29
1publicclass
TaxCaculator{ 2privatestaticArrayListlist=new ArrayList(); 3 4public TaxCaculator(){ 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(float salary){ 16TaxItemitem=new TaxItem(); 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=new
TaxCaculator(); 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. 制作一个命令的抽象接口.
1publicinterface
Command{ 2publicabstractvoid execute(String[]args); 3} 2. 让每种命令都实现这个接口.
1//命令一
2publicclassCommandType01implements Command{ 3publicvoid execute(String[]args){ 4System.out.println("\ncommandType01start!" ); 5System.out.print("\tcommandType01Length="+ args.length); 6System.out.println("\ncommandType01End!" ); 7 } 8 } 9 10//命令二 11publicclassCommandType02implements Command{ 12publicvoid execute(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//命令三 25publicclassCommandType03implements Command{ 26publicvoid execute(String[]args){ 27System.out.println("\ncommandType03start!" ); 28System.out.print("\tcommandType03lastNation="+args[args.length-1 ]); 29System.out.println("\ncommandType03End!" ); 30 } 31 } 32 33
3. 将命令防置到命令中心中去
1publicclass
Mediation{ 2Commandcmmd;//命令对象的引用 3String[]cmmdArgs;//参数列表 4 5public Mediation(){ 6 7 } 8 9publicvoid fetchCommand(StringstrCmmd){ 10cmmdArgs=strCmmd.split("\s+");//分析原始命令 11 12StringclassName="Command"+cmmdArgs[0];//根据分析后命令的第一个参数得到类名 13 14try |
为你的程序锦上添花的五种程序组织形式
最新推荐文章于 2022-07-02 09:18:43 发布