Software_programming_GoodFormat

2019-09-30

Effective Java

1 创建和销毁对象
1.用静态工厂方法代替构造器
2.遇到多个构造参数时使用构造器重构
3.用私有构造器或枚举类型强化SingleTon属性
4.通过私有构造器强化不可实例化的能力
5.优先考虑依赖注入来引用资源
6.避免创建不必要的对象
7.消除过期的对象引用
8.避免使用终结方法和清除方法
9.try-with-resouce 由优于 try-finally

2.所有对象都通用的方法
1.始终要覆盖toString
2.考虑实现Comparable接口
3.覆盖equals时总要覆盖hashCode
4.谨慎地覆盖clone
5.覆盖equals时请遵守通用约定

3.类和接口
1.使类和成员的可访问性最小化
2.要在公有类而非公有域中使用访问方法
3.使可变性最小化
4.复合优先于继承
5.要么设计继承并提供文档说明,要么禁止继承。
6.接口优于抽象类
7.为后代设计接口
8.接口只用于定义类型
9.类层次优于标签类
10.静态成员类优于非静态成员类
11.限制源文件为单个顶级类

4.泛型
1.不要使用原生态类型
2.消除非受检的警告
3.列表优于数组
4.优先考虑泛型
5.优先考虑泛型方法
6.利用有限制通配符来提升API的灵活性
7.谨慎并用泛型和可变参数
8.优先考虑类型安全的异构容器

5.枚举和注解
1.用 enum 代替 int 常量
2.用实例域代替序数
3.用EnumSet代替位域
4.用EnumMap代替序数索引
5.用接口模拟可扩展的枚举
6.注解优于命名模式
7.坚持使用Override注解
8.用标记接口定义类型

6.Lambda 和 Stream
1.Lambda 优先于匿名类
2.方法引用优先于 Lambda
3.坚持使用标准的函数接口
4.谨慎使用Stream
5.优先使用Stream中无副作用的函数
6.Stream要优先用Collection作为返回类型
7.谨慎使用Stream并行

7.方法
1.检查参数的有效性
2.必要时进行保护性拷贝
3.谨慎设计方法签名
4.慎用重载
5.慎用可变参数
6.返回零长度的数组或者集合,而不是null
7.谨慎返回option_bar_1al
8.为所有导出的API元素编写文档注释

8.通用编程
1.将局部变量的作用域最小化
2.for-each循环优于传统的for循环
3.了解和使用类库
4.如果需要精确的答案,避免使用float和double.
5.基本类型优先于装箱基本类型
6.如果其他类型更适合,则尽量避免使用字符串。
7.了解字符串连接的性能
8.通过接口引用对象
9.接口优先于反射机制
10.谨慎地使用本地方法
11.谨慎地进行优化
12.遵守普遍接受的命名方法。

9. 异常
1.只针对异常的情况使用异常
2.针对可恢复的情况使用受检异常,对编程错误使用运行时异常
3.避免不必要使用受检异常
4.优先使用标准的异常
5.抛出与抽象对应的异常
6.每个方法抛出的所有异常都要建立文档
7.在细节消息中包含失败-捕获信息
8.努力使失败保持原子性
9.不要忽略异常

10 并发
1.同步访问共享的可变数据
2.避免过度同步
3.executor, task 和 stream 优先与线程
4.并发工具优先于wait和notify
5.线程安全的文档化
6.慎用延迟初始化
7.不要依赖于线程调度器

11 序列化
1.其他方法优先于java 序列化
2.谨慎地实现Serializable接口
3.考虑使用自定义的序列化形式
4.保护性地编写 readObject方法
5.对于实例控制,枚举类型优先于readResolve
6.考虑用序列化代理代替序列化实例

 


 

Pramatic unit testing

1. General Principies:
1) Test anything that might break.
2) Test everything that does break.
3) New code is guilty until proven innocent
4) Write at least as Test code as production code
5) Run local tests with each compile
6) Run all tests before check-in repository

