[关闭]
@iamfox 2016-10-09T15:40:22.000000Z 字数 5045 阅读 1450

业务代码重构示例

学习



1.反面示例

这是知识库模块,修改试卷的实现。

  1. //选择和修改试卷试题
  2. public void ModifyKBQuestionnaire(ModifyKBQuestionCommand command) throws KBQuestionException, KBResourceException{
  3. KBQuestionnaire kbQuestionnaire = (KBQuestionnaire) get(command.getQuestionnaireId());
  4. if(kbQuestionnaire == null){
  5. throw new KBResourceException(KBResourceException.ENTITY_NOT_FOUND, "试卷不存在");
  6. }
  7. List<String> addList = command.getAddQuestionIds();
  8. List<String> delList = command.getDelQuestionIds();
  9. System.out.println(addList.size());
  10. System.out.println(delList.size());
  11. String a=addList.get(0);
  12. String[] b = a.split(",");
  13. System.out.println(b.length);
  14. if (StringUtils.isNotBlank(b[0])) {
  15. for (int j = 0; j < b.length; j++) {
  16. KBQuestion kbQuestion = kbQuestionService.get(b[j]);
  17. if(kbQuestion == null){
  18. throw new KBQuestionException(KBQuestionException.ENTITY_NOT_FOUND, "问题不存在");
  19. }
  20. KBQuestionnaireAndQuestionLink link = new KBQuestionnaireAndQuestionLink();
  21. link.create(kbQuestion, kbQuestionnaire);
  22. kbQuestionnaire.addQuestionNum(1);
  23. update(kbQuestionnaire);
  24. save(link);
  25. }
  26. }
  27. String c=delList.get(0);
  28. String[] d = c.split(",");
  29. System.out.println(d.length);
  30. if (StringUtils.isNotBlank(d[0]) ){
  31. for (int j = 0; j < d.length; j++) {
  32. System.out.println(d[j]);
  33. KBQuestionQO kbQuestionQO=new KBQuestionQO();
  34. kbQuestionQO.setId(d[j]);
  35. KBQuestionnaireAndQuestionLinkQO kbQuestionnaireAndQuestionLinkQO=new KBQuestionnaireAndQuestionLinkQO();
  36. kbQuestionnaireAndQuestionLinkQO.setKbQuestionQO(kbQuestionQO);
  37. KBQuestionnaireAndQuestionLink link=kbQuestionnaireAndQuestionLinkService.queryUnique(kbQuestionnaireAndQuestionLinkQO);
  38. if(link != null){
  39. kbQuestionnaireAndQuestionLinkService.deleteById(link.getId());
  40. kbQuestionnaire.delQuestionNum(1);
  41. update(kbQuestionnaire);
  42. }
  43. }}
  44. }
  1. /**
  2. * 修改试卷题目
  3. */
  4. public class ModifyKBQuestionCommand extends BaseCommand {
  5. private List<String> addQuestionIds;//问题id
  6. private List<String> delQuestionIds;//问题id
  7. private String questionnaireId;//试卷id
  8. public List<String> getAddQuestionIds() {
  9. return addQuestionIds;
  10. }
  11. public void setAddQuestionIds(List<String> addQuestionIds) {
  12. this.addQuestionIds = addQuestionIds;
  13. }
  14. public List<String> getDelQuestionIds() {
  15. return delQuestionIds;
  16. }
  17. public void setDelQuestionIds(List<String> delQuestionIds) {
  18. this.delQuestionIds = delQuestionIds;
  19. }
  20. public String getQuestionnaireId() {
  21. return questionnaireId;
  22. }
  23. public void setQuestionnaireId(String questionnaireId) {
  24. this.questionnaireId = questionnaireId;
  25. }

2.存在问题

  1. 方法名没有小写开头,基本规范。
  2. 修改KBQuestionnaire没在KBQuestionnareService操作而是写进了KBResourceService
  3. command表达和方法名不匹配。command是修改问题,方法实现的是修改试卷。
  4. system.out过多没有清理。
  5. 无意义的变量命名a b c d j,毫无可读性。
  6. 字符串切割split不属于业务逻辑,在外层做好转换再进来,影响逻辑阅读。
  7. 循环执行update(kbQuestionnaire);没有意义,如果不是hibernate自动优化这里update sql语句已经泛滥了。
  8. 在循环里一条一条按id查实体。要用in查询一次性查完,不要循环产生大量sql。
  9. 没有格式化代码,空格空行混乱。容易引起git冲突。
  10. command字段顺序和注释混乱,可读性差。

再次强调:
- 代码写给人看比跑起来更重要,不要为了省几秒钟时间随意乱写!节省的时间最后会在调试和扩展时十倍几十倍耗掉。
- 代码混乱一般不是因为逻辑复杂,也和技术水平无关,先规划,不要想到哪写到哪。

3.重构

3-1.调整command

要修改的command,实体id是最重要的参数,放最上面。变量名和注释都要表达准确含义。少用缩略英文写法,每个人缩略习惯不一样,大多数缩略只会降低整体阅读效率。

  1. /**
  2. * 修改试卷题目
  3. */
  4. @SuppressWarnings("serial")
  5. public class ModifyKBQuestionnaireCommand extends BaseCommand {
  6. private String questionnaireId;// 试卷id
  7. private List<String> addQuestionIds;// 要添加的问题id集合
  8. private List<String> deleteQuestionIds;// 要删除的问题id集合
  9. public List<String> getAddQuestionIds() {
  10. return addQuestionIds;
  11. }
  12. public void setAddQuestionIds(List<String> addQuestionIds) {
  13. this.addQuestionIds = addQuestionIds;
  14. }
  15. public List<String> getDeleteQuestionIds() {
  16. return deleteQuestionIds;
  17. }
  18. public void setDeleteQuestionIds(List<String> deleteQuestionIds) {
  19. this.deleteQuestionIds = deleteQuestionIds;
  20. }
  21. public String getQuestionnaireId() {
  22. return questionnaireId;
  23. }
  24. public void setQuestionnaireId(String questionnaireId) {
  25. this.questionnaireId = questionnaireId;
  26. }
  27. }

3-2.先写注释

  1. public void modifyKBQuestionnaire(ModifyKBQuestionnaireCommand command) throws KBResourceException {
  2. // 查出要修改的试卷
  3. // 查出要添加的全部问题
  4. // 遍历问题逐个创建和试卷的关联
  5. // 查出要删除的全部试卷问题关联
  6. // 循环删除关联
  7. // 保存更新试卷问题数量统计
  8. }

整个方法其实就几大步骤,用注释规划好步骤。

3-3.填充代码

  1. public void modifyKBQuestionnaire(ModifyKBQuestionnaireCommand command) throws KBResourceException {
  2. // 查出要修改的试卷
  3. KBQuestionnaire questionnaire = get(command.getQuestionnaireId());
  4. if (questionnaire == null) {
  5. throw new KBResourceException(KBResourceException.ENTITY_NOT_FOUND, "试卷不存在");
  6. }
  7. // 查出要添加的全部问题
  8. KBQuestionQO questionQO = new KBQuestionQO();
  9. questionQO.setIds(new ArrayList<String>());
  10. for (String addQuestionId : command.getAddQuestionIds()) {
  11. questionQO.getIds().add(addQuestionId);
  12. }
  13. List<KBQuestion> questions = questionService.queryList(questionQO);
  14. // 遍历问题逐个创建和试卷的关联
  15. for (KBQuestion question : questions) {
  16. KBQuestionnaireAndQuestionLink link = new KBQuestionnaireAndQuestionLink();
  17. link.create(question, questionnaire);
  18. save(link);
  19. questionnaire.addQuestionNum(1);
  20. }
  21. // 查出要删除的试卷和问题关联
  22. KBQuestionnaireAndQuestionLinkQO linkQO = new KBQuestionnaireAndQuestionLinkQO();
  23. linkQO.setKbQuestionQO(new KBQuestionQO());
  24. linkQO.getKbQuestionQO().setIds(new ArrayList<String>());
  25. for (String deleteQuestionId : command.getDeleteQuestionIds()) {
  26. linkQO.getKbQuestionQO().getIds().add(deleteQuestionId);
  27. }
  28. List<KBQuestionnaireAndQuestionLink> links = kbQuestionnaireAndQuestionLinkService.queryList(linkQO);
  29. // 循环删除关联
  30. for (KBQuestionnaireAndQuestionLink link : links) {
  31. kbQuestionnaireAndQuestionLinkService.delete(link);
  32. questionnaire.addQuestionNum(-1);
  33. }
  34. // 更新试卷问题计数
  35. update(questionnaire);
  36. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注