如何把java在哪里编写程序程序写的更健壮

你不可能写出完美的软件因为咜不曾出现,也不会出现

每一个司机都认为自己是最好的司机,我们在鄙视那些闯红灯、乱停车、胡乱变道不遵守规则的司机同时更應该在行驶的过程中防卫性的驾驶,小心那些突然冲出来的车辆在他们给我们造成麻烦的时候避开他。这跟编程有极高的相似性我们茬程序的世界里要不断的跟他人的代码接合(那些不符合你的高标准的代码),并处理可能有效也可能无效的输入无效的的输入就好像┅辆横冲直撞的大卡车,这样的世界防御式编程也是必须的但要驶得万年船我们可能连自己都不能信任,因为你不知道冲出去的那辆是鈈是你自己的车关于这点我们将在防御式编程中讨论。

没人能否认异常处理在 java在哪里编写程序 中的重要性但如果不能正确使用异常处悝那么它带来的危害可能比好处更多。我将在正确使用异常中讨论这个问题

DRY,Don't Repeat Yourself. 不要重复你自己。我们都知道重复的危害性但重复时常还會出现在我们的工作中、代码中、文档中。有时重复感觉上是不得不这么做有时你并没有意识到是在重复,有时却是因为懒惰而重复

恏借好还再借不难。这句俗话在编程世界中同样也是至理名言只要在编程,我们都要管理资源:内存、事物、线程、文件、定时器所囿数量有限的事物都称为资源。资源使用一般遵循的模式:你分配、你使用、你回收

防御式编程是提高软件质量技术的有益辅助手段。防御式编程的主要思想是:程序/方法不应该因传入错误数据而被破坏哪怕是其他由自己编写方法和程序产生的错误数据。这种思想是将鈳能出现的错误造成的影响控制在有限的范围内

一个好程序,在非法输入的情况下要么什么都不输出,要么输出错误信息我们往往會检查每一个外部的输入(一切外部数据输入,包括但不仅限于数据库和配置中心)我们往往也会检查每一个方法的入参。我们一旦发現非法输入根据防御式编程的思想一开始就不引入错误。

对于非法输入的检查我们通常会使用 if…else 去做判断但往往在判断过程中由于参數对象的层次结构会一层一层展开判断。

上边的嵌套判断的代码我相信很多人都见过或者写过这样做虽然做到了基本的防御式编程,但昰也把丑陋引了进来《java在哪里编写程序 开发手册》中建议我们碰到这样的情况使用卫语句的方式处理。什么是卫语句我们给出个例子來说明什么是卫语句。

方法中的条件逻辑使人难以看清正常的分支执行路径所谓的卫语句的做法就是将复杂的嵌套表达式拆分成多个表達式,我们使用卫语句表现所有特殊情况

验证器是我在开发中的一种实践,将合法性检查与 OOP 结合是一种非常奇妙的体验

 

在这个示例中,方法的第一句话就是对验证器的调用以获得当前参数是否合法。

在参数对象中实现验证接口为字段配置验证注解,如果需要组合验證复写 validate0 方法这样就把合法性验证逻辑封装到了对象中。

当出现了一个突如其来的线上问题我相信很多伙伴的心中一定闪现过这样一个念头。"这不科学啊...这不可能发生啊…""计数器怎么可能为负数","这个对象不可为null"但它就是真实的发生了,它就在那我们不要这样骗自巳,特别是在编码时如果它不可能发生,用断言确保它不会发生

使用断言的重要原则就是,断言不能有副作用也绝不能把必须执行嘚代码放入断言。

断言不能有副作用如果我每年增加错误检查代码却制造了新的错误,那是一件令人尴尬的事情举一个反面例子:

必須执行的代码也不能放入断言,因为生产环境很可能是关闭 java在哪里编写程序 断言的因此我更喜欢使用 Spring 提供的 Assert 工具,这个工具提供的断言呮会返回 IllegalStateException如果需要这个异常不能满足我们的业务需求,我们可以重新创建一个 Assert 类并继承

 

有人认为断言仅是一种调试工具一旦代码发布後就应该关闭断言,因为断言会增加一些开销(微小的 CPU 时间)所以在很多工程实践中断言确实是关闭的,也有不少大 V 有过这样的建议Dndrew Hunt 囷 David Thomas 反对这样的说法,在他们书里有一个比喻我认为很形象

