場(chǎng)景假設(shè)
當(dāng)前界面是一個(gè)工資計(jì)算器畔派,不同的角色有不同的計(jì)算邏輯,比如有三種角色:老師润绵、院長(zhǎng)线椰、校長(zhǎng)。在這個(gè)界面上可以選擇角色尘盼、輸入請(qǐng)假天數(shù)憨愉、輸入工齡烦绳,自動(dòng)計(jì)算出本月工資。
通常寫(xiě)法
class SalaryCalculator
public static final int ROLE_TEACHER = 1;
public static final int ROLE_DEAN = 2;
public static final int ROLE_PRESIDENT = 3;
private int role;
private int leaveCount;//請(qǐng)假天數(shù)
private int workYear;
private int salary;
private int baseSalary;
//...
if(role== ROLE_TEACHER) {
baseSalary = workYear*100+10000; //1年工齡月薪+100
} else if(role== ROLE_DEAN) {
if(workYear >= 10) {
baseSalary = workYear*300+20000;
} else {
baseSalary = workYear*200+20000;
}
} else {
baseSalary = workYear*500+30000;
}
//...為什么不把上下2個(gè)if else里面的代碼合并起來(lái)配紫,因?yàn)檫@只是DEMO径密,簡(jiǎn)單化了真實(shí)場(chǎng)景,真實(shí)場(chǎng)景比如這2段代碼都需要各自在不同的回調(diào)里處理呢
if(role== ROLE_TEACHER) {
salary = baseSalary/23*(23 - leaveCount);
} else if(role== ROLE_DEAN) {
leaveCount = Math.max(leaveCount - 2, 0); //院長(zhǎng)每個(gè)月有額外的2天假期
salary = baseSalary/23*(23 - leaveCount);
} else {
// 校長(zhǎng)請(qǐng)假有半薪躺孝,且每個(gè)月有額外的3天假期
leaveCount = Math.max(leaveCount - 3, 0);
salary = baseSalary/23*(23-leaveCount)+ baseSalary/23/2*leaveCount;
}
//...
策略模式
class SalaryCalculator
public static final int ROLE_TEACHER = 1;
public static final int ROLE_DEAN = 2;
public static final int ROLE_PRESIDENT = 3;
private int role;
private int leaveCount;//請(qǐng)假天數(shù)
private int salary;
private SalaryStrategy strategy;
//...
if(role== ROLE_TEACHER) {
strategy = new TeacherSalaryStrategy ();
} else if(role== ROLE_DEAN) {
strategy = new DeanSalaryStrategy ();
} else {
strategy = new PresidentSalaryStrategy ();
}
//..
strategy.setWorkYear(workYear);
//...
strategy.setLeaveCount(leaveCount);
salary = strategy.getSalary();
//...
interface SalaryStrategy
private void setWorkYear();
private void setLeaveCount();
private int getSalary();
這個(gè)可以用接口享扔,當(dāng)然也可以用抽象類(lèi),抽象類(lèi)里面還能封裝一些基本的公共的代碼植袍。
class TeacherSalaryStrategy implements SalaryStrategy
private int baseSalary=10000;
private int salary;
private void setWorkYear(int workYear){
baseSalary = workYear*100+salary;
}
private void setLeaveCount(int leaveCount){
salary = baseSalary/23*(23 - leaveCount);
}
private int getSalary(){
if(salary==0){
salary = baseSalary;
}
return salary;
}
另外2個(gè)類(lèi)惧眠,院長(zhǎng)和校長(zhǎng)的,自己想吧于个。
總結(jié):
使用了策略模式后氛魁,SalaryCalculator類(lèi)里面只會(huì)出現(xiàn)一次if else
的角色判斷,明顯簡(jiǎn)潔了很多厅篓。這樣后續(xù)有對(duì)薪資算法的修改秀存,就不用改SalaryCalculator類(lèi)了,有針對(duì)性的去不同角色的策略類(lèi)里面修改就可以了羽氮。
當(dāng)你看到一個(gè)類(lèi)里面出現(xiàn)多次相同的判斷條件或链,如例子中出現(xiàn)2次
if(role== ROLE_TEACHER) {
} else if(role==ROLE_DEAN) {
} else {
}
(雖然DEMO只有2次,但是可以繼續(xù)假設(shè)場(chǎng)景乏苦,寫(xiě)出N次if else)
就要考慮是否能把代碼合并在同一個(gè)if else里株扛,是否要使用策略模式。