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

  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. Python13_安装、解释器

    Linux下大部分系统默认自带python2.x的版本,最常见的是python2.6或python2.7版本,默认的python被系统很多程序所依赖, 比如centos下的yum就是python2写的 ...

  2. 《疯狂Java讲义第4版》PDF+代码+课件 电子书pdf 分享

    <疯狂Java讲义(第4版)>是<疯狂Java讲义>的第4版,第4版保持了前3版系统.全面.讲解浅显.细致的特性,全面新增介绍了Java 9的新特性. <疯狂Java讲义 ...

  3. C# 将PDF转为Word、Html、XPS、SVG、PCL、PS——基于Spire.Cloud.PDF

    Spire.Cloud.PDF提供了接口PdfConvertApi可用于将PDF文档转换为其他格式文档,如Word(docx/doc).Html.XPS.SVG.PCL.PS.Png以及XPS转成PD ...

  4. centos利用OneinStack搭建环境

    介绍 OneinStack支持以下数种环境组合: LNMP(Linux + Nginx+ MySQL+ PHP) LAMP(Linux + Apache+ MySQL+ PHP) LNMPA(Linu ...

  5. 原生JS数组方法实现(一)————push()、unshift()、pop()和shift()

    push 向数组末尾添加一个或多个元素,并返回数组新的长度 ```javascript function push(){ for(let i=0;i<arguments.length;i++){ ...

  6. 20191031-4 beta week 1/2 Scrum立会报告+燃尽图 02

    此作业要求参见 https://edu.cnblogs.com/campus/nenu/2019fall/homework/9912 git地址:https://e.coding.net/Eustia ...

  7. QTableView 控件的简单使用

    QTableView类提供了一个表视图的默认模型/视图实现. 一个QTableView实现一个表视图,它显示来自一个模型的项目.这个类用于提供以前由QTable类提供的标准表,但是使用Qt的模型/视图 ...

  8. Qt listWidget和QListWidgetItem的简单使用

    简单的来实习了下 #include "mainwindow.h" #include "ui_mainwindow.h" #include<QListWid ...

  9. 【题解】NOIP2017 提高组 简要题解

    [题解]NOIP2017 提高组 简要题解 小凯的疑惑(数论) 不讲 时间复杂度 大力模拟 奶酪 并查集模板题 宝藏 最优解一定存在一种构造方法是按照深度一步步生成所有的联通性. 枚举一个根,随后设\ ...

  10. Theia APIs——Preferences

    上一篇:Theia APIs——命令和快捷键 Preferences Theia有一个preference service,模块可以通过它来获取preference的值,提供默认的preference ...