能为你的程序锦上添花的五种程序组织形式

形式一."见兔撒鹰".
如果有一个类有一个集合成员,可以在为此成员添加元素时再把具体集合建立起来,以免浪费空间和时间.

例:

 1  public   class  Company{
 2       private  List members = null ;
 3 
 4       public   void  addMember(Member member){
 5        if (members = null ){
 6      members = new  ArrayList();
 7        }
 8 
 9       members.add(member);
10      }
11  }
12 


异曲同工的另外一个例子:

 1  public   class  Singleton{
 2          private   static  Singleton instance = null ;
 3 
 4          public   static   synchronized  Singleton getInstance(){
 5      //  要用的时候再把Singleton建立起来
 6      if (instance == null ){
 7       instance = new  Singleton();
 8     }       
 9 
10      return  instance;
11         }
12  }
13 

 

形式二."只管结果,不顾过程"
从集合中取区间元素时,可以直接从上下限之间取来,让try...catch...去处理越界的事.

题设:有个数不定元素的列表(allTodoes),需要从中取N个,起始位置不限,你怎么编写程序.

很多人开始进行越界的判断,出来一堆if else,有时还需要在纸上写好思路,完毕后还有多方测试,生怕出错,即使编写好后其他人维护起来也是小心翼翼的.其实没必要这么麻烦.

例.

 1     int  start = pageIndex * pageSize;
 2     int  end = start + pageSize;
 3    
 4     for ( int  i = start;i < end;i ++ ){
 5      try {
 6      todoResult.addTodo((Todo)allTodoes.get(i));
 7     }
 8      catch (Exception ex){
 9       continue ;
10     }
11    }

题外话:分支和循环语句天生就不容易理解,尤其是在嵌套较深的时候,因为这是机器的思维特性.还是try...catch...比较贴近人类思维.


形式三."奉旨行事"
在查询中,如果把查询条件和遴选过程分开来更有益,程序也因此解耦合.这才是OO化的查询.

需求:从公司的职员列表中,找出男性且年龄大于22的成员.

传统写法: 

 1   List allmembers = company.getMembers(); //  取得所有成员
 2    List results = new  ArrayList(); //  结果列表
 3    
 4     for (Iterator it = allmembers.iterator();it.hasNext();){
 5     Member member = (Member)it.next();
 6     
 7      if (member.getAge() > 22   &&  member.isMale()){   //  筛选,这里是把查询条件和遴选过程融合在一起,条件一变立即就得加个分支.
 8      results.add(member);
 9     }
10    } 
11 

 

这种写法没有错,但是不是面向对象的写法,它有以下缺陷:
1.查询条件和筛选过程没有分离.
2.这样写的后果使Company变成了一个失血模型而不是领域模型.
3.换查询条件的话,上面除了"筛选"一句有变化外其它都是模板代码,重复性很高.

真正符合OO的查询应该是这样:

1    MemberFilter filter1 = new  MemberFilter(){
2      public   boolean  accept(Member member) {
3           return  member.isMale()  &&  member.getAge() > 22 ;
4     }
5    };
6    
7    List ls = company.listMembers(filter1);

 

这段代码成功的把查询条件作为一个接口分离了出去,接口代码如下:

1  public   interface  MemberFilter{
2    public   boolean  accept(Member member); 
3  }

而类Company增加了这样一个函数:

 1    public  List listMembers(MemberFilter memberFilter){
 2    List retval = new  ArrayList();
 3    
 4     for (Iterator it = members.iterator();it.hasNext();){
 5     Member member = (Member)it.next();
 6     
 7      if (memberFilter.accept(member)){
 8      retval.add(member);
 9     }
10    }  
11    
12     return  retval;
13   }

这就把模板代码归结到了类内部,外面不会重复书写了.Company也同时拥有了数据和行为,而不是原来的数据容器了.

形式四."化繁为简"
这种结构将多个分支语句变换为一个查表结构,这样做对扩充程序结构,修改具体数额都很方便,使程序更易于维护.还可以把归结出的表结构放在持久介质中如XML文件,数据库等,用到的时候再取,这样做在条件变化时不需要修改程序.

原始代码(VB代码,但应该不妨碍理解):

 1  Dim  count1 
 2  count1  =  salary.Value  +  USA.Value  *  Drate  +  JAN.Value  *  Jrate  -   4000  
 3  If  count1  <   500   Then  
 4   tax.Value  =  count1  *   0.05  
 5  ElseIf  count1  <   2000   Then  
 6   tax.Value  =  count1  *   0.1   -   25  
 7  ElseIf  count1  <   5000   Then  
 8   tax.Value  =  count1  *   0.15   -   125  
 9  ElseIf  count1  <   20000   Then  
10   tax.Value  =  count1  *   0.2   -   375  
11  ElseIf  count1  <   40000   Then  
12   tax.Value  =  count1  *   0.25   -   1375  
13  ElseIf  count1  <   60000   Then  
14   tax.Value  =  count1  *   0.3   -   3375  
15  Else  
16   tax.Value  =  count1  *   0.3   -   3375  
17  End   If  

 

变换如下:
这是个税率计算的语句段,公式是确定的:税=月薪*税率-折扣,税率又和月薪有关系,月薪越高税率越高,首先这里可以归纳出一个基本类:

 1  public   class  TaxItem{
 2    float  limit;  //  月薪界限
 3    float  ratio; //  税率
 4    float  discount; //  折扣
 5 
 6    public  TaxItem( float  limit, float  ratio, float  discount){
 7     this .limit = limit;
 8     this .ratio = ratio;
 9     this .discount = discount;
10   }
11 
12    public  TaxItem(){
13     this ( 0.0f , 0.0f , 0.0f );
14   }
15 
16    public   float  getDiscount() {
17     return  discount;
18   }
19 
20    public   float  getLimit() {
21     return  limit;
22   }
23 
24    public   float  getRatio() {
25     return  ratio;
26   }
27  }
28 
29 


