当前位置: 首页 > news >正文

手机一元云购网站建设网页设计首页

手机一元云购网站建设,网页设计首页,乡镇网站个人做可以不,网站搭建服务平台这篇文章介绍了重构真正的开源代码#xff08; Gradle Modules Plugin #xff09;时应用的五​​种#xff08;最著名的#xff09;重构原理。 语境 当我为Gradle Modules Plugin #xff08;PR #xff03;73 #xff09; 单独编译 module-info.java #xff0c;我注… 这篇文章介绍了重构真正的开源代码 Gradle Modules Plugin 时应用的五​​种最著名的重构原理。 语境 当我为Gradle Modules Plugin PR 73 单独编译 module-info.java 我注意到了一些重构的潜力。 结果我提交了问题79 后来又通过PR 88 尚未合并解决了该问题在其中重构了代码。 事实证明重构比我最初想象的要广泛得多。 在这里我介绍此PR的一部分作为我在此处应用的重构原则的示例。 重构原理 注意这里列出的列表绝不是全面的并且原则不是原创的不过我以自己的声音并根据自己的理解提出了这些原则。 正如我所看到的这篇文章的最大价值在于遵循这些原则的真实示例。 这里介绍的五项原则是 用“什么”隐藏“如何” 力求一致性 避免深层嵌套 单独的关注点单一责任原则 明智地避免重复不要重复自己 1.用“什么”隐藏“如何” 该原则只是由Robert Martin提出的“ 干净代码”原则的一部分。 对我来说用“什么”隐藏“如何”意味着在任何时候提取类和方法 我可以识别出由一段代码执行的独特不平凡的功能并且 我可以用一个有意义的名称将这种不琐碎的事情隐藏起来。 示例1 重构之前这是RunTaskMutator的一个片段 mainDistribution.contents(copySpec - copySpec.filesMatching(patchModuleExtension.getJars(), action - { RelativePath relativePath action.getRelativePath().getParent().getParent() .append( true , patchlibs , action.getName()); action.setRelativePath(relativePath); })); 这是重构后的代码段 mainDistribution.contents( copySpec - copySpec.filesMatching(patchModuleExtension.getJars(), this ::updateRelativePath) ); 综上所述我们 隐藏如何更新相对路径 与我们有什么 我们更新它的事实。 由于有了这样的重构掌握mainDistribution发生的事情要容易mainDistribution 。 作为参考 这里提供了updateRelativePath的内容。 示例2 这是重构之前TestTask类的一部分的样子 TestEngine.select(project).ifPresent(testEngine - { args.addAll(List.of( --add-reads , moduleName testEngine.moduleName)); SetFile testDirs testSourceSet.getOutput().getClassesDirs().getFiles(); getPackages(testDirs).forEach(p - { args.add( --add-opens ); args.add(String.format( %s/%s%s , moduleName, p, testEngine.addOpens)); }); }); 如下所示 TestEngine.select(project).ifPresent(testEngine - Stream.concat( buildAddReadsStream(testEngine), buildAddOpensStream(testEngine) ).forEach(jvmArgs::add)); 同样我们 隐藏如何 --add-reads和--add-opens选项的值 与我们有什么 我们指定它们的事实。 作为参考可在此处获得buildAddReadsStream和buildAddOpensStream的内容。 2.追求一致性 这很笼统但是我的意思是我们可以获得任何合理的一致性。 例如 唐纳德·拉布 Donald Raab 关于对称的博客文章就是努力保持一致性的一个很好的例子。 不用说我完全同意他的结论 具有对称性的大型系统变得更容易理解因为您可以检测并期望重复出现的模式。 Donald Raab对称的同情 对于Gradle Modules Plugin这主要归结为提取AbstractModulePluginTask基类并统一任务查找和配置调度过程。 例如重构之前的JavadocTask和TestTask是 public class JavadocTask { public void configureJavaDoc(Project project) { Javadoc javadoc (Javadoc) project.getTasks().findByName(JavaPlugin.JAVADOC_TASK_NAME); if (javadoc ! null ) { // ... } } } public class TestTask { public void configureTestJava(Project project, String moduleName) { Test testJava (Test) project.getTasks().findByName(JavaPlugin.TEST_TASK_NAME); // ... (no null check) } } 之后它们是 public class JavadocTask extends AbstractModulePluginTask { public void configureJavaDoc() { helper().findTask(JavaPlugin.JAVADOC_TASK_NAME, Javadoc. class ) .ifPresent( this ::configureJavaDoc); } private void configureJavaDoc(Javadoc javadoc) { /* ... */ } } public class TestTask extends AbstractModulePluginTask { public void configureTestJava() { helper().findTask(JavaPlugin.TEST_TASK_NAME, Test. class ) .ifPresent( this ::configureTestJava); } private void configureTestJava(Test testJava) { /* ... */ } } 供参考 JavaDocTask diff和TestTask diff 。 3.避免深度嵌套 我想这很明显。 对我而言控制结构的深层嵌套非常难以阅读和掌握。 结果我重构了以下getPackages方法 private static SetString getPackages(CollectionFile dirs) { SetString packages new TreeSet(); for (File dir : dirs) { if (dir.isDirectory()) { Path dirPath dir.toPath(); try (StreamPath entries Files.walk(dirPath)) { entries.forEach(entry - { if (entry.toFile().isFile()) { String path entry.toString(); if (isValidClassFileReference(path)) { Path relPath dirPath.relativize(entry.getParent()); packages.add(relPath.toString().replace(File.separatorChar, . )); } } }); } catch (IOException e) { throw new GradleException( Failed to scan dir, e); } } } return packages; } 如下所示 private static SetString getPackages(CollectionFile dirs) { return dirs.stream() .map(File::toPath) .filter(Files::isDirectory) .flatMap(TestTask::buildRelativePathStream) .map(relPath - relPath.toString().replace(File.separatorChar, . )) .collect(Collectors.toCollection(TreeSet:: new )); } private static StreamPath buildRelativePathStream(Path dir) { try { return Files.walk(dir) .filter(Files::isRegularFile) .filter(path - isValidClassFileReference(path.toString())) .map(path - dir.relativize(path.getParent())); } catch (IOException e) { throw new GradleException( Failed to scan dir, e); } } 可在此处找到完整的差异 。 4.单独的问题 SRP 单一职责原则 是众所周知的软件设计原则。 在这里我们可以看到其在从RunTaskMutator中提取StartScriptsMutator应用程序。 之前 public class RunTaskMutator { // common fields public void configureRun() { /* ... */ } public void updateStartScriptsTask(String taskStartScriptsName) { /* ... */ } // 12 other methods (incl. 2 common methods) } 后 public class RunTaskMutator extends AbstractExecutionMutator { public void configureRun() { /* ... */ }   // 2 other methods } public class StartScriptsMutator extends AbstractExecutionMutator { public void updateStartScriptsTask(String taskStartScriptsName) { /* ... */ } // 8 other methods } 由于提取了StartScriptsMutator 因此更容易理解以下范围 本身配置run任务 配置相关的startScripts任务。 供参考以上提取的提交 。 5.明智地避免重复 DRY 请勿重复 是另一种著名的软件开发原理。 但是以我的经验这个原则有时太过复杂导致代码无法重复但是也太复杂了。 换句话说只有在成本/收益比为正时才应该重复数据删除 成本 重构时间产生的复杂性等 获得 没有重复或更严格地说是唯一的真理来源 。 Gradle Modules Plugin中的一个这样的例子在我看来成本/收益比接近零但仍然为正是PatchModuleResolver的引入。 下面是重构前的代码片段其中包括 PatchModuleExtension.configure方法。 使用它的地方 TestTask 。 无法使用的地方 RunTaskMutator 。 不能使用它的另一个地方 JavadocTask 。 // 1. PatchModuleExtension public ListString configure(FileCollection classpath) { ListString args new ArrayList(); config.forEach(patch - { String[] split patch.split( ); String asPath classpath.filter(jar - jar.getName().endsWith(split[ 1 ])).getAsPath(); if (asPath.length() 0 ) { args.add( --patch-module ); args.add(split[ 0 ] asPath); } } ); return args; } // 2. TestTask args.addAll(patchModuleExtension.configure(testJava.getClasspath())); // 3. RunTaskMutator patchModuleExtension.getConfig().forEach(patch - { String[] split patch.split( ); jvmArgs.add( --patch-module ); jvmArgs.add(split[ 0 ] PATCH_LIBS_PLACEHOLDER / split[ 1 ]); } ); // 4. JavadocTask patchModuleExtension.getConfig().forEach(patch - { String[] split patch.split( ); String asPath javadoc.getClasspath().filter(jar - jar.getName().endsWith(split[ 1 ])).getAsPath(); if (asPath ! null asPath.length() 0 ) { options.addStringOption( -patch-module , split[ 0 ] asPath); } } ); 引入PatchModuleResolver 代码如下所示 // 1. PatchModuleExtension public PatchModuleResolver resolve(FileCollection classpath) { return resolve(jarName - classpath.filter(jar - jar.getName().endsWith(jarName)).getAsPath()); } public PatchModuleResolver resolve(UnaryOperatorString jarNameResolver) { return new PatchModuleResolver( this , jarNameResolver); } // 2. TestTask patchModuleExtension.resolve(testJava.getClasspath()).toArgumentStream().forEach(jvmArgs::add); // 3. RunTaskMutator patchModuleExtension.resolve(jarName - PATCH_LIBS_PLACEHOLDER / jarName).toArgumentStream().forEach(jvmArgs::add); // 4. JavadocTask patchModuleExtension.resolve(javadoc.getClasspath()).toValueStream() .forEach(value - options.addStringOption( -patch-module , value)); 多亏了重构现在只有一个地方 PatchModuleResolver 我们在其中分割了PatchModuleExtension类的config条目。 供参考DIFFS 1 2 3 4 。 摘要 在这篇文章中我介绍了以下五个重构原则 用“什么”隐藏“如何” 力求一致性 避免深层嵌套 单独关注 明智地避免重复 每个原则都附有一个真实的示例希望该示例显示了遵循该原则如何产生简洁的代码。 翻译自: https://www.javacodegeeks.com/2019/05/5-refactoring-principles-example.html
http://www.zqtcl.cn/news/949733/

