使用策略模式(Strategy Pattern)取代switch

一般來說使用switch通常會產生一些缺點,如同樣的switch散佈在不同的位置時,當需要修改switch時,必須找出所有的switch一併修改,以及switch本身很難符合開閉原則,或是switch中條件區塊擴大時會擴展switch本身,所以可考慮Strategy Pattern取代switch

簡單的switch如下
    private static void useSwitchExample(){
        switch(condition){
            case 0:
                System.out.println("audio error");
                break;
            case 1:
                System.out.println("client error");
                break;
            case 2:
                System.out.println("not match");
                break;
        }
    }

根據condition執行不同的case條件,會印出不同的錯誤訊息,為了取代switch,先建立Strategy如下
public interface IErrorStrategy
{
    public void showErrorMessage();
   
    class AudioError implements IErrorStrategy{
        @Override
        public void showErrorMessage()
        {
            System.out.println("audio error");
        }
    }
   
    class ClientError implements IErrorStrategy{
        @Override
        public void showErrorMessage()
        {
            System.out.println("client error");
        }
    }
   
    class NoMatchError implements IErrorStrategy{

        @Override
        public void showErrorMessage()
        {
            System.out.println("no match");
        }
    }
}

在showErrorMessage方法即是印出各個錯誤代碼,接著建立Manager來控制Strategy如下
public class ErrorStrategyManager
{
    public static final int AUDIO_ERROR = 0;
    public static final int CLIENT_ERROR = 1;
    public static final int NOMATCH_ERROR = 2;

    private Map<Integer, IErrorStrategy> mErrors = new HashMap<Integer, IErrorStrategy>();

    public ErrorStrategyManager() {
        initErrors();
    }

    private void initErrors()
    {
        mErrors.put(CLIENT_ERROR, new IErrorStrategy.ClientError());
        mErrors.put(AUDIO_ERROR, new IErrorStrategy.AudioError());
        mErrors.put(NOMATCH_ERROR, new IErrorStrategy.NoMatchError());
    }

    public void showErrorMessage(int errorMessage)
    {
        IErrorStrategy error = mErrors.get(errorMessage);
        error.showErrorMessage();
    }

}

其中使用Map來對應不同的情況對應不同的Strategy,便可取代原本的switch

    private static void useStrategyInsteadSwitchExample(){
        new ErrorStrategyManager().showErrorMessage(condition);
    }


標籤: