PC的blog

Finding... Thinking... Solving...

BlogJava 首页 新随笔 联系 聚合 管理
  9 Posts :: 0 Stories :: 54 Comments :: 0 Trackbacks
本文紧接使用重构移除丑陋的if else代码(2)

移除if else

首先仔细观察一 下updateState()方法,我们会发现,导致该方法内存在大量if else的原因是它的参数仅仅是一个enum。由于enum本身并不含有任何逻辑代码,因此导致处理enum的方法需要使用if else来分析enum然后调用相应的逻辑。明白了这个道理之后,重构的方向就明了了。简单的说,我们需要要将方法参数由enum替换成一个更加强壮的抽 象类,每一个继承该类的子类将具体负责处理一个enum实例,之后再将updateState()方法中相应的逻辑代码转移到这些子类中。这样处理之后, 令人讨厌的if else就会消失了。


我们将这个替换enum的抽象类命名为SystemStatePerformer,代码如下:

package de.jingge.refactoring;

 

import java.awt.Image;


public abstract class SystemStatePerformer {

    
private final SystemState state;

    
private Image image;

    
public SystemStatePerformer(SystemState state, Image image) {

        
this.state = state;

        
this.image = image;

    }

    
public SystemState getState() {

        
return state;

    }

    
public Image getImage() {

        
return image;

    }
    
    
public abstract void perform();

}

从代码中可以看出,每 一个performer都含义有一个SystemState,这个SystemState属性,将只能通过构建器映射方式射入一个performer的对 象实例。换句话说SystemState只是一个只读属性,而且每一个performer实体类都只负责处理一个enum的实例(下面马上会解释如何实现 的)。这里使用的Image作为一个例子,它表示用户的每一个状态都可以使用一个图标来表示。performer()方法将负责处理具体的逻辑。这个 SystemStatePerformer的实体子类可以引用任何类型的对象,然后在perform()方法里面进行调用。




下 一步就是编写SystemStatePerformer的实体子类。我首先想到的是为每一个enum实例编写一个实际的子类,理论上来说是没问题的,但是 这样做必须编写一大堆的子类,不便于管理。所以我决定使用Factory + annonymous classes来构建具体的实体子类,让Factory来管理所有的实体子类。 代码如下:

package de.jingge.refactoring;

 

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

import java.awt.Image;

import java.awt.image.BufferedImage;


public class SystemStatePerformerFactory {

 

private static SystemStatePerformerFactory INSTANCE = new SystemStatePerformerFactory();

   

    
private SystemStatePerformerFactory() {

}

 

    
public static SystemStatePerformer getSystemStatePerformer(SystemState state) {

        
switch (state) {

            
case LOGGEDIN:

                
return createLoggedInPerformer();

            
case IDLE:

                
return createIdlePerformer();

            
case LOGGEDOUT:

                
return createLoggedOutPerformer();

            
default:

                
throw new IllegalAccessError("Unkonw status");

        }

    }

 

    
private static 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.

            }

        };

    }

 

    
private static 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.            }

            }

        };

    }

 

    
private static 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 static Image getImage(String string) {

        
return new BufferedImage(1010, BufferedImage.TYPE_4BYTE_ABGR);

    }

}

从 代码中可以看到,针对每一个enum状态都有一个创建performer的方法,该方法返回一个匿名类。逻辑代码将会被转移至个匿名类的 perform()方法之内。整个Factory只有一个公开的方 法:getSystemStatePerformer(SystemState),SystemManager可以调用这个方法来获得相应的 Performer实例。


在 这篇文章中,我希望专属于if else的问题。对于其他设计方面的问题,我采取的态度是能省略就省略。实际开发中,还有有很多问题需要处理,例如,使用static方法会导致系统的可 测试性下降,在实际开发中应该尽量避免,解决这类问题的方法之一是使用DI框架,例如Google Guice。

下一篇文章使用重构移除丑陋的if else代码(4)继续讲解。




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

posted on 2008-08-04 02:54 polygoncell 阅读(2227) 评论(4)  编辑  收藏

Feedback

# re: 使用重构移除丑陋的if else代码(3) 2008-08-04 06:58 游客
你的做法在某些情况下是非常适合的
但 if else 在某些复杂的业务逻辑中是无法避免的  回复  更多评论
  

# re: 使用重构移除丑陋的if else代码(3) 2008-08-04 11:50 残梦追月
呵呵,看到这里,我明白你是怎么做的老!  回复  更多评论
  

# re: 使用重构移除丑陋的if else代码(3) 2008-09-25 10:47 iridiumcao
这里用了switch...case的方式,不是if...else变体吗?

那么这个重构虽然形式上去掉了if...else,但代码复杂度反而增加了。

个人觉得前文把int换成enum型就足够了,不必再往后重构。  回复  更多评论
  

# re: 使用重构移除丑陋的if else代码(3) 2013-03-20 15:38 000
00000  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: