员工薪水支付系统介绍
很早以前学习了敏捷软件开发:原则、模式与实践中的薪水支付案例,有些代码设计思想觉得特别好的,特来分享下。
本系统实现了一个计算员工薪水,并发放薪水的功能,该系统必须为不同类型的员工支付正确的薪水,员工类型和结构如下:
- 有些员工是钟点工。会按照他们工作记录中每小时报酬字段的值对他们进行支付。他们每天会提交工作时间卡,其中记录了日期以及工作小时数。如果每天工作超过8小时,那么超过的部分会按照正常报酬的1.5倍进行支付。每周五对他们进行支付。
- 有些员工完全以月薪进行支付。每个月的最后一个工作日对他们进行支付。在他们的雇员记录中有一个月薪字段。
- 还有些销售员工,除了基本工资外,会根据他们的销售情况,支付他们一定数量的酬金。他们会提交销售凭条,其中记录了销售日期和数量。在他们的工作记录中有一个酬金字段,每隔一周的周五对他们进行支付。
员工还可以自由选择发放薪水方式,可以选择银行卡发放、把支票保存在出纳人员那里随时支取或者通过邮寄方式发放。
一些员工还会加入协会。每周需要扣除相应会费,协会有时也会针对单个协会成员征收服务费用。
刚学Java的时候,学习视频里的讲师有提到写代码时要一个类一个方法只做一件事,遇到会变化的内容时要知道抽象出来,我觉得在这个系统里得到了充分的体现。
有3种类型的员工,一般我们可以这么设计:
设计一个父类员工类,然后分别设计小时工、固定薪资员工、销售员工去继承父类员工类,但是这里有个问题,假如哪天有个需求说要把固定薪资员工转为小时工,或者把小时工转为销售员工时,我们该怎么办,很明显子类间是不能转化的。
解决方法是进行抽象,一些员工按小时支付,一些员工按固定薪资支付,一些员工按销售业绩支付。每种类型的员工都需要被支付,只是支付的策略不同,所以我们可以把支付的策略抽象出来。这就有了支付策略接口:
public interface PaymentClassification {//抽象出支付策略类
double calculatePay(Paycheck payCheck);
}
员工类不用理会员工的支付形式,把支付形式交由支付策略接口去解决,由此的到三个实现类:
按工作小时支付:
/*
* 小时工即按小时支付,把按小时支付计算单独拿出来实现
*/
public class HourlyClassification implements PaymentClassification {
private double hourlyRate;//每小时工钱
private List<TimeCard> timeCards=new ArrayList<TimeCard>();//记录员工的工作时间卡
public HourlyClassification(double hourlyRate) {
this.hourlyRate = hourlyRate;
}
public double calculatePay(Paycheck payCheck) {
// TODO Auto-generated method stub
double totalPay=0;
for(TimeCard card:timeCards) {
if(DateUtil.between(card.getDate(), payCheck.getPayPeriodStart(), payCheck.getPayPeriodend()))
totalPay+=calculatePayForTimeCard(card);
}
return totalPay;
}
public void addTimeCard(TimeCard timeCard) {
this.timeCards.add(timeCard);
}
public double calculatePayForTimeCard(TimeCard timeCard) {
double hours=timeCard.getHours();
if(hours>8) {
return (8*hourlyRate+(hours-8)*hourlyRate*1.5);
}else {
return hours*hourlyRate;
}
}
@Override
publi