编码风格在编程中是一个相对乏味的主题,但是合适的编码风格对一个有效的程序员是至关重要的。 它有三个组成部分:

  1. 程序结构 ( application layout)

  2. 编码规则或风格

  3. 命名约定

我已经在清晰架构(Clean Architecture)的Go微服务: 程序结构¹中讨论了程序结构,因此本文将介绍后两点。

编码规则或风格
  1. 没有包级别(package level)变量。

    包级别变量打破了函数封装并使函数有了不确定。我在本程序中遵循了这个规则,唯一的例外是在“容器”包中,因为它负责程序级配置,在这里很难做到。其实即使在“容器”包中也可以去除掉包级别变量,但它需要付出很多努力,有些得不偿失。但是,由于包级别变量仅限于“容器”包中,因此导致的破坏大大减少。

  2. 尽量少使用常量

    常量也是包级别,因为具有不变性,它们作为全局变量的危害较小,但它们仍然会破坏函数封装并需要进行限制。

  3. 依赖于接口而不是具体类型

    当你尝试最小化外部更改对程序的影响时,无论外来者是函数,包还是应用程序,都要使代码依赖于接口而不是具体类型。

命名规则

最佳的代码是自我解释的,良好的命名起着至关重要的作用。Go的命名约定与Java非常矛盾。尝试之后,我发现它是有效的,在创建简洁的代码同时并没有降低可读性。 Go是一种相对与更底层接近的语言,人们用它来编写网络,驱动程序和docker容器代码。在这些环境中,使用简洁的名称是合适的。

但是,在编写业务应用程序时,我们需要创建许多不同的类型或结构来处理相似的业务概念,简洁的命名便不再适用。例如,为了处理与“用户”相关概念,我们有“User”,“UserDataService”,“RegistrationUseCase”,“RegistrationUseCaseIterface”和“UserDataInterface”,它们都与“User”有关,但都完全不同。你确实需要一个相对较长的名字来区分它们。为了获得良好的可读性,我有意违反了Go的一些命名约定,我将逐一解释它们。

我遵循的一条规则是“变量声明(name declaration)与其使用之间的距离越大,名称应该越长”Andrew Gerrand². 我从Dave Cheney³的一篇文章中学到了这一点。基于它,我创建了自己的命名规则:“为类型(结构,接口)或函数命名使用长名称使其清晰易读,为局部变量命名使用短名称”,因为局部变量声明和使用之间的距离较短。

给类型(types)命名:

当我看到一个名字时,重要的是要了解它是哪种类型,它处于哪个层。例如,“UserDataInterface”,告诉我它是域模型“User”,它提供数据服务(持久性),并且它是一个接口。

Model:

域模型层,是最容易提供名称的层。 例如,域模型用户的“User”。

Dataservice:

数据持久性服务层。 例如“UserDataMySql”作为用户持久性服务MySQL数据库的命名; “UserDataCouchdb”作为CouchDB数据库的用户持久性服务的命名。 用户数据服务的不同实现共享相同的前缀“UserData”,并且它们的接口是“UserDataInterface”。

“CourseDataInterface”是课程数据服务的接口,“CourseDataMySql”是具体课程数据服务MSql数据库实现的名称。 所有数据服务共享相同的前缀“[model]Data”。

Use Case:

用例层。 “RegistrationUseCase”是注册用例的具体类型,接口是“RegistrationUseCaseInterface”。 “ListCourseUseCase”是课程列表用例的具体类型。 所有用例共享相同的后缀“UseCase”

Interface:

在清晰架构(Clean Architecture)中,所有业务逻辑都是基于接口调用的。 在遇到类型时,重要的是要识别类型是接口还是具体实现,因此我在所有接口上添加后缀“Interface”,例如“UseCaseInterface”。 如果你认为它太长,你可以用“I”,“If”或“Intf”等缩略语替换“Interface”。 对我来说,打字不是一个问题,IDE在大多数时间里都已经把问题解决了。

Constants:

对于常量,重要的是将它们与变量区分开来,所以我使用全部大写,如果是多字段常量(multi-words constant),我使用蛇形命名法(Snake Case)而不是驼峰命名法(Camel Case)(我知道它与Go命名约定相左)。 例如,“QUERY_USER_BY_NAME”而不是“queryUserByName”,这使它易读性更好。

结论:

编码风格对于使编程效率至关重要。 良好的命名使代码自我解释。 对类型或函数使用长名称,对局部变量使用短名称。 将“interface”放在接口名称中是有帮助的。 用蛇形命名法(Snake Case)并且所有字母大写来命名常量,以便于识别。

源程序:

完整的源程序链接 github: https://github.com/jfeng45/servicetmpl

索引:

