阜阳市城乡建设 档案馆网站wordpress主题商店

diannao/2026/1/16 5:59:36/文章来源:
阜阳市城乡建设 档案馆网站,wordpress主题商店,行政单位建设网站方案,品牌建设存在的问题及对策前言 DRY 原则#xff0c;英文描述为#xff1a; Don’t Repeat Yourself。中文直译#xff1a;不要重复自己。将它应用在编程中#xff0c;可理解为#xff1a;不要写重读的代码。 可能你认为#xff0c;这个原则很简单。只要两段代码长得一样#xff0c;那就是违反 …前言 DRY 原则英文描述为 Don’t Repeat Yourself。中文直译不要重复自己。将它应用在编程中可理解为不要写重读的代码。 可能你认为这个原则很简单。只要两段代码长得一样那就是违反 DRY 原则了。真的是这样吗 答案是否定的。这是很多人对这条原则存在的误解。实际上重读的代码不一定违反 DRY 原则而有些看似不重复的代码也可能违反 DRY 原则。 DRY 原则Don’t Repeat Yourself DRY 原则的定义非常简单我就不再过度解读了。今天主要将三种典型的代码重复情况它们分别是实现逻辑重复、功能语义重复和代码执行重复。这三种代码重复有些看似违反 DRY 原则实际上并不违反有的看似不违反实际上却违反了。 实现逻辑重复 先看一段代码 public class UserAuthenticator {public void authenticate(String username, String password) {if (!isValidUsername(username)) {// throw new InvalidUsernameException...}if (!isValidPassword(password)) {// throw new InvalidPasswordException...}// 省略其他代码...}private boolean isValidUsername(String username) {if (StringUtils.isEmpty(username)) { return false; }// check length: 4-64int length username.length();if (length 4 || length 64) { return false; }// contains only lower case lettersif (StringUtils.isAllLowerCase(username)) { return false; }// contains only z~z,0~9,dotfor (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.isEmpty(password)) { return false; }// check length: 4-64int length password.length();if (length 4 || length 64) { return false; }// contains only lower case lettersif (StringUtils.isAllLowerCase(password)) { return false; }// contains only z~z,0~9,dotfor (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;} }在代码中有两处非常重复的代码片段 isValidUsername() 和 isValidPassword()。重复的代码被敲了两遍看起来明显违反了 DRY 原则。为了移除重复的代码我们进行下重构将 isValidUsername() 和 isValidPassword() 合并Wie一个更通用的函数 isValidUsernameOrPassword()。 public class UserAuthenticator {public void authenticate(String username, String password) {if (!isValidUsernameOrPassword(username)) {// throw new InvalidUsernameException...}if (!isValidUsernameOrPassword(password)) {// throw new InvalidPasswordException...}// 省略其他代码...}private boolean isValidUsernameOrPassword(String usernameOrPassword) {if (StringUtils.isEmpty(usernameOrPassword)) { return false; }// check length: 4-64int length usernameOrPassword.length();if (length 4 || length 64) { return false; }// contains only lower case lettersif (StringUtils.isAllLowerCase(usernameOrPassword)) { return false; }// contains only z~z,0~9,dotfor (int i 0; i length; i) {char c usernameOrPassword.charAt(i);if (!((c a c z) || !(c 0 c 9) || c ! .)) { return false; }}return true;} }重构之后代码行数减少了也没有重复代码了是不是更好呢 单从名字上看合并之后的 isValidUsernameOrPassword() 函数负责两件事情验证用户名和密码违反了单一职责原则和接口隔离原则。实际上即便将两个函数合并成 isValidUsernameOrPassword() 代码仍然存在问题。 因为 isValidUsername() 和 isValidPassword()虽然代码实现逻辑上看起来是重复的但是从语义上并不重复。尽管在目前的设计中两个校验逻辑完全一样但是如果按照第二种写法将两个函数合并那就回农村在潜在的问题。在未来的某一天如果我们修改了密钥校验逻辑比如允许密码包含大写字符允许密码长度为 8 到 64 个字符那这个时候 isValidUsername() 和 isValidPassword() 的实现逻辑就会不相同。我们需要把合并后的函数重新拆分成合并前的两个函数。 所谓 “语义不重复” 是指从功能上看这两个函数干的是完全不重复的事情一个是校验用户名一个是校验密码。 尽管代码的实现逻辑相同但语义不同我们判定它并不违反 DRY 原则。对于包含重复代码的问题我们可以通过抽象成更细粒度函数的方式来解决。比如将校验只包含 a-z、0-9、dot 的逻辑都封装成函数。 功能语义重复 在看另一个例子。在同一个项目代码中有下面两个函数 isValidIp() 和 checkIfIpValid()。尽管命名不同、实现逻辑不同但是功能是相同的都是用来判定 IP 是否合法的。 出现这个现象的原因可能是其中的一个同事不知道已有了 isValidIp() 的情况下自己又定义并实现了相同用来校验 IP 地址是否合法的 checkIfIpValid() 函数。 这两个函数如下所示它们是否违反了 DRY 原则 public boolean isValidIp(String ip) {if (StringUtils.isBlank(ip)) { 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 ip.matches(regex); }public boolean checkIfIpValid(String ip) {if (StringUtils.isBlank(ip)) { return false; }String[] ipUnits StringUtils.split(ip, .);if (ipUnits.length ! 4) { return false; }for (int i 0; i ip.length(); 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 原则。 我们应该在项目中统一一种实现思路所有用到判断 IP 地址是否合法的地方都统一调用一个函数。 假设我们不统一实现思路有些地方调用了 isValidIp()有些地方又调用了 checkIfIpValid()这就会导致代码看起来很奇怪相当于给代码 “挖坑”给不熟悉的这部分代码的同事增加了阅读难度。同事可能研究了半天觉得功能一样但又有点疑问觉得是不是有更高深的考量才定义了两个功能类似的函数最终发现居然是代码设计的问题。 另外如果哪天项目中 IP 地址是否合法的判定逻辑改了比如 255.255.255.255 判定不合法相应地我们对 isValidIp() 的实现逻辑做了修改但却忘记修改 checkIfIpValid()这样就会导致有些代码仍然用老的 IP 判定逻辑导致出现一些莫名其妙的 BUG。 代码执行重复 前两个例子一个是实现逻辑重复一个是语义重复在看下第三个例子。其中 UserService 中 login() 用来校验用户登录是否成功。如果失败就返回异常如果成功就返回用户信息。具体代码如下所示 public class UserService {private UserRepo userRepo; // 通过依赖注入或者IOC框架注入public User login(String email, String password) {boolean existed userRepo.checkIfUserExisted(email, password);if (!existed) {// throw AuthenticationFailureException...}User user userRepo.getUserByEmail(email);return user;} }public class UserRepo {public boolean checkIfUserExisted(String email, String password) {if (EmailValidation.validate(email)) {// throw InvalidEmailException...}if (PasswordValidation.validate(password)) {// throw InvalidPasswordException...}// query db to check if emailpassword exists...}public User getUserByEmail(String email) {if (EmailValidation.validate(email)) {// throw InvalidEmailException...}// query db to get user by email...} }上面的代码既没有逻辑重复也没有语义重复但仍然违反了 DRY 原则。这是因为代码存在 “执行重复”。 重复执行最明显的地阿福就是在 login() 中email 的校验逻辑执行了两次。一次是在调用 checkIfUserExisted() 函数的时候另一次是调用 getUserByEmail() 的时候。这个问题解决起来比较简答只要将校验逻辑从 UserRepo 中移除统一放到 UserService 中就可以了。 此外代码中还有移除比较隐藏的执行重复 login() 函数并不需要调用 checkIfUserExisted()只需要调用一次 getUserByEmail() 从数据库中获取用户的 email、password 等信息然后跟输入的 email、password 信息做比对判断是否登录成功。 这样的优化是很有必要的。因为 checkIfUserExisted() 和 getUserByEmail() 都需要查询数据库而数据库类的 I/O 操作是比较耗时的。我们在写代码的时候应该尽量减少 I/O 操作。 按照刚刚的思路我们重构下代码。 public class UserService {private UserRepo userRepo; // 通过依赖注入或者IOC框架注入public User login(String email, String password) {if (EmailValidation.validate(email)) {// throw InvalidEmailException...}if (PasswordValidation.validate(password)) {// throw InvalidPasswordException...}User user userRepo.getUserByEmail(email);if (user null || !password.equals(user.getPassword())) {// throw AuthenticationFailureException...}return user;} }public class UserRepo {public boolean checkIfUserExisted(String email, String password) {// query db to check if emailpassword exists...}public User getUserByEmail(String email) {// query db to get user by email...} }代码复用性Code Reusability 什么是代码的复用性 首先区分三个概念 代码复用性Code Reusability、代码复用Code Reuse、DRY 原则。 代码复用表示一种行为我们在开发新功能的时候尽量复用已存在的代码。代码复用性表示一段代码可被复用的特性或能力我们在编写代码的时候尽量让代码可复用。DRY 原则是一条原则不要写重复的代码。 首先“不重复” 不代表 “可复用”。在一个项目中可能不存在任何重复的代码但也不表示里面有可复用的代码不重复和可复用完全是两个概念。所以从这个角度来说DRY 原则和可复用性将的是两回事。 其次“复用” 和 “可复用性” 关注角度不同。代码 “可复用性” 是从代码开发者的角度来讲的“复用” 是从代码使用者角度来讲的。比如 A 同事编写了一个 UrlUrils 类代码的 “可复用性” 很好。同事 B 在开发新功能是直接 “复用” A 同事编写的 UrlUrils 类。 虽然复用性、复用、DRY 原则这三者从理解上有区别但是它们的目的是一样的都是为了较少代码量提高代码的可读性、可维护性。此外复用已经过测试的老代码bug 会比从零开发的要少。 “复用” 这个概念不仅可以指导细粒度的模块、类、函数的设计开发实际上一些框架、类库、组件等的生产也都是为了达到复用的目的。比如Spring 框架、UI 组件等等。 怎么提高代码复用性 一共有 7 条规则 减少代码耦合。对于高耦合的代码当希望复用其中的一个功能想把这个功能的代码抽取出来成为一个独立的模块、类或者函数时往往会牵一发而动全身。所以高耦合度的代码会影响到代码的可复用性。满足单一职责原则。 前面讲过如果职责不够单一模块、类设计得大而全那就增加了代码的耦合度依赖它的它依赖的代码就会比较多。也会影响到代码的可复用性。相反粒度越细的代码代码的通用性会越好容易被复用。模块化。这里的 “模块”不单单只一组类构成的模块还可以理解为单个类、函数。我们要善于将功能独立的代码封装成模块。独立的模块就像积木更加容易复用直接拿来搭建更加复杂的系统。业务与非业务逻辑分离。越是和业务无关的代码余额容易复用越是针对特定业务的代码越难复用。所以为了复用跟业务无关的代码我们将业务和非业务逻辑代码分离抽取成一些通用的框架、类库、组件等。通用代码下层。从分层角度来看越底层的代码越通用、会被越多的模块调用越应该设计得足够可复用。一般情况下在代码分层之后为了避免交叉调用导致调用关系混乱我们只允许上层代码调用下层代码及同层代码杜绝下层代码调用上层代码。所以通用的代码我们尽量下沉到更下层。继承、多态、抽象、封装。在讲面向对象特性的时候我们讲过利用继承可以将公共代码抽取到父类子类复用父类的属性和方法。利用多态可以动态替换一段代码的部分逻辑让这段代码可复用。此外抽象和封装从更加广义的层面、而非狭义的面向对象特性层面来理解的话越抽象、越不依赖具体实现越容易复用。代码封装成模块隐藏可变细节、暴露不变的接口就越容易复用。应用模板等设计模式。一些设计模式也能提高代码复用性。比如模板模式利用了多态技术来实现可以灵活地替换其中的部分代码整个流程模板代码可复用。 除了上面讲到的 7 点还有一些跟编程语言相关的特性也可以提高代码的复用性比如泛型编程等。另外除了上面讲到的知识复用意识也很重要。在写代码的时候要取多思考这部分代码是否可以抽取出来作为一个独立模块、类或者函数供多出使用。在设计每个模块、类、函数的时候要像设计一个外部 API 一样去思考它的复用性。 辩证思考和灵活应用 编写可复用的代码并不简单。如果在编写代码时已经有复用的需求场景那根据复用的需求去开发可复用的代码可能还不算难。但是如果当下没有复用的需求只是希望现在编写的代码具有可复用的特点能在未来某个同事开发某个新功能时复用得上。在这种没有具体复用需求的情况下就需要去预测未来代码会如何复用这就比较有挑战了。 实际上除非有明确的复用需求否则为了暂时用不到的复用需求花费太多时间、精力投入太多成的开发成本并不是一个值得推荐的做法。也违反我们之前讲到的 YAGNI 原则。 实际上我们在第一次写代码的时候如果当下没有复用的需求而未来的需求也不是特别明确并且开发复用代码的成本比较高那我们就不需要考虑它的复用性。在之后开发新能够的时候发现可以复用的之前的代码那我们就重构它让其变得更加复用。 总结 1.DRY 原则 讲解了三种重复的情况实现逻辑重复、语义重复、执行逻辑重复。 实现逻辑重复但功能语义不重复并不违反 DRY 原则。实现逻辑不重复但是功能语义重复则违反了 DRY 原则。此外代码执行重复也是违反 DRY 原则。 2.代码复用性 提高代码可复用性的 7 点方法 减少代码耦合满足单一职责原则模块化业务与非业务逻辑分离通用代码下沉继承、多态、抽象、封装应用模板等设计模式 除了上面降到的方法外复用意识也非常重要。在设计每个模块、类、函数时要像设计一个外部 API 一样思考它的复用性。 在第一编写代码时如果当下没有复用需求而未来的复用需求也不是特别明确并且开发可复用代码的成本比较高那我们就不需要考虑代码的复用性。在之后开发新功能时发现可以复用之前的代码那我们就重构这段代码让其变得更加可复用。 相对于代码可复用DRY 原则适用性更强一些。我们可以不写可复用的代码但一定不能写重复的代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/91558.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