然后就是税计算类:

 1  public   class  TaxCaculator{
 2           private   static  ArrayList list = new  ArrayList();
 3          
 4           public  TaxCaculator(){
 5                   //  这里把各个等级加入到链表中,注意添加顺序是由小到大
 6                  list.add( new  TaxItem( 500.0f , 0.05f , 0.0f ));
 7                  list.add( new  TaxItem( 2000.0f , 0.1f , 25.0f ));
 8                  list.add( new  TaxItem( 5000.0f , 0.15f , 125.0f ));
 9                  list.add( new  TaxItem( 20000.0f , 0.2f , 375.0f ));
10                  list.add( new  TaxItem( 40000.0f , 0.25f , 1375.0f ));
11                  list.add( new  TaxItem( 60000.0f , 0.3f , 3375.0f ));
12          }
13          
14           //  这个函数用来计算所得税
15           public   float  getTax( float  salary){
16                  TaxItem item = new  TaxItem();
17                  
18                   for ( int  i = 0 ;i < list.size();i ++ ){
19                          item = (TaxItem)list.get(i);
20                          
21                           if (salary > item.getLimit()){
22                                   continue ;
23                          }
24                           else {
25                                   break ;
26                          }
27                  }               
28                  
29                   //  返回最终结果,当然,这个公式也可以放在TaxItem 类中,这里就见仁见智了。
30                   return  salary * item.getRatio() - item.getDiscount();
31          }
32  }



调用如下 :

 1                  TaxCaculator taxCaculator = new  TaxCaculator();
 2                  
 3                   float  salary = 1000 .f;    
 4                  System.out.println( " Salary= " + salary  + "  Tax= " + taxCaculator.getTax(salary));
 5                  
 6                  salary = 2000 .f;  
 7                  System.out.println( " Salary= " + salary  + "  Tax= " + taxCaculator.getTax(salary));
 8                  
 9                  salary = 3000 .f;  
10                  System.out.println( " Salary= " + salary  + "  Tax= " + taxCaculator.getTax(salary));


 

形式五."分而治之"
该结构将分支语句的执行部分分散到单独的类中处理,降低了系统耦合度,程序也更容易维护.

举例如下:
在日常工作中,我们经常需要解析一段字符串并交由相应的函数进行处理,例如TCP/IP通信中的命令解析和用户自定义文件解析等场合,通常的处理方法是这样:

if(命令==”AAA”){
    函数AAA执行;
}
else if(命令==”BBB”){
    函数BBB执行;
}
.
.
.
else{
    函数XXX执行;
}

这种方法在命令较少时是有效的,当命令众多时,if语句和相关的函数将会形成一个巨集,给检查,维护和扩充带来了很大的不便,久而久之将会成为系统性能提升的瓶颈。

一个成功的软件程序必须尽可能简单并易于重构和扩展,在命令模式和Java反射机制的帮助下,我们可以从容解决上述问题,达到简单并易于重构和扩展的要求。以下将简要说明解决方案。

1. 制作一个命令的抽象接口.

1  public   interface  Command{ 
2          public   abstract   void  execute(String[] args); 
3 

 

2. 让每种命令都实现这个接口.

 1  //  命令一 
 2  public   class  CommandType01  implements  Command{ 
 3          public   void  execute(String[] args){ 
 4                 System.out.println( " \n commandType01 start! " );           
 5                 System.out.print( " \t commandType01 Length= " + args.length);                
 6                 System.out.println( " \n commandType01 End! " ); 
 7         } 
 8 
 9 
10  //  命令二 
11  public   class  CommandType02  implements  Command{ 
12          public   void  execute(String[] args){ 
13                 System.out.println( " \n commandType02 start! " );           
14                  
15                 System.out.print( " \t commandType02 is: " );                
16                  for (String item:args){ 
17                         System.out.print( " \t  " + item); 
18                 } 
19                  
20                 System.out.println( " \n commandType02 End! " ); 
21         } 
22 
23 
24  //  命令三 
25  public   class  CommandType03  implements  Command{ 
26          public   void  execute(String[] args){ 
27                 System.out.println( " \n commandType03 start! " );           
28                 System.out.print( " \t commandType03 last Nation= " + args[args.length - 1 ]);           
29                 System.out.println( " \n commandType03 End! " ); 
30         } 
31 
32 
33 


让每种命令都实现execute接口的用意是强制每个命令的执行方式一致,简化调用时的处理,但执行内容应该根据实际情况决定.
例如
命令一的执行内容是输出参数的个数
命令二的执行内容是输出参数的内容
命令二的执行内容是输出最后一个参数

3. 将命令防置到命令中心中去
命令中心类的代码如下:

 1  public   class  Mediation{ 
 2         Command cmmd; //  命令对象的引用 
 3         String[] cmmdArgs; //  参数列表 
 4          
 5          public  Mediation(){ 
 6                  
 7         } 
 8          
 9          public   void  fetchCommand(String strCmmd){ 
10                 cmmdArgs = strCmmd.split( " \s+ " ); //  分析原始命令 
11                  
12                 String className = " Command " + cmmdArgs[ 0 ]; //  根据分析后命令的第一个参数得到类名 
13                  
14          &am
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值