相关文章:

  • 广州企业网站推广织梦学校网站模板
  • 国内响应式网站案例深圳住房和城乡建设局网站
  • 网页制作网站首页中国建筑论坛网
  • 众创空间网站建设少年宫网站建设模块
  • 企业营销型网站的内容科技公司取名大全
  • 哈尔滨云建站模板投资公司的钱从哪里来
  • 海南做网站公司哪家好中国人做外贸生意的网站
  • 没有网站怎么做cpa成都百度推广公司地址
  • 龙湖地产 网站建设高端上海网站设计公司
  • 触屏手机网站模板装修设计软件排名
  • 怎么做盗文网站郑州建设教育培训中心
  • 网站安全解决方案嵌入式软件工程师培训
  • 怎么做一种网站为别人宣传网站界面切片做程序
  • 麻涌网站建设河北网站建设联系方式
  • 建设银行官方网站打不开啊寮步仿做网站
  • 一个人可做几次网站备案峰峰网站建设
  • 怎么盗号网站怎么做北京高端网站设计外包公司
  • 著名的淘宝客网站wordpress博客内容预览
  • 成都网站seo公司甘肃网站建设推广
  • 做网站加班网站项目意义
  • 在虚拟机中如何做二级域名网站个人网站做哪种能赚钱
  • 贵州建设水利厅考试网站wordpress主查询翻页
  • 网站优化网络推广seo天津建设工程信息网几点更新
  • 兰州网站seo技术厂家比较实用的h5网页建设网站
  • 怎样让自己做的网站被百度收录动漫制作软件
  • 西安网站制作哪家公司好怎么向企业推销网站建设
  • 电子商务网站建设新闻深圳坂田网站设计公司有哪些
  • 上海电子商城网站制作wordpress循环该分类子分类
  • 茶山做网站教育网站建设计划书
  • 成品门户网站源码免费海外网络加速器免费