☆软件研发代码规范

1. 分支开发流程

  1. GIT分支开发规范,具体请参考:http://www.jianshu.com/p/cbd8cf5e232d

2. 代码规范

  1. 主要使用Java语言来进行开发,严格遵循Sun公司的Java编码规范。此外还有以下补充。

2.1 大小写

  1. 常量的字母 全部大写,单词之间用一个 下划线字符(_)进行分隔。
  2. 除常量外的命名 采用大小写混合,提高名字的可读性。
  3. 一般采用小写字母,但是类和接口的名字的首字母,以及任何中间单词的 首字母应该大写

2.2 编码格式

  1. 确保IDE工作环境使用UTF-8编码格式。
  2. 缩进一律使用空格而非Tab。
  3. 缩进一律采用4空格。可以设置IDE 1Tab=4空格。
  4. 对于非第一次创建的代码文件,禁止做reformate操作,这个操作会破坏代码的修改历史,造成大概率的push、merge、pull等操作冲突。

2.3 常量定义

  1. 对具有特殊意义的数字或字符要以常量的形式定义,并说明常量所表示的意义,避免幻数的出现。

2.4 统一定义公共常量

  1. 对于一些公共常量的使用,应该单独定义相应的常量类,并统一使用,避免在各业务类、功能类中分别定义、直接使用。

2.5 命名规则

  1. 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;

  2. Class类:类名必须是名词,且以大写字母开头。类名应该简单清晰。

  3. Interface类:
    3.1 Interface命名上,暂定以XxxService的形式提供;
    3.2 最终提供的接口应以Java Interface的形式出现;
    3.3 每个独立的业务的Interface应该有独立的package包,一个package下可包含该业务模块下的多个Interface;
    3.4 每个Interface的一个方法对应所谓的一个“中间层服务接口”,需要按照规范书写该接口的说明;

  4. 缓存命名规则:对缓存的key要采用命名空间,以避免冲突,同时要考虑缓存的命中率,不要浪费缓存的空间。

2.6 Controller,Interface类,接口实现类编写注意事项

  1. Controller类里不能出现业务逻辑,只能直接调用Service类,不能直接调用Biz类(Biz类是对业务逻辑的实现封装,不依赖dao层,可独立做单元测试),manager类则是作为service、biz、dao三层的粘合剂,来协调三者执行关系。
  2. Interface接口定义类只定义方法,方法的实现要在实现类里完成,interface接口以xxxService结尾,接口实现类以xxxServiceImpl结尾。

2.7 注释

  1. 方法注释:每个接口、方法应该有一个方法的整体说明,包括方法实现的功能、参数的详细含义、返回值的取值及其详细含义。
  2. 类注释:对于工具类或者流程类,需要在类的注释中对于类的功能进行详细的说明;对于Model类,要对其重要的属性添加注释,注明其含义,必要时要重载hashCode和equals,toString方法。

3. 设计规范

3.1 对功能性模块的抽象

业务模块的开发过程中,应该避免过长的方法,进行合理的功能模块的提取以及抽象,避免同一段代码、类似代码到处copy的情况。

3.2 单一职责原则SRP(Single Responsibility Principle)

所谓单一职责原则,指的就是:一个类应该仅有一个引起它变化的原因。

这里变化的原因就是 所说的“职责”,如果一个类有多个引起它变化的原因,那么也就意味着这个类有多个职责,再进一步说,就是把多个职责耦合在一起了。这会造成职责的相互影响,可能一个职责的变化,会影响到其它职责的实现,甚至引起其它职责跟着变化,这种设计是很脆弱的。

这个原则看起来是最简单和最好理解的,但是实际上是很难完全做到的,难点在于如何区分这个“职责”,这是个没有标准量化的东西,哪些算职责,到底这个职责有多大的粒度,这个职责如何细化等等。因此,在实际开发中,这个原则也是最容易违反的。

3.3 开放-关闭原则OCP(Open-Closed Principle)

所谓开放-关闭原则,指的就是:一个类应该对扩展开放,对修改关闭。一般也被简称为开闭原则,开闭原则是设计中非常核心的一个原则。

