草庐IT

读Java实战(第二版)笔记12_重构、测试和调试

躺柒 2023-04-16 原文

1. 设计模式

1.1. 对设计经验的归纳总结

1.2. 一种可重用的蓝图

1.3. Java 5引入了for-each循环

1.3.1. 替代了很多显式使用迭代器的情形

1.4. Java 7推出的菱形操作符(<>)

1.4.1. 帮助大家在创建实例时无须显式使用泛型

1.4.2. 推动了Java程序员们采用类型接口(type interface)进行程序设计

1.5. 单例模式

1.5.1. 一般用于限制类的实例化,仅生成一份对象

1.6. 访问者模式

1.6.1. 常用于分离程序的算法和它的操作对象

2. 策略模式

2.1. 解决一类算法的通用解决方案,你可以在运行时选择使用哪种方案

2.2. 一个代表某个算法的接口(Strategy接口)

2.3. 一个或多个该接口的具体实现,它们代表了算法的多种实现

2.4. 一个或多个使用策略对象的客户

2.5. Lambda表达式避免了采用策略设计模式时僵化的模板代码

3. 模板方法模式

3.1. 如果需要采用某个算法的框架,同时又希望有一定的灵活度,能对它的某些部分进行改进

3.2. “希望使用这个算法,但是需要对其中的某些行进行改进,才能达到希望的效果”时是非常有用的

3.3. 通过传递Lambda表达式,直接插入不同的行为,不再需要继承

3.4. Lamba表达式能帮助解决设计模式与生俱来的设计僵化问题

4. 观察者模式

4.1. 消除僵化代码

4.1.1. 直接传递Lambda表达式表示需要执行的行为即可

4.2. 某些事件发生时(比如状态转变),如果一个对象(通常称之为主题)需要自动地通知其他多个对象(称为观察者)

5. 责任链模式

5.1. 通过定义一个代表处理对象的抽象类来实现的,在抽象类中会定义一个字段来记录后续对象

5.2. UnaryOperator的一个实例

5.2.1. 为了链接这些函数,需要使用andThen方法对其进行构造

6. 工厂模式

6.1. 无须向客户暴露实例化的逻辑就能完成对象的创建

6.2. 特殊的函数接口TriFunction


          public interface TriFunction<T, U, V, R>{
              R apply(T t, U u, V v);
          }
          Map<String, TriFunction<Integer, Integer, String, Product>> map
              = new HashMap<>();

7. 改善程序代码的可读性

7.1. 代码的可读性

7.1.1. 别人理解这段代码的难易程度

7.1.2. 确保你的代码能非常容易地被包括自己在内的所有人理解和维护

7.2. 重构代码,用Lambda表达式取代匿名类

7.3. 用方法引用重构Lambda表达式

7.4. 用Stream API重构命令式的数据处理

8. 从匿名类到Lambda表达式的转换

8.1. “更简洁”来描述Lambda表达式是因为相较于匿名类

8.2. 匿名类和Lambda表达式中的this和super的含义是不同的

8.2.1. 在匿名类中,this代表的是类自身

8.2.2. 在Lambda中,它代表的是包含类

8.3. 匿名类可以屏蔽包含类的变量

8.4. Lambda表达式不能(会导致编译错误)

8.5. 涉及重载的上下文里,将匿名类转换为Lambda表达式可能导致最终的代码更加晦涩

8.5.1. 匿名类的类型是在初始化时确定的

8.5.2. Lambda的类型取决于它的上下文

8.5.3. Task尝试使用显式的类型转换来解决这种模棱两可的情况

8.5.4. NetBeans、Eclipse和IntelliJ都支持这种重构,能自动地帮你检查,避免发生这些问题

9. 从Lambda表达式到方法引用的转换

9.1. Lambda表达式非常适用于需要传递代码片段的场景

9.2. 尽量将复杂的Lambda表达式抽象到普通方法中

9.3. 为了改善代码的可读性,请尽量使用方法引用

9.3.1. 利用这种方法能写出非常简洁的代码

9.4. 尽量考虑使用静态辅助方法

9.4.1. 比如comparing和maxBy

9.4.2. 这些方法设计之初就考虑了会结合方法引用一起使用

10. 从命令式的数据处理切换到Stream

10.1. Stream API能更清晰地表达数据处理管道的意图

10.2. 建议将所有使用迭代器这种数据处理模式处理集合的代码都转换成Stream API的方式

