Package: 1.1 Package: 每个包的名称老是小写,暂定将com.keegoo.+(模块名)做为总前缀,好比com.keegoo.demo.blog.service、com.keegoo.demo.blog.dto; 1.2 明确不一样业务建议创建子package,好比有关User业务的:com.keegoo.user.account.service、com.keegoo.user.account.dto;编程
Class类:类名必须是名词,且以大写字母开头。类名应该简单清晰。缓存
Interface类: 3.1 Interface命名上,暂定以XxxService的形式提供; 3.2 最终提供的接口应以Java Interface的形式出现; 3.3 每一个独立的业务的Interface应该有独立的package包,一个package下可包含该业务模块下的多个Interface; 3.4 每一个Interface的一个方法对应所谓的一个“中间层服务接口”,须要按照规范书写该接口的说明;工具
缓存命名规则:对缓存的key要采用命名空间,以免冲突,同时要考虑缓存的命中率,不要浪费缓存的空间。性能
业务模块的开发过程当中,应该避免过长的方法,进行合理的功能模块的提取以及抽象,避免同一段代码、相似代码处处copy的状况。单元测试
所谓单一职责原则,指的就是:一个类应该仅有一个引发它变化的缘由。测试
这里变化的缘由就是 所说的“职责”,若是一个类有多个引发它变化的缘由,那么也就意味着这个类有多个职责,再进一步说,就是把多个职责耦合在一块儿了
。这会形成职责的相互影响,可能一个职责的变化,会影响到其它职责的实现,甚至引发其它职责跟着变化,这种设计是很脆弱的。编码
这个原则看起来是最简单和最好理解的,可是其实是很难彻底作到的,难点在于如何区分这个“职责”
,这是个没有标准量化的东西,哪些算职责,到底这个职责有多大的粒度,这个职责如何细化等等。所以,在实际开发中,这个原则也是最容易违反的。设计
所谓开放-关闭原则,指的就是:一个类应该对扩展开放,对修改关闭。通常也被简称为开闭原则,开闭原则是设计中很是核心的一个原则。调试
开闭原则要求的是,类的行为是能够扩展的
,并且是在不修改已有的代码的状况下进行扩展,也没必要改动已有的源代码或者二进制代码。日志
看起来好像是矛盾的,怎么样才能实现呢?
实现开闭原则的关键就在于合理的抽象,分离出变化与不变化的部分,为变化的部分预留下可扩展的方式
,好比:钩子方法、或是动态组合对象等等。
这个原则看起来也很简单,但事实上,一个系统要所有作到遵照开闭原则,几乎是不可能的
,也没这个必要。适度的抽象能够提升系统的灵活性,使其可扩展、可维护,可是过分的抽象,会大大增长系统的复杂程度
。应该在须要改变的地方应用开闭原则就能够了,而不用处处使用,从而陷入过分设计。
所谓里氏替换原则,指的就是:子类型必须可以替换掉它们的父类型。这很明显是一种多态的使用状况,它能够避免在多态的应用中,出现某些隐蔽的错误。
事实上,当一个类继承了另一个类,那么子类就拥有了父类中能够继承下来的属性和操做,理论上来讲,此时使用子类型去替换掉父类型,应该不会引发原来使用父类型的程序出现错误。
可是,很不幸的是,在某些状况下是会出现问题的,好比:若是子类型覆盖了父类型的某些方法,或者是子类型修改了父类型某些属性的值,那么原来使用父类型的程序就可能会出现错误
,由于在运行期间,从表面上看,它调用的是父类型的方法,须要的是父类型方法实现的功能,可是实际运行调用的确是子类型覆盖实现的方法,而该方法跟父类型的方法并不同,那就会致使错误的产生
。
从另一个角度来讲,里氏替换原则是实现开闭的主要原则之一,开闭原则要求对扩展开放,扩展的一个实现手段就是使用继承,而里氏替换原则是保证子类型可以正确替换父类型,只有能正确替换,才能实现扩展,不然扩展了也会出现错误
。
所谓依赖倒置原则,指的就是:
要依赖于抽象,不要依赖于具体类
。要作到依赖倒置,典型的应该作到:
高层模块不该该依赖于底层模块
,两者都应该依赖于抽象;抽象不该该依赖于具体实现
,具体实现应该依赖于抽象;
不少人以为,层次化调用的时候,应该是高层调用“底层所拥有的接口”,这是一种典型的误解。事实上,通常高层模块包含对业务功能的处理和业务策略选择,应该被重用,应该是高层模块去影响底层的具体实现。
所以,这个底层的接口,应该是由高层提出的,而后由底层实现的,也就是说底层的接口的全部权在高层模块
,所以是一种全部权的倒置。
倒置接口全部权,这就是著名的Hollywood(好莱坞)原则:不要找咱们,咱们会联系你。
所谓接口隔离原则,指的就是:
不该该强迫客户依赖于他们不用的方法
。
这个原则用来处理那些比较“庞大”的接口,这种接口一般会有较多的操做声明,涉及到不少的职责。客户在使用这样的接口的时候,一般会有不少它不须要的方法,这些方法对于客户来说,就是一种接口污染,至关于强迫用户在一大堆“垃圾方法”里面去寻找他须要的方法。
所以,这样的接口应该被分离,应该按照不一样的客户须要来分离成为针对客户的接口,这样的接口里面,只包含客户须要的操做声明,这样既方便了客户的使用,也能够避免因误用接口而致使的错误。
分离接口的方式,除了直接进行代码分离以外,还可使用委托来分离接口,在可以支持多重继承的语言里面,还能够采用多重继承的方式进行分离。
所谓最少知识原则,指的就是:
只和你的朋友谈话
。
这个原则用来指导咱们在设计系统的时候,应该尽可能减小对象之间的交互,对象只和本身的朋友谈话,也就是只和本身的朋友交互,从而松散类之间的耦合
。经过松散类之间的耦合来下降类之间的相互依赖,这样在修改系统的某一个部分时候,就不会影响其它的部分,从而使得系统具备更好的可维护性。
那么究竟哪些对象才能被看成朋友呢?最少知识原则提供了一些指导:
当前对象自己;
经过方法的参数传递进来的对象;
当前对象所建立的对象;
当前对象的实例变量所引用的对象;
方法内所建立或实例化的对象;
总之,最少知识原则要求咱们的方法调用,必须保持在必定的界限范围以内,尽可能减小对象的依赖关系。
除了上面提到的这些原则,还有一些你们都熟知的原则,好比:
面向接口编程;
优先使用组合/聚合,而非继承;
固然也还有不少不是很熟悉的原则,好比:
一个类须要的数据应该隐藏在类的内部;
类之间应该零耦合,或者只有传导耦合,换句话说,类之间要么没有关系,要么只使用另外一个类的接口提供的操做;
在水平方向上尽量统一的分布系统功能;
根据日志的严重程度和功能所划分红如下五种:
FETA:致命的错误,程序不能或不该该正常运行。FETAL级别的日志主要用于记录很是严重而致使程序不能正常运行的错误,好比得不到FileSystem对象、Job运行失败、ODFS写重要的数据文件不成功等。
ERROR:严重的错误,但不影响程序流程,Tool能够继续运行。ERROR级别的日志主要用于记录虽然严重但不至于影响程序运行的错误,好比Parser解析失败等。代码中捕获异常后输出的日志一部分会属于ERROR级别。
WARN: 警告日志,不影响程序流程,Tool能够继续运行。WARN级别的日志与ERROR级别的日志有一些类似,但一般是不能准确判断是否出现问题,须要人来判 断,好比某轮待抓取的数据为0;而ERROR级别的日志一般是在程序运行过程当中就能够发现代码、流程或数据等的某一方面或几方面存在问题。
INFO:信息日志,不影响程序流程,Tool能够继续运行。INFO级别的日志主要用来记录一些须要统计的信息,好比抓取统计,以及一些必要的诸如程序启停等信息。
DEBUG:调试日志,不影响程序流程,Tool能够继续运行。DEBUG级别的日志主要用于记录调试所用到的信息,在线上运行的过程当中该级别的日志不会输出。
设计这些日志级别是为了方便的对日志进行过滤,对于线上系统,通常会将日志级别设置为WARN
,这是为了让维护人员可以根据日志迅速判断问题,另外一方面不会由于频繁的写磁盘也带来性能问题。而在查找具体问题时,可能要将日志级别调到DEBUG
,但愿经过更多的输出信息来定位问题。
日志格式指的是输出到日志文件的每一条日志所遵循的格式。为方便起见,每一条日志格式都由若干个“key=value”这样的属性对组成,不一样的属性对之间用制表符(即“\t”)分隔。有几个特殊的属性稍有区别,不采用“key=value”这样的形式:
除此以外的其余属性均采用“key=value”的格式。这些属性对位于级别和消息体之间,以制表符(即“\t”)分隔,无需排序。对于“key=value”中的“key”,有一些经常使用的值能够定义为常量,如“CLASS(类名)”、“ERROR(错误类型)”等,对于很是见或特殊需求的“key”,能够在记log的时候本身定义,解析的时候注意保持一致便可。 属性中还有一个特殊的属性,即“ERROR(错误类型)”,用于表示错误的类型。ERROR和FETAL级别的日志中须要包含该属性,其余级别的日志中无需包括。“ERROR”属性的取值会有一个固定的范围,包括但不限于如下几种:
- IOException
- ConnectionRefused