开闭原则要求的是,类的行为是可以扩展的,而且是在不修改已有的代码的情况下进行扩展,也不必改动已有的源代码或者二进制代码。

看起来好像是矛盾的,怎么样才能实现呢?

实现开闭原则的关键就在于合理的抽象,分离出变化与不变化的部分,为变化的部分预留下可扩展的方式,比如:钩子方法、或是动态组合对象等等。

这个原则看起来也很简单,但事实上,一个系统要全部做到遵守开闭原则,几乎是不可能的,也没这个必要。适度的抽象可以提高系统的灵活性,使其可扩展、可维护,但是过度的抽象,会大大增加系统的复杂程度。应该在需要改变的地方应用开闭原则就可以了,而不用到处使用,从而陷入过度设计。

3.4 里氏替换原则LSP(Liskov Substitution Principle)

所谓里氏替换原则,指的就是:子类型必须能够替换掉它们的父类型。这很明显是一种多态的使用情况,它可以避免在多态的应用中,出现某些隐蔽的错误。

事实上,当一个类继承了另外一个类,那么子类就拥有了父类中可以继承下来的属性和操作,理论上来说,此时使用子类型去替换掉父类型,应该不会引起原来使用父类型的程序出现错误。

但是,很不幸的是,在某些情况下是会出现问题的,比如:如果子类型覆盖了父类型的某些方法,或者是子类型修改了父类型某些属性的值,那么原来使用父类型的程序就可能会出现错误,因为在运行期间,从表面上看,它调用的是父类型的方法,需要的是父类型方法实现的功能,但是实际运行调用的确是子类型覆盖实现的方法,而该方法跟父类型的方法并不一样,那就会导致错误的产生

从另外一个角度来说,里氏替换原则是实现开闭的主要原则之一,开闭原则要求对扩展开放,扩展的一个实现手段就是使用继承,而里氏替换原则是保证子类型能够正确替换父类型,只有能正确替换,才能实现扩展,否则扩展了也会出现错误

3.5 依赖倒置原则DIP(Dependence Inversion Principle)

所谓依赖倒置原则,指的就是:要依赖于抽象,不要依赖于具体类。要做到依赖倒置,典型的应该做到:

  1. 高层模块不应该依赖于底层模块,二者都应该依赖于抽象;
  2. 抽象不应该依赖于具体实现,具体实现应该依赖于抽象;

很多人觉得,层次化调用的时候,应该是高层调用“底层所拥有的接口”,这是一种典型的误解。事实上,一般高层模块包含对业务功能的处理和业务策略选择,应该被重用,应该是高层模块去影响底层的具体实现

因此,这个底层的接口,应该是由高层提出的,然后由底层实现的,也就是说底层的接口的所有权在高层模块,因此是一种所有权的倒置。

倒置接口所有权,这就是著名的Hollywood(好莱坞)原则:不要找我们,我们会联系你

3.6 接口隔离原则ISP(Interface Segregation Principle)

所谓接口隔离原则,指的就是:不应该强迫客户依赖于他们不用的方法

这个原则用来处理那些比较“庞大”的接口,这种接口通常会有较多的操作声明,涉及到很多的职责。客户在使用这样的接口的时候,通常会有很多它不需要的方法,这些方法对于客户来讲,就是一种接口污染,相当于强迫用户在一大堆“垃圾方法”里面去寻找他需要的方法

因此,这样的接口应该被分离,应该按照不同的客户需要来分离成为针对客户的接口,这样的接口里面,只包含客户需要的操作声明,这样既方便了客户的使用,也可以避免因误用接口而导致的错误。

分离接口的方式,除了直接进行代码分离之外,还可以使用委托来分离接口,在能够支持多重继承的语言里面,还可以采用多重继承的方式进行分离。

3.7 最少知识原则(Least Knowledge Principle)

所谓最少知识原则,指的就是:只和你的朋友谈话

这个原则用来指导我们在设计系统的时候,应该尽量减少对象之间的交互,对象只和自己的朋友谈话,也就是只和自己的朋友交互,从而松散类之间的耦合。通过松散类之间的耦合来降低类之间的相互依赖,这样在修改系统的某一个部分时候,就不会影响其它的部分,从而使得系统具有更好的可维护性。

那么究竟哪些对象才能被当作朋友呢?最少知识原则提供了一些指导:

当前对象本身;

通过方法的参数传递进来的对象;

当前对象所创建的对象;

当前对象的实例变量所引用的对象;

方法内所创建或实例化的对象;

总之,最少知识原则要求我们的方法调用,必须保持在一定的界限范围之内,尽量减少对象的依赖关系

3.8 其它原则

除了上面提到的这些原则,还有一些大家都熟知的原则,比如:

面向接口编程;

优先使用组合/聚合,而非继承;

当然也还有很多不是很熟悉的原则,比如:

一个类需要的数据应该隐藏在类的内部;

类之间应该零耦合,或者只有传导耦合,换句话说,类之间要么没有关系,要么只使用另一个类的接口提供的操作;

在水平方向上尽可能统一的分布系统功能;

4. 日志规范

根据日志的严重程度和功能所划分成以下五种:

  1. FETA:致命的错误,程序不能或不应该正常运行。FETAL级别的日志主要用于记录非常严重而导致程序不能正常运行的错误,比如得不到FileSystem对象、Job运行失败、ODFS写重要的数据文件不成功等。

  2. ERROR:严重的错误,但不影响程序流程,Tool可以继续运行。ERROR级别的日志主要用于记录虽然严重但不至于影响程序运行的错误,比如Parser解析失败等。代码中捕获异常后输出的日志一部分会属于ERROR级别。

  3. WARN: 警告日志,不影响程序流程,Tool可以继续运行。WARN级别的日志与ERROR级别的日志有一些相似,但通常是不能准确判断是否出现问题,需要人来判 断,比如某轮待抓取的数据为0;而ERROR级别的日志通常是在程序运行过程中就可以发现代码、流程或数据等的某一方面或几方面存在问题。

  4. INFO:信息日志,不影响程序流程,Tool可以继续运行。INFO级别的日志主要用来记录一些需要统计的信息,比如抓取统计,以及一些必要的诸如程序启停等信息。

  5. DEBUG:调试日志,不影响程序流程,Tool可以继续运行。DEBUG级别的日志主要用于记录调试所用到的信息,在线上运行的过程中该级别的日志不会输出。

设计这些日志级别是为了方便的对日志进行过滤,对于线上系统,一般会将日志级别设置为WARN,这是为了让维护人员能够根据日志迅速判断问题,另一方面不会因为频繁的写磁盘也带来性能问题。而在查找具体问题时,可能要将日志级别调到DEBUG,希望通过更多的输出信息来定位问题。

5. 日志格式

日志格式指的是输出到日志文件的每一条日志所遵循的格式。为方便起见,每一条日志格式都由若干个“key=value”这样的属性对组成,不同的属性对之间用制表符(即“\t”)分隔。有几个特殊的属性稍有区别,不采用“key=value”这样的形式:

  1. 时间:时间是一条日志的第一项。而由于outlog会采用“yyyyMMddHHmmssSS”这样的格式自动记录日志的时间,所以无需再增加“key=value”这种格式的时间。
  2. 级别:级别是一条日志的第二项。级别采用“[LEVEL]”这种形式,如“[INFO]”。
  3. 消息体:消息体是一条日志的最后一项。为更直观,消息体也不采用“key=value”的格式,而直接输出,如“This is a message.”。

除此之外的其他属性均采用“key=value”的格式。这些属性对位于级别和消息体之间,以制表符(即“\t”)分隔,无需排序。对于“key=value”中的“key”,有一些常用的值可以定义为常量,如“CLASS(类名)”、“ERROR(错误类型)”等,对于非常见或特殊需求的“key”,可以在记log的时候自己定义,解析的时候注意保持一致即可。 属性中还有一个特殊的属性,即“ERROR(错误类型)”,用于表示错误的类型。ERROR和FETAL级别的日志中需要包含该属性,其他级别的日志中无需包括。“ERROR”属性的取值会有一个固定的范围,包括但不限于以下几种:

  1. IOException
  2. ConnectionRefused
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容