背景 你要问我设计模式是干嘛的?我的总结就是:构建“大厦”的一套成熟的经验理论,是一套成熟的构建理论。 本篇文章记录,在极客时间课程学习之下的一些纪实与感悟,记录学习的过程。为日后复习、查询所用。 文章纪实部分代码片段来自课程文稿。
课程纪实 原课程链接:https://time.geekbang.org/column/article/179607
学习导读
设计原则与思想:面向对象 设计原则与思想:设计原则 21.重复的代码就一定违背DRY吗?如何提高代码的复用性? DRY原则 (Don’t Repeat Yourself)
实现逻辑重复 代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 public class UserAuthenticator { public void authenticate (String username, String password) { if (!isValidUsername(username)) { } if (!isValidPassword(password)) { } } private boolean isValidUsername (String username) { if (StringUtils.isBlank(username)) { return false ; } int length = username.length(); if (length < 4 || length > 64 ) { return false ; } if (!StringUtils.isAllLowerCase(username)) { return false ; } for (int i = 0 ; i < length; ++i) { char c = username.charAt(i); if (!(c >= 'a' && c <= 'z' ) || (c >= '0' && c <= '9' ) || c == '.' ) { return false ; } } return true ; } private boolean isValidPassword (String password) { if (StringUtils.isBlank(password)) { return false ; } int length = password.length(); if (length < 4 || length > 64 ) { return false ; } if (!StringUtils.isAllLowerCase(password)) { return false ; } for (int i = 0 ; i < length; ++i) { char c = password.charAt(i); if (!(c >= 'a' && c <= 'z' ) || (c >= '0' && c <= '9' ) || c == '.' ) { return false ; } } return true ; } }
虽然从代码实现逻辑上看起来是重复的,但是从语义上并不重复。所谓“语义不重复”指的是:从功能上来看,这两个函数干的是完全不重复的两件事情,一个是校验用户名,另一个是校验密码。 尽管代码实现逻辑是相同的,但是语义不同,我们判定它并不违反DRY原则 。
功能语义重复 示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public boolean isValidIp (String ipAddress) { if (StringUtils.isBlank(ipAddress)) return false ; String regex = "^(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\." + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\." + "(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)$" ; return ipAddress.matches(regex); } public boolean checkIfIpValid (String ipAddress) { if (StringUtils.isBlank(ipAddress)) return false ; String[] ipUnits = StringUtils.split(ipAddress, '.' ); if (ipUnits.length != 4 ) { return false ; } for (int i = 0 ; i < 4 ; ++i) { int ipUnitIntValue; try { ipUnitIntValue = Integer.parseInt(ipUnits[i]); } catch (NumberFormatException e) { return false ; } if (ipUnitIntValue < 0 || ipUnitIntValue > 255 ) { return false ; } if (i == 0 && ipUnitIntValue == 0 ) { return false ; } } return true ; }
这个例子跟上个例子正好相反。上一个例子是代码实现逻辑重复,但语义不重复,我们并不认为它违反了 DRY 原则。而在这个例子中,尽管两段代码的实现逻辑不重复,但语义重复 ,也就是功能重复,我们认为它违反了 DRY 原则
代码执行重复 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public class UserService { private UserRepo userRepo; public User login (String email, String password) { boolean existed = userRepo.checkIfUserExisted(email, password); if (!existed) { } User user = userRepo.getUserByEmail(email); return user; } } public class UserRepo { public boolean checkIfUserExisted (String email, String password) { if (!EmailValidation.validate(email)) { } if (!PasswordValidation.validate(password)) { } } public User getUserByEmail (String email) { if (!EmailValidation.validate(email)) { } } }
重构后的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public class UserService { private UserRepo userRepo; public User login (String email, String password) { if (!EmailValidation.validate(email)) { } if (!PasswordValidation.validate(password)) { } User user = userRepo.getUserByEmail(email); if (user == null || !password.equals(user.getPassword()) { } return user; } } public class UserRepo { public boolean checkIfUserExisted (String email, String password) { } public User getUserByEmail (String email) { } }
代码复用性(Code Reusability) 有三个概念:代码复用性(Code Reusability)、代码复用(Code Resue)和 DRY 原则。“不重复”并不代表“可复用” “复用”和“可复用性”关注角度不同 :代码“可复用性”是从代码开发者的角度来讲的,“复用”是从代码使用者的角度来讲的。
怎么提高代码复用性?
减少代码耦合
满足单一直责原则
模块化
业务与非业务逻辑分离
通用代码下沉
继承、多态、抽象、封装
应用模板等设计模式
设计原则与思想:规范与重构 设计原则与思想:总结课 设计模式与范式:创建型 设计模式与范式:结构型 设计模式与范式:行为型 思考
Related Issues not found
Please contact @nimbusking to initialize the comment