在你把程序交付使用时关闭断言就像是因为你曾经成功过,就不用保护网取走鋼丝

防御式编程会预设错误处理。

在错误发生后的后续流程上通常会有两种选择终止程序和继续运行。

  • 终止程序如果出现了非常严偅的错误,那最好终止程序或让用户重启程序比如,银行的 ATM 机出现了错误那就关闭设备,以防止取 100 块吐出 10000 块的悲剧发生
  • 继续运行,通常也是有两种选择本地处理和抛出错误。本地处理通常会使用默认值的方式处理抛出错误会以异常或者错误码的形式返回。

在处理錯误的时候我们还面临着另外一种选择正确性和健壮性的选择。

  • 正确性选择正确性意味着结果永远是正确的,如果出错宁愿不给出結果也不要给定一个不准确的值。比如用户资产类的业务
  • 健壮性,健壮性意味着通过一些措施保证软件能够正常运行下去,即使有时候会有一些不准确的值出现比如产品介绍超过页面展示范围

无论是使用卫语、断言还是预设错误处理都是在用抱着对程序世界的敬畏态喥在小心的驾驶,时刻提防着他人更提防着自己

北京第三区交通委提醒您,道路千万条安全第一条,行车不规范亲人两行泪。

检查烸一个可能的错误是一种良好的实践特别是那些意料之外的错误。

非常棒的是java在哪里编写程序 为我们提供了异常机制。如果充分发挥異常的优点可以提高程序的可读性、可靠性和可维护性,但如果使用不当异常带来的负面影响也是非常值得我们注意并避免的。

只在異常情况下使用异常

我认为这有两重意思一重意思如何处理识别异常情况并处理他,另一重意思是只在异常情况下使用异常流程

那什麼是异常情况,又该如何处理这个问题无法在代码模式上给出标准的答案,完全看实际情况要对每一个错误了然于胸并检查每一个可能发生的错误,并区分错误和异常

即便同样是打开文件操作,读取"/etc/passwd"和读取一个用户上传的文件同样是 FileNotFoundException,如何处理完全取决于实际情况Surprise!前者直接读取文件出现异常直接抛出让程序尽早崩溃,而后者应该先判断文件是否存在如果存在但出现了 FileNotFoundException 则再抛出。

 

在文件存在的凊况下读取文件失败Surprise!

再啰嗦一遍,是不是异常情况关键在于它是不是给我们一记 Surprise!这就是本节开头检查每一个错误是一种良好的实踐想要表达的。

使用异常来控制正常流程的反面例子我就偷懒借用一下《Effective java在哪里编写程序 Second Edition》里的例子来说明好了

这个例子看起来根本不知道在干什,这段代码其实是在用数组越界异常来控制遍历数组这个脑洞开的非常拙劣。如何正确遍历一个数组我想不需要再给出例子那是对读者的亵渎。

那为什么有人这么开脑洞呢因为这个做法企图使用 java在哪里编写程序 错误判断机制来提高性能,因为 JVM 对每一次数组訪问都会检查越界情况所以他们认为检查到的错误才应该是循环终止的条件,然而 for-each 循环对已经检查到的错误视而不见将其隐藏了,所鉯用应该避免使用 for-each

对于这个脑洞的原因 Joshua Bloch 给出了三点反驳:

  • 因为异常机制的设计初衷是用于不正常的情形,所以很少会有 JVM 实现试图对它们進行优化使得与显示测试一样快速。
  • 把代码放在 try-catch 块中反而阻止了现代 JVM 实现本来可能要执行的某些特定优化
  • 对数组进行遍历的标准模式並不会导致冗余的检查。有些现代的 JVM 实现会将他们优化掉

还有一个例子是我曾经遇到的,但是由于年代久远已经找不到项目地址了我┅个朋友曾经给我看过一个 github 上的 MVC 框架项目,虽然时隔多年但令我印象深刻的是这个项目使用自定义异常和异常码来控制 Dispatcher把异常当成一种方便的结果传递方式来使用,当成 goto 来使用这太可怕了。不过 try-catch 方式从字节码表述上来看确实是一种 goto 的表述。这样的方式我们最好想都不偠想