2 Question to Ask
1) If the code run correctly, how would i know?
2) How am i going to test this
3) What else can go wrong ?
4) Could this same kind of problem happen anywhere else?

3 What to Test: Use your RIGHT-BICEP
1) Are the result RIGHT
2) Are all the boundary conditions CORRECT?
3) Can you check inverse relationships?
4) Can you cross-check results using other means
5) Can you force error-condition to happen?
6) Are performance characteristics within bounds?

4 Good Tests are A TRIP
1) Automatic
2) Through
3) Repeatable
4) Independent
5) Professional

5 CORRECT boundary conditions

1) Confromance - Does the value conform to an expected format?
2) Ordering - Is the set of values ordered or unordered as appropriate?
3) Ranges - Is the value reasonable minimum and maximum values?
4) Reference - Does the code reference external that
isn`t under direct control of the code itself?
5) Exitence - Does the value exist?
(e.g.,is non-null? non-zero? present in a set, etc.)
6) Cordinality - Are there exactly enought values?
7) Time(absolute and relative) - Is everything happening in order?
At the right order? At time?


 

Refactroing - bad smell

1 Duplicate code

2 Long parameter list
3 Long Method
4 data clumps
5 primitive obsession
6 switch statements
7 temporary field

8 Long class
9 Divergent change 违反单一职责, 引起一个类变化的原因有多种
10 Shotgun surgery 一个变化引起多个类相应地修改
11 Feature ency 迁移至所该去的地方
12 Lazy class
13 Speculative generality
14 Message chains
15 Middle man
16 Inappropriate intimacy
17 Alternative classes with different interfaces
18 Incomplete library class
19 Data class 赋予职责
20 Refused bequest 所有的超类都应该是抽象的

21 Comments


 

standard function interface

不建议: Template Method 中,用一个子类覆盖基本类型方法(primitive method),
来限定其超类的行为。

替代方法使提供一个接受函数对象的静态工厂或者构造器,便可达到同样的效果。

java.util.function 大量标准的函数接口

基础接口作用于对象引用类型。

Operator 接口代表其结果与参数类型一致的函数
Predicate 接口代表带有一个参数并返回boolean的函数
Function接口代表其参数与返回的类型不一致的函数
Supplier 接口代表没有参数并且返回或提供一个值的函数。
Consumer代表的是带有一个函数但不反悔任何值的函数

6个基础接口各自还有3种变体,分别可用于基本类型 int, long 和 double
命名方式是在其基础接口名称前面加上基础类型而得。

Function 接口还有9种变体,用于结果类型为基本类型的情况

接口 函数签名 demo
UnaryOperator<T> T apply(T t) String::toLowerCase
BinaryOperator<T> T apply(T t1, T t2) BigInteger::add
Predicate<T> boolean test(T t) Collection::isEmpty
Function<T> R apply(T t) Arrays::asList
Supplier<T> T get() Instance::now
Consumer<T> void accepte(T t) System.out::println

==================================================================

Stream
filter : Predicate<T> 函数签名 T -> boolean
map : Function<T,R> 函数签名 T -> R
limit : 截断流 获取前几个
sorted : Comparator<T> 函数签名 (T,T) -> int
distinct : 去重

sorted(Compator.comparing(T::getInt())

forEach : 消费流中的每个元素并对其应用 lambda 表达式
count : long
collect : 把流规约成一个集合 List, Map, Integer

--------------------------------------------------------------------
forEach(System.out::println)


====================================================================
option_bar_1al<T> 容器类, 代表一个值存在与否
1. isPresent(): option_bar_1al 存在值时返回true, 否则返回 false
2. ifPresent(Consumer<T> block) 会在值存在的时候执行给定的代码块,
(Consumer接口:传递一个T参数,消费这个 T 什么也不返回)
3. T get() : 值存在时返回值,否则抛出一个 NoSuchElement 异常
4. T orElse(T other) : 会在值存在时返回值, 否则返回一个默认值

 

posted @ 2019-09-30 08:33  君子之行  阅读(1)  评论(0编辑  收藏  举报