JAVA設計模式之策略模式(七)

所有設計模式傳送門

定義一系列算法,把他們一個個封裝起來,並使它們可以相互的替換。本模式使得算法可獨立於使用它的客戶而變化。策略模式 也是處理算法不同變體的一種成熟模式。

包含的角色:
                1、策略:     是一個接口,該接口定義若干個算法標識,即定義了若干個抽象方法。
                2、具體策略: 是實現策略接口的類,即給出算法標識的具體算法。
                3、上下文:  是依賴與策略接口的類,即上下文包含由策略聲明的變量。上下文中提供一個方法,該方法委託策略變量調用具體策略所實現的策略接口中的方法。

優點:
                1、上下文和具體策略是鬆耦合的關係。因此上下文只知道它要使用 某一個實現Strategy接口類的實例,但不知道具體是哪一個類。
                 2、滿足開-閉原則。當增加新的策略時,不需要修改上下文類的代碼,上下文就可以引用新的具體策略的實例。

適用情景:

   1、一個類定義了多種行爲,並且這些行爲在這個類的方法中以多個條件語句的形式出現,那麼可以使用該模式避免在類中大量使用條件語句。
              2、程序不希望暴露覆雜的、與算法相關的數據結構,那麼可以使用該模式封裝算法。
              3、需要使用一個算法的不同變體。     

簡單的例子:

    在某種比賽,有若干個裁判,每位裁判給選手一個得分。選手的最後得分是根據全體裁判的得分計算出來的。請給出幾種計算選手得分的評分方案(策略),對於某次比賽,可以從你的方案中選擇一種方案作爲本次比賽的評分方案。

/**
 * 選手類
 */
public class Person {

    String name;
    double score;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getScore() {
        return score;
    }
    public void setScore(double score) {
        this.score = score;
    }
}

/**
 *  策略接口-計算得分
 */
public interface ComputableStrategy {

    public abstract double computeScore(double[] a);
}

/**
 * 上下文
 */
public class GymnasticsGame {

    ComputableStrategy strategy;
    
    public void setStrategy(ComputableStrategy strategy){
        this.strategy = strategy;
    }
    
    public double getPersonScore(double[] a){
        if (strategy != null) {
            return strategy.computeScore(a);
        }
        else {
            return 0;
        }
    }
}

/**
 * 策略一
 * 計算代數平均分
 */
public class StrategyOne implements ComputableStrategy{

    @Override
    public double computeScore(double[] a) {
        
        double score = 0;
        double sum = 0;
        
        for (int i = 0; i < a.length; i++) {
            sum += a[i];
        }
        score = sum / a.length;
        
        return score;
    }
}

/**
 * 策略二
 * 計算幾何平均分
 */
public class StrategyTwo implements ComputableStrategy{

    @Override
    public double computeScore(double[] a) {
        
        double score = 0;
        double muti = 1;
        int n = a.length;
        
        for (int i = 0; i < a.length; i++) {
            muti *= a[i];
        }
        score = Math.pow(muti, 1.0/n);
        
        return score;
    }
}

/**
 * 策略三
 * 計算去掉最高分最低分以後的代數平均分
 */
public class StrategyThree implements ComputableStrategy{

    @Override
    public double computeScore(double[] a) {
        
        if (a.length <= 0) {
            return 0;
        }
        
        double score = 0;
        double sum = 0;
        
        Arrays.sort(a);
        
        for (int i = 1; i < a.length-1; i++) {
            sum += a[i];
        }
        score = sum / (a.length - 2);
        
        return score;
    }
}

/**
 * 啓動器類
 */
public class Application {

    public static void main(String[] args) {
        
        GymnasticsGame game = new GymnasticsGame();   //上下文對象
        game.setStrategy(new StrategyOne());          //上下文使用策略一
        
        Person zhang = new Person();
        zhang.setName("張三");
        double[] a = {9.12,9.25,8.87,9.81,8.32,7.88};
        
        Person li = new Person();
        li.setName("李四");
        double[] b = {8.12,9.25,8.17,9.81,9.32,7.28};
        
        zhang.setScore(game.getPersonScore(a));
        li.setScore(game.getPersonScore(b));
        
        System.out.println("使用算術平均值方案:");
        System.out.printf("%s 最後得分:%5.3f %n",zhang.getName(),zhang.getScore());
        System.out.printf("%s 最後得分:%5.3f %n",li.getName(),li.getScore());
        
        game.setStrategy(new StrategyTwo());          //上下文使用策略二
        zhang.setScore(game.getPersonScore(a));
        li.setScore(game.getPersonScore(b));
        
        System.out.println("*******************");
        System.out.println("使用幾何平均值方案:");
        System.out.printf("%s 最後得分:%5.3f %n",zhang.getName(),zhang.getScore());
        System.out.printf("%s 最後得分:%5.3f %n",li.getName(),li.getScore());
        
        System.out.println("*******************");
        game.setStrategy(new StrategyThree());          //上下文使用策略三
        zhang.setScore(game.getPersonScore(a));
        li.setScore(game.getPersonScore(b));
        
        System.out.println("使用(去掉最高,最低)算術平均值方案:");
        System.out.printf("%s 最後得分:%5.3f %n",zhang.getName(),zhang.getScore());
        System.out.printf("%s 最後得分:%5.3f %n",li.getName(),li.getScore());
    }
}

最後運行結果:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章