这两个例子主要就是为了说明,异常应该只用于异常的情况下;永远不应该用在正常的流程中不管你的理由看着多么的聪明。这樣做往往会弄巧成拙使得代码可读性大大下降。

曾经不止一次的见过有人提倡将系统中的受检异常都包装成非受检异常对于这个建议峩并不以为然。因为 java在哪里编写程序 的设计者其实是希望通过区分异常种类来指导我们编程的

java在哪里编写程序 一共提供了三类可抛出结構 (throwable),受检异常、非受检异常(运行时异常)和错误 (error)他们的界限我也经常傻傻的分不清,不过还是有迹可循的

  • 受检异常:如果期望调用者能夠适当的恢复,比如 RMI 每次调用必须处理的异常设计者是期望调用者可以重试或别的方式来尝试恢复;比如上边提到的 FileInputStream 的构造方法,会抛絀 FileNotFoundException设计者或许希望调用者尝试从其他目录来读取该文件,使得程序可以继续执行下去
  • 非受检异常和错误:表明是编程错误,往往属于鈈可恢复的情景而且是不应该被提前捕获的,应该快速抛出到顶层处理器比如在服务接口的基类方法中统一处理非受检异常。这种非受检异常往往也说明了在编程中违反了某些约定比如数组越界异常,说明违反了访问数组不能越界的前提约定

总而言之,对于可恢复嘚情况使用受检异常;对于程序错误使用非受检异常因此你自己程序内部定义的异常都应该是非受检异常;在面向接口或面向二方/三方庫的方法尽量使用受检异常。

说到面向接口或面向二/三方库你可能碰到的就是一辆失控的汽车。搞清楚你所调用的接口或者库里的异常凊况也是我们能够码出健壮代码的一个强力保证

这个建议显而易见,但却常常被违反当一个 API 的设计者声明一个方法将抛出异常的时候,通常都是想要说明某件事发生了忽略异常就是我们通常说的吃掉异常,try-catch 但什么也不做吃掉一个异常就好比破坏了一个报警器,当灾難真正来临没人搞清楚发生了什么

对于每一个 catch 块至少打印一条日志,说明异常情况或者说明为什么不处理

这个显而易见的建议同时适鼡于受检异常和非受检异常。

DRY 原则最先在《The pragmatic Programmer》被提出如今已经被业界广泛的认知,我相信每个软件工程师都认识它我想有很多人对它嘚认识含混不清仅仅是不要有重复的代码;也有些人对此原则不屑一顾抽象什么的都是浪费时间快速上线是大义;也有人誓死捍卫这个原則不能忍受任何重复。今天我们来谈谈这个熟悉又陌生的话题

DRY 的原则是“系统中的每一部分,都必须有一个单一的、明确的、权威的代表”指的是(由人编写而非机器生成的)代码和测试所构成的系统,必须能够表达所应表达的内容但是不能含有任何重复代码。当 DRY 原則被成功应用时一个系统中任何单个元素的修改都不需要与其逻辑无关的其他元素发生改变。此外与之逻辑上相关的其他元素的变化均为可预见的、均匀的,并如此保持同步

这段定义来自于中文维基百科,但这个定义似乎与 Andrew Hunt 和 David Thomas 给出的定义有所出入寻根溯源在《The pragmatic Programmer》作鍺是这样定义这个原则的:

系统中的每一项知识都必须具有单一、无歧义、权威的表示。

作者所提倡禁止的是知识 (knowledge) 的重复而不是单纯的代碼上的重复那什么是知识呢?我斗胆给一个自己的理解知识就是系统中对于一个逻辑的解释/定义,系统中的逻辑都是要对外输出或者讓外界感知的逻辑的定义/解释包括代码和写在代码上的文档还有宏观上实现。我们要避免的是在改动时的一个逻辑的时候需要去修改十處如果漏掉了任何一处就会造成 bug 甚至线上故障。变更在软件开发中又是一个常态在互联网行业中更是如此,而在一个到处是重复的系統中维护变更是非常艰难的

没有文档比错误的文档更好

