前言
最近一直有小伙伴私信我学Go语言的问题:
有的小伙伴觉得客户端太卷了,想转服务端,觉得 Java 也卷,想学Go语言;
有的小伙伴是想从PHP或者Java转 Go ,做高并发编程,觉得Go更有前途。
聊的多了,发现这是一个共性问题,所以干脆整理成文章,希望对更多的人有帮助。
这篇文章会结合我的经历:
聊聊我认为客户端转服务端开发最大的挑战是什么?
如何高效转型做服务端开发?如何高效学完Go基础?
在熟练掌握Go基础之后,如何进阶?进阶要掌握哪些知识点?
先说结论
- 客户端转服务端,最大的挑战不是学一门新语言,而是 编程思维的改变 ;
- “三刷”官方文档是我高效学习一门新的编程语言的制胜法宝 :
- 1刷从头看到尾,扫清知识盲点,搞清楚概念;
- 2刷必须手敲,而且要写注释和总结;
- 3刷先只写注释,不看文档实现功能,遇到问题再和文档比较,加深理解。如果还有余力,就和我一样整理成文章,分享出来帮助大家学习,回馈社区。
- 在掌握Go基础之后,也可以 通过“三刷”的方式掌握 SQL , Redis , Linux , Nginx 的基础知识点 ,这样就有能力开发Web项目了。
- 要进阶就要学“ 微服务 ”和“ DDD ”!下文也会重点讲讲微服务和DDD的概念,让大家先有个目标,这样才能心中有火,眼里有光。
我的经历
我从2015年开始编程,已经有7年经验。入行时用Java语言开发了2年安卓客户端,然后转岗用PHP做服务端开发,最近2年用Go做Web应用开发和微服务开发。
下面介绍一下我的转型经历,看看对小伙伴们有没有启发,欢迎在评论区留言。
客户端开发到服务端开发
无论客户端转服务端,还是服务端转客户端,在有基础的情况下,学习一门新的编程语言,我认为都是比较轻松的。
对有基础的同学来说,学习一门新的语言,无外乎就是学习新语言的:数据类型、函数、 运算符 、错误处理等,再重点攻克一下语言的特点,基本2周时间就能去尝试写简单的demo,开发项目了。
当然,开发项目往往不是一帆风顺的,遇到问题也不要怕,一个一个的去解决就好了。 多在论坛或者社区里和大家交流,闻道有先后,不用担心自己提的问题太简单而不好意思。
难点在哪里呢?
客户端开发思维
回想一下当年用Java开发安卓时考虑的问题:
- 如何复用 UI ,如何做到高保真还原设计稿,机型兼容处理
- Activity 生命周期的管理,不同生命周期适合处理什么业务
- 如何做机型兼容? 小米 和 华为 的消息通知如何做特殊处理?
- 内存泄露的场景和解决办法
- 客户端如何实现 三级缓存
- 如何合理的使用 线程 和 线程池 等
尤其是刚入行的时候,就是照着设计稿按部就班的切页面开发功能。
有了经验之后,会先把项目中所有的列表页面抽取出来,封装一套组件;再把所有的按钮、轮播图等抽取出来,封装成组件…
反思一下,我们开发客户端的思维习惯是什么呢?我们是如何设计代码的?
我认为是以设计稿为标准进行开发的,每位客户端开发的同学要开展工作都离不开 UI设计师 的设计稿。我称这种编程思维是: “页面驱动设计”
资深的客户端小伙伴们还有哪些高见,欢迎在评论区讨论。
服务端开发思维
当我转岗做服务端开发,发现一个非常爽的事情:我不需要再等UI同学的设计稿、UE同学的交互图了。
只要产品同学确定好PRD文档,我就可以开发了,开发的顺序往往是这样的:
- 通读一遍需求文档和原型图
- 梳理业务逻辑,进行抽象,明确有多少个功能需求要开发
- 根据功能需求创建数据库,创建表,添加字段,设置合适的字段类型,长度,主外键等
- 考虑业务场景,创建 索引 …
- 开始疯狂的CRUD…
- 开始疯狂的加Cache…
- 开发疯狂的给客户端提供数据接口…
- 持续迭代:根据业务增长做负载均衡、分库分表、 读写分离 ….
做服务端开发的小伙伴是不是和我一样呢?欢迎在评论区讨论。
你认为上面哪个步骤最重要呢?
我认为 设计数据库表结构 是最重要的环节:对业务的理解程度,对可扩展性的考虑程度都直接影响到了我们会“如何设计数据库表结构”; 数据库表结构设计 是否合理,也直接影响了我们后续开发业务逻辑是否顺利。
我称这种编程思维是: “数据驱动设计” 。
(PS: 网络上关于“数据驱动设计”这一名词更主流的解释:通过不断的数据积累和反馈,来指导产品的更新迭代。 )
阶段性总结
客户端和服务端就是会有不同的编程思维,关注点是不一样的:
客户端不需要关心数据是怎么来的,要求服务端返回自己需要的数据即可。
服务端不需要关心客户端如何管理应用的生命周期,只需要按照客户端要求返回数据即可。
以上,就是我认为的客户端转服务端, 最大的挑战是编程思维,思考方式,考虑问题关注点的转变 。
客户端同学在学完服务端编程语言后,要有意识的站在服务端的角度去思考问题,及时调整自己的角度,不要用之前开发客户端的角度思考问题,不然会很痛苦。
如果你有PHP或者Java的基础想转Go,相比于前端同学会轻松很多,可以复刻一下我的转Go之旅:# 回顾一下我的Go学习之旅 | 对你应该会有启发
好了,给想转Go同学的建议聊完了,咱们再聊一聊进阶的知识点:DDD和微服务。
不同岗位的技术人员思维方式有区别,技术人员和非技术人员的思考问题的方式就更不一样了。
正是因为不同群体在协助中就是会有“思考方式的不同”,有一个科学的方法来指导我们更好的协作就非常重要了。
我们再来延伸一下,聊一聊“ 软件架构 演进史”:
软件架构演进史
结合我自己的经历来介绍一下:
软件的 架构模式 总的说经历了三个阶段的演进: 从单机、集中式到分布式微服务架构 。
第一阶段: 单机架构,这个阶段通常采用面向过程的设计方法 。通常采用C/S架构。现在反思一下,我在2015年刚刚入行做Android开发时的思考方式,本质上是面向过程的。虽然Java是面向对象语言,并且一直强调面向对象编程,但是因为自己的编程思想并没有转变过来,导致写了一段时间烂代码,被组长一顿KO操作。
第二阶段: 集中式架构,这个阶段通常采用面向对象的设计方法 。一般采用经典的三层架构MVC,系统包括业务接入层、业务逻辑层和数据库层。在开发Android的后期是采用的这种方式,包括使用PHP做服务端开发时也是这种架构。这种设计模式的问题是:容易使系统变得臃肿,不易扩展性、弹性伸缩能力差。
第三阶段: 分布式 微服务 架构, 微服务架构 可以实现业务和应用之间的 解耦 。解决单体应用扩展性差、弹性伸缩能力不足的问题,非常适合在 云计算 环境下的部署和运营。近期在使用go-micro微服务框架开发项目,对微服务架构有了新的认识。
分布式微服务架构是主流趋势,越来越多的企业采用分布式微服务架构进行业务转型。
那么如何才能更好的从单体架构和集中式架构转型到分布式微服务架构呢?答案就是:DDD。 这也是我们的进阶之道。
我们再回顾一下上面提到的” 页面驱动设计 “和” 数据驱动设计 “的场景,这样能更好的理解DDD。
什么是DDD?
DDD (Domain Driven Design):领域驱动设计。
我不想复制粘贴官方对于DDD晦涩难懂的定义,下面我将用最简单易懂的话告诉你DDD是什么?你值得知道的几个概念,对一线开发人员来说,知道这些,足矣。
1. 核心思想
- DDD的核心思想就是避免业务逻辑的复杂性和技术实现的复杂性耦合在一起。
- 明确业务复杂性和技术复杂性的边界,隔离双方的复杂性,站在更高的角度实现解耦。
2. 最大价值
DDD最大的价值就是梳理业务需求,抽象出一个个“领域”,并形成各个领域之间的接口交互,方便团队协作,推进项目前进。
3. 必懂概念
领域
领域就是一种 边界 的划分,首先举一些生活中的例子:
比如互联网、机械制造、种植业、养殖业等等这就是不同的领域;
再比如互联网中的: 移动互联网 、 互联网金融 、互联网健康这也是不同的领域;
我们把领域抽象一下,领域还可以这样划分:
- 核心领域:业务系统中的核心价值
- 通用领域:提供通用服务的领域,比如消息系统
- 支撑领域:作为基础设施,专注于业务系统中的某个重要业务,比如日志系统
在明确领域的概念之后,还有个更重要的概念:
领域模型
DDD的核心就是通过一套科学的方法论告诉大家如何创建不同的领域,如何确定领域的边界。
“模型”是DDD中的重要概念:模型是对领域的抽象和模拟。
“建模”是DDD中重要的手段:建模是针对特定问题建立领域的合理模型。
“不以用户为中心”
DDD领域驱动设计,还有一个有意思的观点:“不以用户为中心”。
为什么会这么说呢?
因为DDD认为,“以用户为中心”其实是表层需求,真正的需求应该是基于领域的,领域之所以有意义,一定是和人有关的。
所以做领域驱动设计时,应该做到“客观设计”,就是无论是谁使用,如何使用,这个领域都是这样的,挖掘深层次的需求。
讲个小故事:
在汽车出现之前,那时候人们的需求就是想要一辆更快的马车,如果当时被限制在“用户需求”的框框里,怎么能发明出来汽车呢?
仔细品品这个小故事,是不是很有意思。
阶段性小结
对于小白来说,关于DDD了解到这里就足够了。
毕竟设计思想这种东西需要长时间的积累,需要不断的通过项目实战才能领悟。
目前也有不少人喷“DDD”,认为这是给CTO、项目经理、老板吹水用的。
对于一线开发人员来讲,与其关注DDD,不如关注如何用好“微服务架构”。
以我的经验,当我看了很多DDD的资料之后还是云里雾里,但是当我使用微服务架构去开发了一个项目,回过头来再思考DDD,就清晰多了。
下面开始介绍微服务是如何让DDD落地的?
微服务
微服务的特点如下,大家先有个整体的概念,后面我会使用go-micro和go-zero框架带大家进行微服务项目的实践。
1. 单一职责
DDD思想指导我们对业务逻辑进行拆分,明确各自边界,形成不同的领域,不同的领域对应不同的微服务,这就是单一职责。
2. 团队独立
不同的领域对应不同的业务团队,也对应着不同的技术团队,彼此之间是解耦的。
3. 技术独立
不同的领域,不同的团队可以使用不同的开发语言,各自独立,只要按规范提供服务即可。
4. 数据库分离
每个领域(每个服务)都拥有自己的数据源。
5. 独立部署
每个领域(每个服务)都是独立的组件,可复用,可替换,降低耦合,易维护,易集群 Docker 部署服务
总结
这篇文章结合我的经历,分享了一下我客户端转服务端在编程思维上的转变;再通过软件架构演进史带大家了解了从单体架构到集中式架构,再到目前主流的分布式微服务架构,为大家进阶实战指明了方向。