[1][Go Microservice with Clean Architecture: Application Layout](https://jfeng45.github.io/posts/go_microservice_application_layout/)

[2][What’s in a name?](https://talks.golang.org/2014/names.slide#4)

[3][Practical Go: Real world advice for writing maintainable Go programs](https://dave.cheney.net/practical-go/presentations/qcon-china.html)

清晰架构(Clean Architecture)的Go微服务: 编码风格的更多相关文章

  1. (转)微服务架构 互联网保险O2O平台微服务架构设计

    http://www.cnblogs.com/Leo_wl/p/5049722.html 微服务架构 互联网保险O2O平台微服务架构设计 关于架构,笔者认为并不是越复杂越好,而是相反,简单就是硬道理也 ...

  2. Java 18套JAVA企业级大型项目实战分布式架构高并发高可用微服务电商项目实战架构

    Java 开发环境:idea https://www.jianshu.com/p/7a824fea1ce7 从无到有构建大型电商微服务架构三个阶段SpringBoot+SpringCloud+Solr ...

  3. 通俗地理解面向服务的架构(SOA)以及微服务之间的关系

    SOA是一种软件的应用架构方法,它基于面向对象,但又不是面向对象,整体上是面向服务的架构.SOA由精确的服务定义.松散的构件服务组成,以及业务流程调用等多个方面形成的一整套架构方法. 这话是不是听起来 ...

  4. Re:从0开始的微服务架构--(二)快速快速体验微服务架构?--转

    原文地址:https://mp.weixin.qq.com/s/QO1QDQWnjHZp8EvGDrxZvw 这是专题的第二篇文章,看看如何搭建一个简单模式的微服务架构. 记得好久之前看到一个大牛说过 ...

  5. 【分布式微服务企业快速架构】SpringCloud分布式、微服务、云架构快速开发平台源码

    鸿鹄云架构[系统管理平台]是一个大型 企业.分布式.微服务.云架构的JavaEE体系快速研发平台,基于 模块化.微服务化.原子化.热部署的设计思想,使用成熟领先的无商业限制的主流开源技术 (Sprin ...

  6. 清晰架构(Clean Architecture)的Go微服务: 设计原则

    我最近写了一个Go微服务应用程序,这个程序的设计来自三个灵感: 清晰架构"Clean Architecture"¹ and SOLID (面向对象设计)² 设计 原则³ Sprin ...

  7. 清晰架构(Clean Architecture)的Go微服务

    我用Go和gRPC创建了一个微服务项目,并试图找出最好的程序结构,它可以作为我其他项目的模板.我还将程序设计和编程的最佳实践应用于Go Microservice程序,例如清晰架构(Clean Arch ...

  8. MicroService 微服务架构模式简述

    开源地址: https://github.com/TheCodeCleaner/MicroService4Net 本文内容 微服务 微服务风格的特性 组件化(Componentization )与服务 ...

  9. 微服务架构(Microservices) ——Martin Flower

    不知不觉到达了Sring Boot的学习中了,在学习之前,了解微服务架构是很有必要的,对于自己提升今后面试的软实力有很大帮助,在此写下. 让我们接下来看下Martin Flower 如何解释微服务架构 ...

随机推荐

  1. 【Docker】删除镜像

    删除镜像:docker rmi [OPTIONS] IMAGE [IMAGE...] 1.删除所有未被 tag 标记和未被容器使用的镜像: docker image prune 2.删除所有未被容器使 ...

  2. E420笔记本升级固态硬盘

      后壳比较好拆   机械硬盘盒 这里 可费了好大劲 才 拧开这 4个螺丝 光驱支架买的这个38-5rmb,京东自提       以前不知道的一件事: 原来的光驱挡板要自己拆下来换到新买的光驱支架上面 ...

  3. 2019 沈阳网络赛 Fish eating fruit

    这题看了三个月,终于过了,第一次看的时候没学树形DP,想用点分治但是不会 后来学了二次扫描,就有点想法了.... 这东西也真就玄学了吧... #include<iostream> #inc ...

  4. $NOIp$普及组做题记录

    \([NOIp2014]\) 螺旋矩阵 \(Sol\) 直接模拟,一次走一整行或者一整列.复杂度\(O(n)\). \(Code\) #include<bits/stdc++.h> #de ...

  5. $Poj2376\ Poj3171\ Luogu4644\ Cleaning\ Shifts$ 数据结构优化$DP$

    $Poj$    $AcWing$    $Luogu$ $ps:$洛谷题目与$Poj$略有不同,以下$Description$是$Poj$版.题目的不同之处在于洛谷中雇用奶牛的费用不相同,所以不可以 ...

  6. 在nginx里面部署node.js本地服务器

    我一个前端,为啥要搞服务器呢?因为公司就招了一个后端啊,后端忙不过来,就叫我这个萌新前端去搞后端的东西,我太难了. 直接进入正题吧,因为公司需求,要我在nginx服务器上面搭一个node.js服务器, ...

  7. 1081 检查密码 (15分)C语言

    本题要求你帮助某网站的用户注册模块写一个密码合法性检查的小功能.该网站要求用户设置的密码必须由不少于6个字符组成,并且只能有英文字母.数字和小数点 .,还必须既有字母也有数字. 输入格式: 输入第一行 ...

  8. MinGW-W64下载与安装

    安装方案 1 下载安装包,MinGW-w64 - for 32 and 64 bit Windows,然后直接以管理员安装即可,但是这个方案在部分电脑可能不行,会提示 cannot download ...

  9. netcore 自动生成Dockerfile的坑

    简介   之前采用shell脚本+dockerfile的方式构建项目,后来发现有Docker在17.05版本之后有多阶段构建方式,该文主要记录了netcore采用dockerfile构建遇到的坑. 原 ...

  10. 日志查看工具 logviewer pro的使用

    1.logViewer Pro 介绍 logViewer Pro 是一款log文件查看器,它可以在短短数秒内打开上G的LOG文件,支持高亮某行文字(例如警告,错误),支持Unicode名字,支持查看的 ...