4月份进入公司后由于对接人很快就要跑路了,所以草草将他手头的项目交接给我了。先拿到的是招聘公众号及其后端管理系统的老项目,项目注释几乎没有,字段命名很随意,而且各种循环查等等,要吐血的感觉。下面是个简单的招聘系统人员简历信息同步到人事系统的代码。
两张表的数据同步直接写在一个方法中,这样后续新增其他表的数据同步是不方便,而且代码回堆积在一个方法之中,不便于维护并且容易出现错误,并且后面人事果然说需要增加其他几张表的数据同步,于是进行如下的简单改造。
@Data
public abstract class AbstractDecorator {
protected AbstractDecorator abstractDecorator;
protected Object data;
protected AbstractDecorator(){};
protected AbstractDecorator(Object data){
this(null,data);
}
protected AbstractDecorator(AbstractDecorator abstractDecorator, Object data){
this.abstractDecorator = abstractDecorator;
if(isLawFulOBJ(data)) {
this.data = data;
}
}
//执行导入,并且调用被装饰者对象的执行导入
public void excute(){
//调用初始化方法
init();
//如果当前导入类数据不为空才执行真正导入方法
if(this.data != null) {
doImport();
}
//如果该导入类有其他被装饰者
if(this.abstractDecorator != null){
//执行被装饰者的导入
this.abstractDecorator.excute();
}
}
public AbstractDecorator setData(Object data){
if(isLawFulOBJ(data)) {
this.data = data;
}
return this;
}
//真正导入操作
protected abstract void doImport();
//判断导入数据是否合法
protected abstract boolean isLawFulOBJ(Object data);
//初始化 (可以在这里初始化DAO)
protected abstract void init();
}
public class StaffInfoAddImport extends AbstractDecorator {
private StaffinfoaddDao staffinfoaddDao;
private StaffInfoAddImport(){}
public StaffInfoAddImport(Object data){
this(null,data);
}
public StaffInfoAddImport(AbstractDecorator abstractDecorator, Object data){
super(abstractDecorator,data);
}
@Override
protected void doImport(){
Asserts.isNotNull(staffinfoaddDao,"导入错误,异常!");
if(data instanceof HrEducation){
HrEducation hrEducation = (HrEducation)data;
Staffinfoadd staffinfoadd = new Staffinfoadd();
staffinfoadd.setStaffname(hrEducation.getStaffname());
staffinfoadd.setStaffcode(hrEducation.getStaffcode());
staffinfoadd.setFullgraduationtime(hrEducation.getEnddate());
staffinfoadd.setFullgraduation(hrEducation.getSchoolname());
staffinfoadd.setFullmajor(hrEducation.getMajor());
staffinfoadd.setFulltime(hrEducation.getEducation());
staffinfoaddDao.insert(staffinfoadd);
}else{
Staffinfoadd staffinfoadd = (Staffinfoadd) this.data;
staffinfoaddDao.insert(staffinfoadd);
}
}
@Override
protected boolean isLawFulOBJ(Object data) {
return data instanceof HrEducation || data instanceof Staffinfoadd;
}
@Override
protected void init(){
this.staffinfoaddDao = ApplicationContextUtils.getBean(StaffinfoaddDao.class);
}
}
public class FamilyPlanningImport extends AbstractDecorator {
private FamilyPlanningDao familyPlanningDao;
private FamilyPlanningImport(){}
public FamilyPlanningImport(Object data){
this(null,data);
}
public FamilyPlanningImport(AbstractDecorator abstractDecorator, Object data){
super(abstractDecorator,data);
}
@Override
protected void doImport(){
Asserts.isNotNull(familyPlanningDao,"导入错误,异常!");
TRecDelivery tRecDelivery = (TRecDelivery)data;
TRecResume tRecResume = tRecDelivery.getResume();
TRecObsterical obsterical = tRecResume.getObsterical();
TRecSpouseInfo spouseInfo = tRecResume.getSpouseInfo();
if(tRecResume != null) {
FamilyPlanning familyPlanning = new FamilyPlanning();
if (spouseInfo != null) {
familyPlanning.setPName(spouseInfo.getFullName()).
setPBirthday(spouseInfo.getBirthday()).
setPChild(spouseInfo.getFertilityTimes()).
setPMarry(spouseInfo.getMaritalStatusName())
.setPId(spouseInfo.getIdCard())
.setPTelephone(spouseInfo.getPhoneNumber())
.setPHukou(spouseInfo.getRegistrationType())
.setPCompany(spouseInfo.getWorkUnit());
}
familyPlanningDao.insert(familyPlanning);
}
}
@Override
protected boolean isLawFulOBJ(Object data) {
return data instanceof TRecDelivery;
}
@Override
protected void init(){this.familyPlanningDao = ApplicationContextUtils.getBean(FamilyPlanningDao.class);
}
}
其他几个表的同步基本代码差不多,使用的时候只需要new包裹起来就可以了。
后面其他表的同步只需要新建一个类继承AbstractDecorator 并且写导入数据逻辑就OK了,可以自由选择组合导入哪些数据,这个就是装饰者,有个可以优化的地方,就是装饰者的data数据可以直接传参穿个下个装饰者的,后面我会在项目中进行优化。
改造完后,人事又提了之前一个功能的变更。那就是招聘系统的数据入到人事系统的数据库时,工种名称不同需要转换,之前代码也和上面差不多写在一个方法内,就不贴出来了。下面看看如何改造的。
AbstractConversionChain
public abstract class AbstractConversionChain {
//下一个节点
protected AbstractConversionChain nextConversion;
//资格等级
protected QualificationLevel qualificationLevel;
public String doConversion(QualificationLevel qualificationLevel,String positionName){
//判断当前转换类是否可以执行转换
if(canConversion()){
return conversion(positionName);
}
//执行下个节点
if(nextConversion != null) {
return nextConversion.doConversion(qualificationLevel,positionName);
}
//未找到能够处理的转换类
return positionName;
}
//转换方法
protected abstract String conversion(String positionName);
protected Boolean canConversion(){
return this.qualificationLevel.equals(qualificationLevel);
}
}
ChainFactory
public class ChainFactory implements Factory <AbstractConversionChain>{
@Override
public AbstractConversionChain getObject(Object o) {
check(o);
switch ((EmploymentType)o){
case REGULAR:{
return new Regular7BChainAbstract();
}
case LABOR:{
return new Labor7BChainAbstract();
}
case TRAINEE:{
return new TraineeDefaultChainAbstract();
}
default:;
}
throw new RuntimeException("未找到相关工种转换器。。");
}
@Override
public boolean check(Object o) {
if(o instanceof EmploymentType) {
return true;
}
throw new RuntimeException("初始化ChainFactory失败。。");
}
}
Labor7BChainAbstract
public class Labor7BChainAbstract extends AbstractConversionChain {
public Labor7BChainAbstract(){
this(null);
}
public Labor7BChainAbstract(AbstractConversionChain abstractConversionChain){
this.nextConversion = abstractConversionChain;
this.qualificationLevel = QualificationLevel.SEVENBLEVEL;
}
@Override
protected String conversion(String positionName) {
switch (positionName){
case "叉车司机":
case "理货员":positionName = "搬运工";break;
case "电脑员":
case "办单员":
case "打单员":
case "现场管理员":positionName = "电脑录入员";break;
case "小车司机":positionName = "导车员";break;
case "监控员":positionName = "GPS管理员";break;
case "电工":positionName = "焊工";break;
}
return positionName;
}
@Override
protected Boolean canConversion() {
return true;
}
}
Regular7BChainAbstract
public class Regular7BChainAbstract extends AbstractConversionChain {
public Regular7BChainAbstract(){
this(null);
}
public Regular7BChainAbstract(AbstractConversionChain abstractConversionChain){
this.nextConversion = abstractConversionChain;
this.qualificationLevel = QualificationLevel.SEVENBLEVEL;
}
@Override
protected String conversion(String positionName) {
switch (positionName){
case "叉车司机":
case "理货员":positionName = "搬运工";break;
case "电脑员":
case "办单员":
case "打单员":
case "现场管理员":positionName = "电脑录入员";break;
case "小车司机":positionName = "导车员";break;
case "监控员":positionName = "GPS管理员";break;
case "电工":positionName = "焊工";break;
}
return positionName;
}
}
TraineeDefaultChainAbstract
public class TraineeDefaultChainAbstract extends AbstractConversionChain {
public TraineeDefaultChainAbstract(){
this(null);
}
public TraineeDefaultChainAbstract(AbstractConversionChain abstractConversionChain){
this.nextConversion = abstractConversionChain;
this.qualificationLevel = QualificationLevel.OTHER;
}
@Override
protected String conversion(String positionName) {
return "搬运工";
}
}
因为有三个用工性质,所有用工厂模式生成责任链,如果以后有新的用工性质出现只需要在工厂中添加就行了,用责任链模式是因为每个用工性质都有不同的级别,所有用责任链模式每个级别的转换都是责任链的一部分,因为现在用工性质下得所有级别转换是一样的,所以现在每个用工性质就一个责任链,如果以后有不同级别的转换不同了就可以新建一个责任链类,在工厂里面new 包裹起来就好了,这看着有点像上面的装饰者模式,但我的理解是装饰者模式侧重的是原对象的方法的的基础上拓展,责任链则是每个类的处理方法都是独立的,不是拓展其他责任链里面的类。
在改造中还使用了建造者、桥接、组合等等一些其他模式,因为功能都比较简单就不一 一列出了。