网站首页 网站导航 课程中心
新闻中心
您所在的位置:Java培训 > 新闻中心 > JAVA的最佳实践(一)

JAVA的最佳实践(一)

来源:中软卓越 日期:2017-05-19 14:20 人气:
标签: Java培训  Java学习  Java开发 
中软国际教育集团Python+大数据课程入驻大武汉啦!!!

JAVA的最佳实践(一)

Java是在世界各地最流行的编程语言之一, 但是看起来没人喜欢使用它。而Java事实上还算是一门不错的语言,随着Java 8最近的问世,我决定编制一个库,实践和工具的清单,汇集Java开发的一些最佳实践。

本文被放到了Github上。你可以随意地提交贡献,并加入自己的有关Java方面的建议和最佳实践。

风格

Javadoc

构建器模式

结构

依赖注入

避免空值

默认不可变更

避免大量的工具类

格式化

发布

依赖收敛

框架

Maven

持续集成

Maven资源库

配置管理

jUnit 4

jMock

AssertJ

Apache Commons

Guava

Gson

Java Tuples

Joda-Time

Lombok

Play framework

SLF4J

jOOQ

Missing Features

Testing

工具

Chronon

IntelliJ IDEA

JRebel

Checker 框架

Eclipse 内存分析器

资源

书籍

播客

风格

通常,我们会以一种非常详细繁杂的企业级JavaBean的风格进行Java代码的编写。新的风格则更加清晰,正确,且看上去也更加的简单。

结构

作为程序员的我们要做的最简单的事情之一,就是传递数据。一般的方式就是定义一个 JavaBean:

publicclassDataHolder{ private String data; publicDataHolder(){ } publicvoidsetData(String data){ this.data = data; } public String getData(){ returnthis.data; }}

这有点麻烦,并且也有点浪费。尽管你的 IDE 也能自动的生成这样的代码,但那也是种浪费。所以,别这么做。

相反,我更愿意选择编写类 C 的结构体风格的类,类里面只容纳数据:

publicclassDataHolder{ publicfinal String data; publicDataHolder(String data){ this.data = data; }}

这样就在代码行数上减少了一半。此外,这个类是不能被修改的,除非你对它进行了扩展,因此我们可以更加容易的理解它,因为我们明白它不可以被修改。

如果你要保存像 Map 或者 List 这样容易被修改的对象,就应该使用 ImmutableMap 和 ImmutableList,这一点会在不可变性质的那一节被讲到。

Builder模式

如果你有一个相当复杂的对象想要去为其构建一个结构,可以考虑使用 Builder 模式。

你可以在对象中创建一个能帮助你构建出这个对象的子类。它使用了可变语句,但是一旦你调用了build,它就会提供给你一个不可变的对象。

想象一下我们要有一个更加复杂的 DataHolder。针对它的构建器看起来可能像是下面这样:

