代碼重構:用工廠+策略模式優化過多的if else代碼塊


http://www.cnblogs.com/pfblog/p/7815238.html

 

最近在工作中優化了一段冗余的if else代碼塊,感覺對設計模式的理解和運用很有幫助,所以分享出來。鑒於原代碼會涉及到公司的隱私,因此就不貼出來了。下面以更加通俗易懂的案例來解析。

假如寫一個針對員工上班不遵守制度做相應懲罰的程序,比如,上班遲到:罰100;上班睡覺:罰1000;上班早退:警告;上班玩游戲:嚴重警告;上班談戀愛:開除等,通常都會這樣寫:

復制代碼
public class WorkPunish {
    public static void main(String[] agrs){
        String state ="late";
        punish(state);
    }
    
    public static void punish(String state){
        if ("late".equals(state)){
            System.out.println("罰100");
        }else if ("sleep".equals(state)){
            System.out.println("罰1000");
        }else if ("early".equals(state)){
            System.out.println("警告");
        }else if ("play".equals(state)){
            System.out.println("嚴重警告");
        }else if ("love".equals(state)){
            System.out.println("開除");
        }
    }
}
復制代碼

可以看到,每增加一種情況都要增加一個if else判斷,這樣會造成這段代碼非常長,可讀性差、不易維護。下面就用靜態工廠+策略模式來重構這段代碼(對於靜態工廠模式和策略模式不知道的同學請自行百度哈

先說說思路:1、定義一個處罰的接口 ,包含一個執行處罰的方法

      2、每一種情況的處罰都抽象成一個具體處罰類並繼承處罰接口(策略模式)

      3、定義一個靜態工廠類,用來根據情況生產具體處罰對象,然后執行處罰的方法(靜態工廠模式)。

代碼如下:

package com.test.punish;

public interface IPunish {
    void exePunish();
}
復制代碼
package com.test.punish;
import org.springframework.beans.factory.InitializingBean;

public class LatePunish implements IPunish,InitializingBean{
    public void exePunish() {
        System.out.println("罰100");
    }
    
    public void afterPropertiesSet(){
        PunishFactory.registerPunish("late", this);
    }

}
復制代碼
復制代碼
package com.test.punish;
import org.springframework.beans.factory.InitializingBean;

public class SleepPunish implements IPunish,InitializingBean{
    public void exePunish() {
        System.out.println("罰款1000");
    }
    public void afterPropertiesSet(){
        PunishFactory.registerPunish("sleep", this);
    }
}
復制代碼
復制代碼
package com.test.punish;
import org.springframework.beans.factory.InitializingBean;

public class EarlyPunish implements IPunish,InitializingBean{
    public void exePunish() {
        System.out.println("警告");
    }
    
    public void afterPropertiesSet(){
        PunishFactory.registerPunish("early", this);
    }

}
復制代碼

剩下的處罰類就不貼出來了。

復制代碼
package com.test.punish;
import java.util.HashMap;
import java.util.Map;

public class PunishFactory {
    
    private static Map<String,IPunish> punishMap = new HashMap<String,IPunish>();
    
    private PunishFactory() {}
    
    private static final IPunish EMPTY = new EmptyPunish();
    
    //獲取
    public static IPunish getPunish(String state) {
        IPunish result = punishMap.get(state);
        return result == null ? EMPTY : result;
    }
    
    //將處罰對象注冊到這里
    public static void registerPunish(String state,IPunish o){
        punishMap.put(state, o);
    }
    
    private static class EmptyPunish implements IPunish {
        public void exePunish() {
            // Empty class
        }
    }
}
復制代碼

重構后,處罰邏輯就可以這么寫了,兩行代碼搞定

復制代碼
public class WorkPunish {
    public static void main(String[] agrs){
        String state ="late";
        punish(state);
    }
    
    //重構后的處罰邏輯
    public static void punish(String state){
     //靜態工廠類獲取處罰對象 IPunish punish = PunishFactory.getPunish(state);
     //執行處罰邏輯 punish.exePunish(); } }
復制代碼

重構后的處罰邏輯簡單、清晰,后續新增一種情況,只需定義一個相應的類即可,根本不需要修改處罰邏輯,完全解耦合,這大大提高了代碼的可讀性和可維護性。

不過,運用靜態工廠+策略模式,也存在弊端,那就是會增加很多類;但是,當每種情況的邏輯代碼很多、很復雜的時候,那么這個弊端就可以忽略不計,其優勢就完全展示出來了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM