一。场景
以前给医院算过一次医院工作人员的工资每种医生护士的工资算法都不同,当时特别蠢,直接面向过程,频繁的ifelse去计算。
最近可能会计算律师的工资,所以自己编一个律师工资为场景。实际上的工资计算远远要麻烦的多
1.律师有实习律师、正式律师、律师主任三种类型on
2.实习律师的工资为基本工资1000+所办案件收入的10%+出勤数*100;
正式律师的工资为基本工资2000+所办案件收入的20%+出勤数*200
主任的工资为基本工资3000+所办案件收入的30%+出勤数*300
二。实现
1.原来的实现
public class SimpleSalaryCal {
public static void main(String[] args) {
System.out.print("请输入律师类型");
Scanner scan = new Scanner(System.in);
String lawyerType = scan.nextLine();
System.out.print("请输入基本工资");
String baseSalary = scan.nextLine();
System.out.print("请输入出勤数");
String workDays = scan.nextLine();
System.out.print("请输入案件金额");
String caseAmount = scan.nextLine();
switch (lawyerType) {
case "1":
System.out.println("实习律师的工资算法,出勤奖金每天100,案件金额的20%");
break;
case "2":
System.out.println("正式律师的工资算法,出勤奖金每天200,案件金额的30%");
break;
case "3":
System.out.println("律师主任的工资算法,出勤奖金每天300,案件金额的40%");
break;
}
}
}
缺点:
1.面向过程,不易扩展、不易维护、不易复用,所有计算堆在一起,如果要加一个律师类型或修改算法就要直接更改客户端的代码,不易维护和扩展,如果别的地方能用到计算工资,就无法复用
2.SimpleSalaryCal就是客户端,客户直接能看到计算过程,耦合性太高
2简单工厂模式的实现
工资算法接口
public interface SalaryCalculation {
/**
*
* @param workDays 出勤数
* @param baseSalayr基本工资
* @param caseAmount 案件收费金额
* @param lawyerType 律师类型
* @return
*/
public Double getSalary(Double baseSalary,Integer workDays,Double caseAmount,Integer lawyerType);
}
三种律师类型工资算法实现
/**
* 实习工资
* @author Administrator
*
*/
public class InternshipSalary implements SalaryCalculation {
@Override
public Double getSalary(Double baseSalayr, Integer workDays, Double caseAmount, Integer lawyerType) {
return baseSalayr+workDays*100+caseAmount*0.1;
}
}
public class LawyerSalayr implements SalaryCalculation {
@Override
public Double getSalary(Double baseSalayr, Integer workDays, Double caseAmount, Integer lawyerType) {
return baseSalayr+workDays*200+caseAmount*0.2;
}
}
public class Director implements SalaryCalculation {
@Override
public Double getSalary(Double baseSalary, Integer workDays, Double caseAmount, Integer lawyerType) {
return baseSalary+workDays*300+caseAmount*0.3;
}
}
简单工厂:
public class SalaryFactory {
public static SalaryCalculation createSalaryCalculation(Integer lawyerType){
SalaryCalculation salaryCalculation = null;
switch (lawyerType) {
case 1:
salaryCalculation = new InternshipSalary();
break;
case 2:
salaryCalculation = new LawyerSalayr();
break;
case 3:
salaryCalculation = new Director();
break;
}
return salaryCalculation;
}
}
客户端实现:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.print("请输入律师类型");
String lawyerType = scan.nextLine();
System.out.print("请输入基本工资");
String baseSalary = scan.nextLine();
System.out.print("请输入出勤数");
String workDays = scan.nextLine();
System.out.print("请输入案件金额");
String caseAmount = scan.nextLine();
SalaryCalculation calculation = SalaryFactory.createSalaryCalculation(Integer.valueOf(lawyerType));
Double salary = calculation.getSalary(Double.valueOf(baseSalary), Integer.valueOf(workDays), Double.valueOf(caseAmount), Integer.valueOf(lawyerType));
System.out.println(salary);
}
三。点睛
1.客户端看不到具体的算法,界面与算法完全分开,耦合性降低
2.如果又添加了一种律师类型和其工资计算方式,只需要再加一个实现工资接口的类,以及在工厂中修改swtich,方便扩展;如果某个律师的算法修改,只需要修改此类型的律师类,方便维护
3.面向对象,复用性提高
4.简单工厂还是为了创建对象,输入不同的条件就创建不同的对象