5在线做网站东莞建设网官网首页

文章目录 openssl3.2 - 官方demo学习 - cms - cms_sign2.c概述笔记END openssl3.2 - 官方demo学习 - cms - cms_sign2.c 概述 用多个证书进行CMS消息联合签名 笔记 /*! * \file cms_sign2.c * \note openssl3.2 - 官方demo学习 - cms - cms_sign2.c 用多个证书进行CMS消息联…

郑州营销型网站建设工作室常州app网站

socket套接字/TCP 一 客户端/服务器架构 C/S架构,包括 硬件C/S架构(打印机)软件C/S 架构(web服务)C/S架构的软件(软件属于应用层)是基于网络进行通信的Server端要: 1.力求一直提供服…

免费制作个人网站的软件建站工具 营销

在交换机组网时常见的故障比较多,为了帮助大家更好地排除这些故障,在此飞畅科技的小编来为大家介绍一些常见的典型故障案例和处理思路供大家参考。接下来大家就一起来看看交换机组最常见的8大故障及解决方法吧。 环网交换机产品图 故障1:交…

网站的建设哪个好山东省城乡住房和建设厅网站首页

本文来自#30天制图挑战#的GISer November_阿瑜瑜瑜瑜,完成了30幅中国风专辑地图,唯美又有韵味,十分赏心悦目,简直把中国风玩出了花~接下来,快来跟着小编一起细品30幅中国风地图吧~~~ 01day 1千里江山图《千里江山图》是…

做俄罗斯外贸的网站设计网页与网站设计

作为开发人员,我们都想写出优雅的代码,可又苦于自身能力不知该如何下手,而框架的作用正在与能够让你规范的去开发。 之前写Web的时候,总被要求采用MVC架构,的确非常好用,也从来没有质疑过这种架构的好与不好…

建站工具缺点施工企业造价管理

牛客题霸 [ 旋转数组] C题解/答案 题目描述 一个数组A中存有N(N&gt0)个整数,在不允许使用另外数组的前提下,将每个整数循环向右移M(M>0)个位置,即将A中的数据由(A0 A1 ………

欧美品牌网站设计怎么做网站自动响应

在当今这个信息爆炸的时代,图像和视频已经成为我们获取和传递信息的主要方式之一。从社交媒体上的照片分享,到安防监控、自动驾驶等领域的图像识别与处理,计算机视觉技术正日益改变着我们的生活。而在这场技术革命中,OpenCV(Open Source Computer Vision Library)这一开源…

企业做网站需要租服务器吗温州专业营销网站费用

设有 N堆石子排成一排,其编号为 1,2,3,…,N。 每堆石子有一定的质量,可以用一个整数来描述,现在要将这 N 堆石子合并成为一堆。 每次只能合并相邻的两堆,合并的代价为这两堆石子的质量之和,合并后与这两堆石子相邻的…

中山免费建网站湖南企业推广软件

随着数字化转型的深入推进,软件开发和运维的界限变得越来越模糊。在这种背景下,DevOps理念应运而生,它强调开发和运维团队的紧密协作,以实现软件的高效交付和稳定运行。与此同时,低代码技术的发展也为软件开发带来了新…

网站制作:网推宝|百度游戏开发需要学什么专业

参考:Ubuntu下无法看到共享文件夹的解决办法 作者:一只青木呀 发布时间:2020-08-07 10:09:04 网址:https://blog.csdn.net/weixin_45309916/article/details/107856157 今天早上起来突然发现共享文件夹的查看不到了,找…

中国优秀设计网站有哪些书签制作简单漂亮

大家好,我是若川。今天分享一篇vue项目如何做单元测试的好文,文章比较长,建议先收藏,需要时用电脑看。点击下方卡片关注我、加个星标学习源码系列、年度总结、JS基础系列关于单元测试,最常见的问题应该就是“前端单元测…

帮彩票网站做流量提升商务网站建设教学视频教程

目录 基于脚手架创建前端工程 1、环境要求 2、操作过程 3、工程结构 4、启动前端服务 🍃作者介绍:双非本科大三网络工程专业在读,阿里云专家博主,专注于Java领域学习,擅长web应用开发、数据结构和算法&#xff0c…

视频网站seo怎么做张家港企业网站

文章目录 一、索引不同1 InnoDB聚簇索引,MyISAM非聚簇索引1 InnoDB聚簇索引2 MyISAM非聚簇索引 2 InnoDB必须要有主键,MyISAM允许没有主键3 InnoDB支持外键4 InnoDB不支持全文索引5 索引保存位置不同 二、对事物的支持三、存储结构不同四、存储空间不同五…

长沙网站托管网络营销专业就业

文章目录 1. 简介2. iKuai 部署2.1 安装 VMware2.2 安装 iKuai(1) 下载固件(2) 安装 iKuai 虚拟机(3) 配置 iKuai 虚拟机(4) 配置 iKuai(5) 配置多拨分流 2.3 测试速度 3. Clash 部署3.1 准备工作(1) 配置磁盘分区(2) 安装 Docker(3) 安装 Clash(4) 设置代理 1. 简介 由于博主…

怎么做网站收录榆林网站开发公司

servlet的本质是什么,它是如何工作的?基于计算机和网络通讯(主要是http协议)构建网络应用的,具体的实现细节是怎样的? 查看https://www.zhihu.com/question/21416727

网站建设的栏目内容是网站总体策划的内容有哪些

这篇文章是我观看 Mosh 的 MySQL 完整版课程进行题目练习的记录,视频的话去 B 站搜索就能找到,数据库文件的话可以从这里下载。 目录第二章2- SELECT 子句3- WHERE 子句4- 逻辑运算符5- IN 运算符6- BETWEEN 运算符7- LIKE 运算符8- REGEXP 运算符&#…

学生管理系统 静态网站源码广州公司注册费用

系列文章目录 unity工具 文章目录 系列文章目录👉前言👉一、下雨的特效1-1.首先就是创建一个自带的粒子系统,整几张贴图,设置一下就能实现想要的效果了1-2 接着往下看视频效果 👉二、下雪的特效👉三、下雪有积雪的效果3-1 先把控…

oppo网站开发设计手机网页游戏排行榜前十名

前言本文是为了帮大家快速回顾了Java中知识点,这套面试手册涵盖了诸多Java技术栈的面试题和答案,相信可以帮助大家在最短的时间内用作面试复习,能达到事半功倍效果。本来想将文件上传到github上,但由于文件太大有的都无法显示所以…

国内网站怎么做有效果网站收录问题

参考链接: Java中的关联 | 组合和聚合 一.引言 其实自己也不知道,在需求设计、架构设计、开发阶段是否真正需要弄明白“关联、聚合、组合”。原本计划这篇博文写“继承“和”多态”,但是一翻阅资料,基本上都会把“继承”和“组…

岳麓区营销型网站建设定制北京公司注销流程及费用

转载:http://blog.csdn.net/liufei_learning/article/details/19220391 理解Hash 哈希表(hash table)是从一个集合A到另一个集合B的映射(mapping)。 映射是一种对应关系,而且集合A的某个元素只能对应集合B中的一个元素。但反过来,集合B中的一…