用工廠模式和策略模式優化過多的if-else


多個if-else代碼:

@RunWith(SpringRunner.class)
@SpringBootTest
public class EducationalBackgroundTest {
    private int year = 6;

    @Test
    public void normalIfElse(){
        if ( year == 6){
            System.out.println("小學畢業");
        }else if ( year == 9){
            System.out.println("初中畢業");
        }else if ( year == 12){
            System.out.println("高中畢業");
        }else {
            System.out.println("未知學習時間");
        }
    }
}

上面只統計了3個學習時間,如果我們要寫其他的學習時間就需要繼續添加if-else,如果業務很復雜,那么這個代碼看起來會很亂,不方便維護;

 

下面用策略模式工廠模式優化該if-else;

1. 定義抽象策略角色(接口

public interface EducationalBackground {
    void process();
}

 

2. 編寫具體策略角色(實現策略角色接口

小學畢業策略角色:

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

@Component
public class Primary implements EducationalBackground,InitializingBean {


    @Override
    public void process() {
        System.out.println("小學畢業");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        EducationBackgroundFactory.put(6,this);
    }

}

 

這里的InitializingBean接口(具體看Spring Bean的生命周期)只有一個方法afterPropertiesSet,實現了該接口的bean初始化會調用這個方法;

再寫一個策略角色“初中畢業”:

import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

@Component
public class Junior implements EducationalBackground,InitializingBean {

    @Override
    public void process() {
        System.out.println("初中畢業");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        EducationBackgroundFactory.put(9,this);
    }

}

 

3. 環境角色,內部持有一個策略類的引用

簡單工廠模式

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class EducationBackgroundFactory {
    private static Map<Integer,EducationalBackground> educationMap = new HashMap<>();

    private EducationBackgroundFactory(){}

    private final static EducationalBackground EMPTY = new EmptyDesc();

    /**
     * 將對應年數的學歷對象注冊到Map中
     * @param year
     * @param educationalBackground
     */
    public static void put(int year,EducationalBackground educationalBackground){
        educationMap.put(year,educationalBackground);
    }

    /**
     *獲得對應學歷對象
     * @param year
     */
    public static EducationalBackground get(int year){
        EducationalBackground educationalBackground = educationMap.get(year);
        //沒有對應year返回EMPTY
        return Optional.ofNullable(educationalBackground).orElse(EMPTY);
    }

    private static class EmptyDesc implements EducationalBackground{
        @Override
        public void process() {
            System.out.println("未知的學習時間year");
        }
    }

}

 

測試方法:

@RunWith(SpringRunner.class)
@SpringBootTest
public class EducationalBackgroundTest {
    private int year = 6;

    /**
     * 設計之后僅需兩行代碼
     */
    @Test
    public void design(){
        EducationalBackground educationalBackground = EducationBackgroundFactory.get(year);
        educationalBackground.process();
    }

}

 

有關於year的參數最好是配置在配置文件中,比如項目已上線,只需要修改配置文件中的內容即可修改對應的引用,而不需要修改代碼(修改了代碼需要發布)!

 

參考來源:

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


免責聲明!

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



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