publicclassComplicatedDataHolder{ publicfinal String data; publicfinalint num; // lots more fields and a constructorpublicstaticclassBuilder{ private String data; privateint num; public Builder data(String data){ this.data = data; returnthis; } public Builder num(int num){ this.num = num; returnthis; } public ComplicatedDataHolder build(){ returnnew ComplicatedDataHolder(data, num); // etc } }}

然后这样去使用它:

final ComplicatedDataHolder cdh = new ComplicatedDataHolder.Builder() .data("set this") .num(523) .build();

还有其它关于构建器的更好的例子 ,而这里提供给你浅尝辄止。这样做最终会得到许多的我们努力去避免的样板式代码,不过这也让你得到了不可变的对象和一个非常流畅的接口。

依赖注入

这是更偏向软件工程而不是 Java 的一节。编写可测试软件的最佳方式之一就是使用依赖注入(DI)。因为 Java 非常鼓励 OO 设计,为了创造出可测试的软件,你需要使用DI。

在 Java 中,一般使用 Spring 框架 的 DI 实现。它同时支持基于代码的装配和基于 XML 配置的装配。 如果你使用的是 XML 配置,因为其基于 XML 的配置, 不去过分使用 Spring 这一点很重要。XML 中绝对不能有任何逻辑或者控制结构,只能用来注入依赖。

使用 Spring 的好的选择就是 Google 和 Square 的 Dagger 库以及Google 的 Guice。他们不使用 Spring 的 XML 配置文件格式,而是将依赖逻辑放到注解和代码中。

避免空值

尽你所能避免空值。如果你可以返回一个空的集合,就不要返回一个空值。如果你要使用空值,就考虑使用 @Nullable 注解。IntelliJ IDEA 内置有对于 @Nullable 注解的支持。

如果你使用的是 Java 8,就可以利用其优秀的新的 Optional 类型。如果一个可能存在也可能不存在,那就像下面这样把它封装到一个 Optional 类中:

publicclassFooWidget{ privatefinal String data; privatefinal Optional<Bar> bar; publicFooWidget(String data){ this(data, Optional.empty()); } publicFooWidget(String data, Optional<Bar> bar){ this.data = data; this.bar = bar; } public Optional<Bar> getBar(){ return bar; }}

这样现在就能很确定数据永远都不会是空值了, 不过 bar 可能存在也可能不存在。Optional 有一些诸如 isPresent 这样的方法,这使得其感觉跟只检查空值的做法小同大异。但是它能让你写出像下面这样的语句:

final Optional<FooWidget> fooWidget = maybeGetFooWidget();final Baz baz = fooWidget.flatMap(FooWidget::getBar) .flatMap(BarWidget::getBaz) .orElse(defaultBaz);

这样就比链条时的 if 空值检查看起来好多了。使用 Optional 的唯一缺陷就是标准库并没有对 Optional 有很好的支持,因此针对空值的处理还是需要的。

默认不可被改变

除非你有一个好的理由要这样做,那么变量、类和集合都是不应该被修改的。

变量的引用可以用 final 来变成不可被修改的:

finalFooWidget fooWidget;if (condition()) { fooWidget = getWidget();} else { try { fooWidget = cachedFooWidget.get(); } catch (CachingException e) { log.error("Couldn't get cached value", e); throw e; }}// fooWidget is guaranteed to be set here

现在你就可以确信 fooWidget 不会突然被重新赋值了。final 关键字一般同 if/else 块和 try/catch 块一起使用。当然,如果 fooWidget 不是不可被修改的,那你就可以很轻易了修改它了。

集合就应该无论何时都尽量使用 Guava 的 ImmutableMap,ImmutableList,或者 ImmutableSet 类。这些都拥有构建器,因此你可以动态地构建它们,并通过调用 build 方法来将它们标记为不可变。

类应该(通过 final)声明其属性域不可变和使用不可变的集合而变成不可变的。你也可以选择使得类自身为 final,那样它就不能被扩展和被改变了。

避免许多的工具类

在你发现自己添加了太多的方法到一个工具类中时要小心。

publicclassMiscUtil{ publicstatic String frobnicateString(String base, int times){ // ... etc } publicstaticvoidthrowIfCondition(boolean condition, String msg){ // ... etc }}

这些类一开始看起来很吸引人,因为它们里面包含的方法并不真的属于任何一块。所以你就以代码重用的名义将它们扔到了一块儿。

治病比生病更糟糕。将这些类放到原本属于它们的地方,要不如果你必须要有像这么一些方法的话,就考虑使用 Java 8 的接口上的默认方法。然后你就可以将公共方法统统扔到接口中去。而因为他们是接口,你就可以多次实现它们。

publicinterfaceThrower{ defaultvoidthrowIfCondition(boolean condition, String msg){ // ... } defaultvoidthrowAorB(Throwable a, Throwable b, boolean throwA){ // ... }}

然后每个有需要的类都可以简单的实现这个接口。

格式化

格式化比起大多数程序员所认为的更加不被重视。那么它是不是同你对于自己技术水平的在意目标一致,还有是不是能有助于其他人的对于代码的解读呢?当然是。但我们也不要浪费一整天加空格来使得 if 的括号能“匹配”。

如果你绝对需要一个代码格式手册,我强烈推荐 Google 的 Java 代码风格指南。该指南的最佳部分就是编程实践这一节。绝对值得一读.

Javadoc

为你的用户所要面对的代码加注文档是很重要的。而这就意味着要使用示例和对于变量、方法和类的极值描述。

这样做的必然结果就是对于不需要加注文档的就不要去加注文档. 如果就一个参数代表的是什么你不想多费口舌,因为答案很明显,就不要为其加注文档。样板一样的文档比没有文档更糟糕,因为这对于会思考此处为何要加注的文档的用户而言这会是一种戏弄。

Java 8 有了一个不错的流和 lambda 语法。你可以像下面这样编写代码:

finalList<String> filtered = list.stream() .filter(s -> s.startsWith("s")) .map(s -> s.toUpperCase());

而不是再像以前这样写:

finalList<String> filtered = Lists.newArrayList();for (String str : list) { if (str.startsWith("s") { filtered.add(str.toUpperCase()); }}

这就让你能写出更加流畅的代码,更具可读性。

发布

发布 Java 通常有点棘手。如今有两种主要的 Java 发布方式 : 使用一套框架,或者根据灵活性的本地增量方案。

框架

因为发布 Java 并不容易,现有的框架可能会有所帮助。最好的两个就是 Dropwizard 和 Spring Boot。Play 框架 也可以被考虑也作为这些部署框架的其中之一。

它们全都试图降低让你的代码发布出去的门槛. 它们在你是名Java新手或者希望能快速运行起来时特别有帮助. 单个的JAR部署比复杂的WAR和EAR部署更简单.

不过,它们可能不怎么灵活,而且详单笨拙,因此如果你的项目不适合框架开发者为你的框架所做出选择,你就得自己集成一个更加手动的配置了。

中软卓越Java培训,优质的课程,优质的师资,优质的就业,把你打造成高逼格设计人才,进入高薪群体,轻松踏上成功之路。

 

中软卓越是中软国际有限公司投资的大型人才服务机构,是中软国际人才战略的核心组成部分之一,承担集团发展过程中人才储备和培养的任务,是软件及外包业务快速发展的重要人才支撑平台,是集团保持高速增长动力之一。

中软国际教育集团专注IT教育36年,一直秉承“用良心做教育”的理念,是中国移动互联网研发人才一体化服务的开拓者,全力打造移动互联网研发人才服务优质平台。

公司总部位于武汉,目前已在深圳、上海、郑州、广州、大连、武汉、成都、西安、杭州、重庆、长沙、合肥、无锡、南宁、厦门、南京、南昌等全国22个省成立了60多家分公司。拥有全国的移动互联网教学就业保障团队,做到了毕业学员业内高薪水,成为学员信赖的IT培训机构。

营业执照 版权所有©Copyright 2008-2017,武汉中软卓越科技有限公司 , All Rights Reserved. ICP备案号:15018648号-1

sitemap | 来校路线 | 分类导航 | 关于我们