設計模式之策略模式

策略模式就是定義一組算法,將每個算法都封裝起來,並且是他們之間可以互換

 



 

通過類圖可以知道,策略模式設計到如下三個角色

1.Context封裝角色

它也叫上下文角色,其作用就是用來封裝高層模塊對策略的直接訪問,封裝可能存在的變化

 

2.Strategy抽象策略角色

策略的抽象,定義每個算法或策略必須具有的方法和屬性

 

3.ConcreteStrategy 具體策略角色

實現抽象策略中的操作

 

下面是上述類圖的代碼實現:

/**
 * 
 * 抽象策略角色
 * 
 */
public abstract class Strategy {

    // 抽象算法
    public abstract void exec();
}

 

public class ConcreteStragegyA extends Strategy {

    /**
     * 
     * @see com.huashao.chapter.chapter18.ch01.Strategy#exec()
     */
    @Override
    public void exec() {

        System.out.println("ConcreteStragegyA");
    }

}

 

public class ConcreteStragegyB extends Strategy {

    /**
     * 
     * @see com.huashao.chapter.chapter18.ch01.Strategy#exec()
     */
    @Override
    public void exec() {

        System.out.println("ConcreteStragegyB");
    }

}

 

public class ConcreteStragegyC extends Strategy{

    /**
     * 
     * @see com.huashao.chapter.chapter18.ch01.Strategy#exec()
     */
    @Override
    public void exec() {

        System.out.println("ConcreteStragegyC");
    }

}

 

public class Context {

    private Strategy strategy;

    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    public void action() {

        strategy.exec();
    }
}

 

記得有位名人曾經說,人只有兩件事沒有辦法逃避,那就是交稅和死亡。

 

應納個人所得稅稅額= 應納稅所得額× 適用稅率- 速算扣除數
扣除標準3500元/月(2011年9月1日起正式執行)(工資、薪金所得適用)
個稅免徵額3500元  (工資薪金所得適用)


 
其實繳納稅額的計算就可以用策略模式實現,每一個等級的計算看做一種策略
例如:某人某月工資減去社保個人繳納金額和住房公積金個人繳納金額後爲5500 元,個稅計算:(5500-3500)*10%-105=95元
類圖如下:


 
 
代碼如下:
/**
 * 稅收計算器
 * 
 */
public abstract class TaxCalculator {

    // 計算稅收的方法
    protected abstract void calculate(int amount);
}
 
/**
 * 等級爲1的收稅計算
 * 全月應納稅所得額不超過1500
 */
public class Level01 extends TaxCalculator {

    /**
     * @param amount
     * @see com.huashao.chapter.chapter18.c02.TaxCalculator#calculate(int)
     */
    @Override
    protected void calculate(int amount) {

        // 爲了簡單計算不考慮小數
        int tax = amount * 3 / 100 - 0;
        System.out.println("應交稅: " + tax);
    }

}
 
/**
 * 等級2:全月應納稅額在1500-4500
 *
 */
public class Level02 extends TaxCalculator {

    /**
     * @param amount
     * @see com.huashao.chapter.chapter18.c02.TaxCalculator#calculate(int)
     */
    @Override
    protected void calculate(int amount) {

        // 爲了簡單計算不考慮小數
        int tax = amount * 10 / 100 - 105;
        System.out.println("應交稅: " + tax);
    }

}
 
/**
 * 
 *等級3:全月應納稅額在4500-9000
 */
public class Level03 extends TaxCalculator {

    /**
     * @param amount
     * @see com.huashao.chapter.chapter18.c02.TaxCalculator#calculate(int)
     */
    @Override
    protected void calculate(int amount) {

        // 爲了簡單計算不考慮小數
        int tax = amount * 20 / 100 - 555;
        System.out.println("應交稅: " + tax);
    }

}
 
public class Context {

    private TaxCalculator taxcal;

    public Context(TaxCalculator taxcal) {

        this.taxcal = taxcal;
    }

    // 計算稅收
    public void calculate(int amount) {
        taxcal.calculate(amount);
    }
}
 
其實看上面的策略模式,可以看到它有一個缺點就是客戶端必須知道所有的策略,能否不需要客戶端知道所有策略也能得到想要的答案呢?答案當然是肯定,下面我們利用前面說的工廠模式修改一下,客戶端只需要輸入一個金額,程序便返回正確的稅收值,類圖如下:
 


 
代碼如下:
/**
 * 稅收等級
 * 
 */
public class Level {

    private int amount;

    private String level;

    public Level(int amount) {

        this.amount = amount - 3500;

        if (this.amount <= 1500) {
            level = "A";
        } else if (this.amount <= 4500) {
            level = "B";
        } else if (this.amount <= 9000) {
            level = "C";
        }
    }

    public int getAmount() {
        return amount;
    }

    public String getLevel() {
        return level;
    }

}
 
/**
 * 稅收策略工廠
 * 
 */
public abstract class TaxFactory {

    protected abstract TaxCalculator createTaxCal(Level level);
}
 
/**
 * 
 */
public class TaxCalFactory extends TaxFactory {

    /**
     * @param level
     * @return
     */
    @Override
    protected TaxCalculator createTaxCal(Level level) {

        if ("A".equalsIgnoreCase(level.getLevel())) {
            return new Level01();
        }

        if ("B".equalsIgnoreCase(level.getLevel())) {
            return new Level02();
        }

        if ("C".equalsIgnoreCase(level.getLevel())) {
            return new Level03();
        }

        return null;
    }

}
 
public class Client {

    public static void main(String[] args) {
        
        Level level=new Level(4000);
        
        TaxFactory factory=new TaxCalFactory();
        
        TaxCalculator calculator=factory.createTaxCal(level);
        
        calculator.calculate(level.getAmount());
        
                
    }
}
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章