10.3. 通过短路和延迟载入以及计算机的多核架构,可以对Stream进行优化

10.3.1. LambdaFicator

11. 增加代码的灵活性

11.1. 采用函数接口

11.1.1. 没有函数接口,就无法使用Lambda表达式

11.2. 有条件的延迟执行

11.2.1. 控制语句被混杂在业务逻辑代码之中

11.2.2. 频繁地从客户端代码去查询一个对象的状态,只是为了传递参数、调用该对象的一个方法,那么可以考虑实现一个新的方法,以Lambda或者方法引用作为参数,新方法在检查完该对象的状态之后才调用原来的方法

11.2.3. 代码会因此而变得更易读(结构更清晰),封装性更好(对象的状态也不会暴露给客户端代码了)

11.3. 环绕执行

11.3.1. 拥有同样的准备和清理阶段

12. 测试Lambda表达式

12.1. 测试可见Lambda函数的行为

12.2. 测试使用Lambda的方法的行为

12.2.1. Lambda的初衷是将一部分逻辑封装起来给另一个方法使用

12.2.2. 不应该将Lambda表达式声明为public,它们仅是具体的实现细节

12.3. 将复杂的Lambda表达式分为不同的方法

12.3.1. 将Lambda表达式转换为方法引用

12.3.2. 需要声明一个新的常规方法

12.3.3. 用常规的方式对新的方法进行测试

12.4. 高阶函数的测试

12.4.1. 如果一个方法接受Lambda表达式作为参数,那么你可以采用的一个方案是使用不同的Lambda表达式对它进行测试

13. 调试

13.1. 查看栈跟踪

13.1.1. 由于Lambda表达式没有名字,因此它的栈跟踪可能很难分析

13.2. 使用日志调试

13.2.1. 流操作方法peek

13.2.2. peek的设计初衷就是在流的每个元素恢复运行之前,插入执行一个动作

有关读Java实战(第二版)笔记12_重构、测试和调试的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  3. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

  4. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  5. ruby - Sinatra:运行 rspec 测试时记录噪音 - 2

    Sinatra新手;我正在运行一些rspec测试,但在日志中收到了一堆不需要的噪音。如何消除日志中过多的噪音?我仔细检查了环境是否设置为:test,这意味着记录器级别应设置为WARN而不是DEBUG。spec_helper:require"./app"require"sinatra"require"rspec"require"rack/test"require"database_cleaner"require"factory_girl"set:environment,:testFactoryGirl.definition_file_paths=%w{./factories./test/

  6. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  7. ruby-on-rails - 迷你测试错误 : "NameError: uninitialized constant" - 2

    我遵循MichaelHartl的“RubyonRails教程:学习Web开发”,并创建了检查用户名和电子邮件长度有效性的测试(名称最多50个字符,电子邮件最多255个字符)。test/helpers/application_helper_test.rb的内容是:require'test_helper'classApplicationHelperTest在运行bundleexecraketest时,所有测试都通过了,但我看到以下消息在最后被标记为错误:ERROR["test_full_title_helper",ApplicationHelperTest,1.820016791]test

  8. ruby - 即使失败也继续进行多主机测试 - 2

    我已经构建了一些serverspec代码来在多个主机上运行一组测试。问题是当任何测试失败时,测试会在当前主机停止。即使测试失败,我也希望它继续在所有主机上运行。Rakefile:namespace:specdotask:all=>hosts.map{|h|'spec:'+h.split('.')[0]}hosts.eachdo|host|begindesc"Runserverspecto#{host}"RSpec::Core::RakeTask.new(host)do|t|ENV['TARGET_HOST']=hostt.pattern="spec/cfengine3/*_spec.r

  9. ruby-on-rails - 如何使辅助方法在 Rails 集成测试中可用? - 2

    我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel

  10. ruby-on-rails - 无法让 rspec、spork 和调试器正常运行 - 2

    GivenIamadumbprogrammerandIamusingrspecandIamusingsporkandIwanttodebug...mmm...let'ssaaay,aspecforPhone.那么,我应该把“require'ruby-debug'”行放在哪里,以便在phone_spec.rb的特定点停止处理?(我所要求的只是一个大而粗的箭头,即使是一个有挑战性的程序员也能看到:-3)我已经尝试了很多位置,除非我没有正确测试它们,否则会发生一些奇怪的事情:在spec_helper.rb中的以下位置:require'rubygems'require'spork'

随机推荐