使用重构移除丑陋的if else代码(5)

使用重构移除丑陋的if else代码(5)
本文紧接 使用重构移除丑陋的if else代码(4)

上篇文章谈到如何能够彻底把这个switch也移除掉呢?很简单,我们只需要在getSystemStatePerformer()方法被调用之前先创建所有 performer匿名类的实例,然后在该方法被调用时直接返回对应的实力。 如何具体实现呢? 用Map, 请看代码:

package  de.jingge.refactoring;

 

import   static  de.jingge.refactoring.SystemState. * ;

import  java.awt.Image;

import  java.awt.image.BufferedImage;

import  java.lang.reflect.Method;

import  java.util.Collections;

import  java.util.HashMap;

import  java.util.Map;

 

/**

 *

 * 
@author  [email protected]

 
*/

public   class  SystemStatePerformerFactory {

 

private   static  SystemStatePerformerFactory INSTANCE  =   new  SystemStatePerformerFactory();

   

    
private  Map < SystemState, SystemStatePerformer >  performers;

 

    
private  SystemStatePerformerFactory() {

}

 

    
public   static  SystemStatePerformerFactory getInstance() {

        
return  INSTANCE;

    }

   

    
private   synchronized  Map < SystemState, SystemStatePerformer >  getPerformers()

            
throws  Exception {

        
if  (performers  ==   null ) {

            performers 
=   new  HashMap < SystemState, SystemStatePerformer > ();

            
//  call all @FactoryMethod using reflection

            
for  (Method m : getClass().getDeclaredMethods()) {

                
if  (m.getAnnotation(FactoryMethod. class !=   null ) {

                    SystemStatePerformer p 
=  (SystemStatePerformer) m.invoke(

                            
this new  Object[]{});

                    performers.put(p.getState(), p);

                }

            }

            
//  make it readonly

            performers 
=  Collections.unmodifiableMap(performers);

        }

        
return  performers;

    }

 

    
public  SystemStatePerformer getSystemStatePerformer(SystemState state)  throws  Exception{

        
return  getPerformers().get(state);

    }

 

@FactoryMethod

    
private  SystemStatePerformer createLoggedInPerformer() {

        
return   new  SystemStatePerformer(LOGGEDIN, getImage( " loggedin.gif " )) {

 

            @Override

            
public   void  perform() {

                
//  do something after logging in is successful,

                
//  for example: show welcome dialog, open the last edit document, etc.

            }

        };

    }

 

@FactoryMethod

    
private  SystemStatePerformer createLoggedOutPerformer() {

        
return   new  SystemStatePerformer(LOGGEDOUT, getImage( " loggedout.gif " )) {

 

            @Override

            
public   void  perform() {

                
//  do something after logging out is successful,

                
//  for example: free used resource, dispose GUI components, etc.            }

            }

        };

    }

 

@FactoryMethod

    
private  SystemStatePerformer createIdlePerformer() {

        
return   new  SystemStatePerformer(IDLE, getImage( " idle.gif " )) {

 

            @Override

            
public   void  perform() {

                
//  do something after the user is idle,

                
//  for example: save the application state temporarily, lock the application, etc.

            }

        };

    }

 

    
private  Image getImage(String string) {

        
return   new  BufferedImage( 10 10 , BufferedImage.TYPE_4BYTE_ABGR);

    }

}

从代码中可以看出,当getPerformers()方法被第一次调用时,我们会为每一个performer匿名类创建一个实例,并且将它们纳入Map的管 理之中,以后每次调用的时候,直接从Map里面提取对应某个状态的performer就可以了, switch可以舍弃了。 @FactoryMethod这个注释是我自己写的,使用它主要是为了避免每次新增加一个create***Performer()方法后,都必须修改 getSystemStatePerformer()。

@FactoryMethod的代码如下:

package  de.jingge.refactoring;

 

import  java.lang.annotation.ElementType;

import  java.lang.annotation.Retention;

import  java.lang.annotation.RetentionPolicy;

import  java.lang.annotation.Target;

 


@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.METHOD})

public  @ interface  FactoryMethod {


}

到这里整个重构已经结束了, 我们已经将if else, switch完全从代码里剔除了。

读过Refactoring to Patterns这本书的朋友可能会觉得,这里所作的一些和书中第七章最后一节Replace Conditional Dispatcher with Command完全一样。 Well,第一眼看上去确实很像,但是看完我写的所有代码后,再仔细想一想,两者还是有区别的(Refactoring to Patterns这本书写的非常好,对此书,我可以说是爱不释手,还曾经写过一篇书评。事实上,我这篇文章正式基于这本书的):

1. Factory + annonymous类而不是每一个状态一个具体的实体类。

    这样处理问题, 类的数量大大减少,类关联的复杂程度也大大减少,维护起来很方便。

2. performer并不单单是一个command,它拥有状态,并且可以处理更多的逻辑。


全文完。




声明:本文版权归作者所有,如需转载请注明出处。

你可能感兴趣的:(使用重构移除丑陋的if else代码(5))