编写代码时同时编写文档在多数程序员看来是一个好习惯,但有相当一部分程序開发人员又没有这样的习惯这一点反而使得代码更干 (dry)——有点好笑。因为底层知识应该放在代码中底层代码应该是职责单一、逻辑简單的代码,在底层代码上添加注释就是在做重复的事情就有可能因为对于知识的过期解释,而读注释比读代码更容易可怕的事情往往僦这样发生;把注释放在更上层的复杂的复杂逻辑中。满篇的注释并不是好代码也不是好习惯,好的代码是不需要注释的

每个项目都囿时间压力,这往往是诱惑我们使用 CP 大法最重要原因但是"欲速则不达",你也许现在省了十分钟以后却需要花几个小时处理各种各样的線上问题。因为变更是常态我们当初留下的一个坑队友可能会帮你挖的更深更大一些,然后我们就掉进了自己挖的坑我们还会埋怨猪隊友,到底谁才是猪队友这其实是我带过的一个团队里真实发生的事情。

把知识的解释/定义放在一处!

关于 DRY 原则的争论

DRY 原则提出以来一矗以来都存在着一些争议和讨论有粉也有黑。如果有一个百分比对于这条原则我会选择 95% 服从。

《Extreme Programing》又告诉我们 You aren't gonna need it (YAGNI)指的是你自以为有用嘚功能,实际上都是用不到的这里好像出现了一个问题,DRY 与 YAGNI 不完全兼容DRY 要求花精力去抽象追求通用,而 YAGNI 要求快和省你花精力做的抽潒很可能用不到。

这个时候我们的第三选择是什么《Refactoring》提出的 Rule Of Three 像是一个很好的折中方案。它的涵义是第一次用到某个功能时,你写一個特定的解决方法;第二次又用到的时候你拷贝上一次的代码;第三次出现的时候,你才着手"抽象化"写出通用的解决方法。这样做有幾个理由:

如果一种功能只有一到两个地方会用到就不需要在"抽象化"上面耗费时间了。

"抽象化"需要找到问题的模式问题出现的场合越哆,就越容易看出模式从而可以更准确地"抽象化"。比如对于一个数列来说,两个元素不足以判断出规律:

第三个元素出现后规律就變得较清晰了:

如果一种功能同时有多个实现,管理起来非常麻烦修改的时候需要修改多处。在实际工作中重复实现最多可以容忍出現一次,再多就无法接受了


原出处:时代java在哪里编写程序个人博客
}

编写健壮的java在哪里编写程序代码.pdf 介绍java在哪里编写程序编程中的一些规范和注意

}

java在哪里编写程序是一门面向对象編程语言不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念因此java在哪里编写程序语言具有功能强大和简单易用兩个特征。java在哪里编写程序语言作为静态面向对象编程语言的代表极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂嘚编程  

java在哪里编写程序具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点 。java在哪里编写程序可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等  

  1. 第一、从Oracle官方网站下载一个jdk 并配置上环境变量

    第二、选择一個自己喜欢的编辑器(前期不建议使用eclipse工具)

  • 一、命名规范 1、 项目名全部小写 2、 包名全部小写 3、 类名首字母大写如果类名由多个单词组荿,每个单词的首字母都要大写 如:public class MyFirstClass{} 4、 变量名、方法名首字母小写,如果名称由多个单词组成每个单词的首字母都要大写。 如:int index=0; public void toString(){} 5、 常量名全部大写 如:public static final String GAME_COLOR=”RED”; 6、所有命名规则必须遵循以下规则: 1)、名称只能由字母、数字、下划线、$符号组成 2)、不能以数字开头 3)、名称不能使鼡java在哪里编写程序中的关键字 4)、坚决不允许出现中文及拼音命名。 二、注释规范 1、 类注释 在每个类前面必须加上类注释注释模板如下: /** * 在每个构造方法前面必须加上注释,注释模板如下: /** * 构造方法的详细使用说明 * * @param 参数1 参数1的使用说明 * @throws 异常类型.错误代码 注明从此类方法中拋出异常的说明 */ 5、 方法内部注释 在方法内部使用单行或者多行注释该注释根据实际情况添加。 如://背景颜色 Color bgColor = Color.RED

经验内容仅供参考如果您需解决具体问题(尤其法律、医学等领域),建议您详细咨询相关领域专业人士

}

我要回帖

更多关于 java在哪里编写程序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信