哪种人是软件设计中的稀缺型人才?


阿里妹导读:好的系统架构离不开好的接口设计,因此,真正懂接口设计的人往往是软件设计队伍中的稀缺型人才。
为什么在接口制定标准中说:一流的企业做标准,二流的企业做品牌,三流的企业做产品?依赖倒置到底是什么意思?什么时候使用接口才算合理?今天,阿里匠人——张建飞将为你详细解读。

接口有什么好处(Why)

在我看来,接口在软件设计中主要有两大好处:

1. 制定标准

标准规范的制定离不开接口,制定标准的目的就是为了让定义和实现分离,而接口作为完全的抽象,是标准制定的不二之选。

这个世界的运转离不开分工协作,而分工协作的前提就是标准化。试想一下,你家的电脑能允许你把显卡从NVIDIA换成七彩虹;你家的灯泡坏了,你可以随便找一个超市买一个新的就可以换上;你把数据从Oracle换成了MySQL,但是你基于JDBC写的代码都不用动。等等这些事情的背后都是因为接口,以及基于接口定制的标准化在起作用。

在Java的世界里,有一个很NB的社区叫JCP( Java Community Process),就是专门通过JSR(Java Specification Request)来制定标准的。正是有了JSR-315(Java Servlet),我们服务端的代码才能在Tomcat和Jetty之间自由切换。

最后,我想用一句话来总结一下标准的重要性,那就是:“一流的企业做标准,二流的企业做品牌,三流的企业做产品。

2. 提供抽象

除了标准之外,接口还有一个特征就是抽象。正是这样的抽象,得以让接口的调用者和实现者可以完全的解耦。

解耦的好处是调用者不需要依赖具体的实现,这样也就不用关心实现的细节。这样,不管是实现细节的改动,还是替换新的实现,对于调用者来说都是透明的。

这种扩展性和灵活性,是软件设计中,最美妙的设计艺术之一。一旦你品尝过这种“依赖接口”的设计来带的美好,就不大会再愿意回到“依赖实现”的简单粗暴。平时我们说的“面向接口编程原则”和“依赖倒置原则”说的都是这种设计。

另外,一旦你融会贯通的掌握了这个强大的技巧——面向抽象、面向接口,你会发现,虽然面向实现和面向接口在代码层面的差异不大,但是其背后所隐含的设计思想和设计理念的差异,不亚于我篮球水平和詹姆斯篮球水平之间的差异!


//面向接口Animal dog = new Dog();//面向实现Dog dog = new Dog();

作为一名资深职场老兵,我墙裂建议各位在做系统设计、模块设计、甚至对象设计的时候。要多考虑考虑更高层次的抽象——也就是接口,而不是一上来就陷入到实现的细节中去。要清楚的意识到接口设计是我们系统设计中的主要工作内容。而这种可以跳出细节内容,站在更高抽象层次上,来看整个系统的模块设计、模块划分、模块交互的人,正是我们软件设计队伍中,非常稀缺的人才。有时候,我们也管这些人叫架构师。

什么时候要用接口(When)

有扩展性需求的时候

可扩展设计,主要是利用了面向对象的多态特性,所以这里的接口是一个广义的概念,如果用编程语言的术语来说,它既可以是Interface,也可能是Abstract Class。

这种扩展性的诉求在软件工作中可以说无处不在,小到一个工具类。例如,我现在系统中需要一个开关的功能,开关的配置目前是用数据库做配置的,但是后续可能会迁移到Diamond配置中心,或者SwitchCenter上去。

简单做法就是,我直接用数据库的配置去实现开关功能,如下图所示:

但是这样做的问题很明显,当需要切换新的配置实现的话,就不得不扒开原来的应用代码做修改了。更恰当的做法应该是提供一个Switch的接口,让不同的实现去实现这个接口,从而在切换配置实现的时候,应用代码不再需要更改了。

如果说,上面的重构只是使用策略模式对代码进行了局部优化,做了当然更好,不做的话,影响也还好,可以将就着过。

那么接下来我要给大家介绍的场景,就不仅仅是“要不要”的问题,而是“不得不”的问题了。

例如,老板给你布置了一个任务,实现一个类似于eclipse可以可插拔(Pluggable)的产品,此时,使用接口就不仅仅是一个选择问题了,而是你不得不使用的架构方法了。因为,可插拔的本质就是,你制定一个标准接口(API),然后有不同的实现者去做插件的实现,最后再由PluginManager把这个插件机制串起来而已。

下图是我当时给ICBU设计的一个企业协同云的Pluggable架构,其本质上,也就是基于接口的一种标准和扩展的设计。

需要解耦的时候

上面介绍的关于Switch的例子,从表面上来看,是扩展性的诉求。但不可扩展的本质原因正是因为耦合性。当我们通过Switch Interface来解开耦合之后,扩展性的诉求也就迎刃而解了。

发现这种耦合性,对系统的可维护性至关重要。有一些耦合比较明显(比如Switch的例子)。但更多的耦合是隐式的,并没有那么明显,而且在很长一段时间,它也不是什么问题,但是,一旦它变成一个问题,将是一个非常头痛的问题。

一个真实的典型案例,就是java的logger,早些年,大家使用commons-logging、log4j并没有什么问题。然而,此处一个隐患正在生长——那就是对logger实现的强耦合。

当logback出来之后,事情开始变得复杂,当我们想替换一个新的logger vendor的时候,为了尽量减少代码改动,不得不上各种Bridge(桥接),到最后日志代码变成了谁也看不懂的代码迷宫。下图就是我费了九头二虎之力,才梳理清楚的一个老业务系统的日志框架依赖情况。

试想一下,假如一开始我们就能遇见到这种紧耦合带来的问题。在应用和日志框架之间加入一层抽象解耦。后续的那么多桥接,那么多的向后兼容都是可以省掉的麻烦。而我们所要做的事情,实际上也很简单——就是加一个接口做解耦而已(如下图所示):

要给外界提供API的时候

上文已经介绍过JCP和JSR了,大家有空可以去阅读一些JSR的文档。不管是做的比较成功的JSR-221(JDBC规范)、JSR-315(Servlet规范),还是比较失败的JSR-94(规则引擎规范)等等。其本质上都是在定义标准、和制定API。其规范的内容都是抽象的,其对外发布的形式都是接口,它不提供实现,最多会指导实现。

还有就是我们通常使用的各种开放平台的SDK,或者分布式服务中RPC的二方库,其包含的主要成分也是接口,其实现不在本地,而是在远程服务提供方。

类似于这种API的情况,都是在倒逼开发者要把接口想清楚。我想,这也算微服务架构一个漂亮的“副作用”吧。当原来单体应用里的各种耦合的业务模块,一旦被服务化之后,就自然而然的变成“面向接口”的了。

通过依赖倒置来实现面向接口(How)

关于依赖倒置,我以前写过不少文章,来阐述它的重要性。实际上,我上面给出的关于扩展需求的Switch案例,关于解耦的logger案例。其背后用来解决问题的方法论都是依赖倒置。

如上图所示,依赖倒置原则主要规定了两件事情:

  1. 高层模块不应该依赖底层模块,两者都应该依赖抽象(如上面的图2所示)
  2. 抽象不应该依赖细节,细节应该依赖抽象。

我们回头看一下,不管是Switch的设计,还是抽象Logger的设计,是不是都在遵循上面的两条定义内容呢。

实际上,DIP(依赖倒置原则)不光在对象设计,模块设计的时候有用。在架构设计的时候也非常有用,比如,我在做COLA 1.0的时候,和大多数应用架构分层设计一样,默许了Domain层可以依赖Infrastructure层。

这种看起来“无伤大雅”的设计,实际上还是存在不小的隐患,也违背了我当初想把业务复杂度和技术复杂度分开的初心,当业务变得更加复杂的时候,这种“偷懒”行为很可能会导致Domain层堕落成大泥球(Big mud ball)。因此,在COLA 2.0的时候,我决定用DIP来反转Domain层和Infrastructure层的关系,最终形成如下的结构:

这样做的好处是Domain层会变得更加纯粹,其好处体现在以下三点:

1、解耦: Domain层完全摆脱了对技术细节(以及技术细节带来的复杂度)的依赖,只需要安心处理业务逻辑就好了。
2、并行开发: 只要在Domain和Infrastructure约定好接口,可以有两个同学并行编写Domain和Infrastructure的代码。
3、可测试性: 没有任何依赖的Domain里面都是POJO的类,单元测试将会变得非常方便,也非常适合TDD的开发。

什么时候不需要接口

"劲酒虽好,可不要贪杯哦!"

和许多其它软件原则一样,面向接口很好,但也不应该是不分背景、不分场合胡乱使用的杀手锏和尚方宝剑。因为过多的使用接口,过多的引入间接层也会带来一些不必要的复杂度。

比如,我就看过有些应用的内部模块设计的过于“灵活”,给什么DAO、Convertor都加上一层Interface,但实际情况是,应用中对DAO、Convertor的实现进行替换的可能性极低。类似于这样的,装模作样,装腔作势的Interface就属于可有可无的鸡骨头(比鸡肋还低一个档次)。

就像《Effective Java》的作者Joshua Bloch所说:

“同大多数学科一样,学习编程的艺术首先要学会基本的规则,然后才能知道什么时候可以打破这些规则。”


双11福利来了!先来康康#怎么买云服务器最便宜# [并不简单]参团购买指定配置云服务器仅86元/年,开团拉新享三重礼:1111红包+瓜分百万现金+31%返现,爆款必买清单,还有iPhone 11 Pro、卫衣、T恤等你来抽,马上来试试手气  https://www.aliyun.com/1111/2019/home?utm_content=g_1000083110

原文链接
本文为云栖社区原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/517522.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

快速Ubuntu的配置(以ubuntu 20.04桌面版为例)

文章目录一、💖更换镜像源二、💖安装VMware Tools工具三、💖安装Google浏览器四、💖安装搜狗输入法五、💖安装C/C开发工具Clion🍀1.安装编译环境🍀2.安装开发环境一、💖更换镜像源 …

阿里工程师太凶残了,竟把服务器泡在“水里”!

万众瞩目的第11个双11要来了!这次天猫说要帮大家省500亿,身边加购物车、组队盖楼的同学数不胜数,热闹非凡。 但在阿里,有一位低调的“高冷男”,丝毫不为红红火火的双11所动,依然稳如磐石、淡定自若。 他的…

“我今年 31 岁,工作 7 年,明年退休...”

凌晨 1:30 的北京,商务楼静静地伫立着,街道上的车水马龙,慢慢地停歇了,只有他的工作台灯还没有休息,台灯忽明忽暗地坚持着。凌晨 2:00 的闹钟忍不住提醒他,电脑也偷偷跳出窗口:“主人&#xff0…

据说这是双11前互联网人的一天~

双11前,据说互联网人的一天是这样度过.... 6段故事,6个黑话关键词,生动刻画了双11前互联网人的一天! 上午9点,运营找老板汇报双11方案。 运营说:老板,本次营销方案你看需要一些预算资源支持&a…

快速入门docker容器

文章目录🌲1.拉取一个镜像🌲2. 在docker里启动一个镜像🌲3.查看所有的镜像列表🌲4.删除镜像🌲5.删除全部image镜像🌲6.运行tomcat🌲7.删除所有未运行的容器🌲8.以守护态运行容器&…

不会玩游戏的程序员不是好作家,《深入理解Java虚拟机》周志明来了!

嘉宾:周志明、杨福川采访、撰文:Satoh_AI这次采访起源来自于我和豆瓣的一位读者有同样的好奇心,为什么网上搜不到周志明老师的更多信息?为什么“80后玩家”可以把本本书都维持在9.0分左右?他的“社恐”到底有多严重?所…

当手机淘宝遇见折叠屏,让购物更随心

华为 5G 新品发布会上,Mate X 正式亮相,淘宝也作为重点展示应用出现在发布会的 PPT 上,同时也成为折叠屏生态联盟应用矩阵的第一位。 现场华为折叠屏上的淘宝多任务演示 伴随手淘技术团队对华为折叠屏适配工作的展开。半年前还只是概念方案的…

SpringBoot2.x 整合 Ueditor

文章目录一、基础准备1. 创建项目并引入依赖2. 下载Ueditor源码3. Java代码整合4. 静态文件整合二、静态页面控制层2.1. index.html2.2. demo1.html2.3. demo2.html2.4. demo3.html2.5. Controller三、配置调整3.1. 图片大小3.2. 修改ueditor.config.js3.3. 修改config.json文件…

无线路由攻击和WiFi密码破解实战[渗透技术]

文章目录一、准备阶段二、攻击阶段1.停止🛑网络管理员2.开启网卡监听模式3. 捕获数据包4.获取数据包5.注入数据包(DeAuth洪水攻击)5.WiFi密码破解一、准备阶段 攻击主机:kali Linux攻击工具:aircrack-ng、airodump-ng…

支付宝双11狂欢幕后的女程序员:服务全球12亿人,每天和不法分子打攻防战

再过3天,全球最大的购物狂欢节就开始了。 在这个睡不着的午夜,无数男男女女会在闪烁的屏幕前滑屏、抢购、享受秒级付款带来的快感。整个过程大脑分泌的多巴胺,又驱使他们以更快的速度重新填满购物车。 2018年天猫双11成交额2135亿元&#x…

技术直播:程序员副业的修炼指南!(限免报名)

面试造飞机,上班拧螺丝,每天想辞职,但无奈副业还“大器晚成”的样子!那可能是你还没有选对副业!滴滴 ~福利卡!!!CSDN学院邀请汤小洋老师开设技术直播课《程序员副业之路-三大终极秘籍…

轻松解决Android gradle太慢问题

夫陶公清风千古,余又何人,敢称庶几 一、解决方案 从网上下载对应版本的gradle,然后把gradle压缩包复制到C:\Users\liuxin\.gradle\wrapper\dists\gradle-6.5-all\2oz4ud9k3tuxjg84bbf55q0tn目录下,重新build工程就搞定了。 安卓开发者平台官…

持续交付体系在高德的实践历程

1. 前序 对于工程团队来说,构建一套具有可持续性的、多方面质量保证的交付体系建设,能够为业务价值的快速交付搭建起高速公路,也能为交付过程中的质量起到保驾护航的作用。本文为大家介绍持续交付体系在高德的演进与落地。 2. 持续交付 正…

RuoYi-Cloud 部署篇_01(windows环境 mysql +nginx版本)

文章目录一、基础准备1. 技术选型2. 源码克隆3. 安装依赖4. 将 RuoYi-Cloud 项目导入到 IDEA5. 安装启动Mysql6. 安装启动Redis7. 创建数据库,执行 SQL脚本文件二、安装与配置 nacos2.1. 下载nacos2.2. 安装 nacos2.3. nacos持久化配置2.4. 执行脚本文件2.5. nacos连…

趣头条基于 Flink 的实时平台建设实践

本文由趣头条实时平台负责人席建刚分享趣头条实时平台的建设,整理者叶里君。文章将从平台的架构、Flink 现状,Flink 应用以及未来计划四部分分享。 一.平台架构 1.Flink 应用时间线 首先是平台的架构,2018 年 3 月之前基本都是基…

我!程序猿!被银行套路了!

作者 | 程序猿石头责编 | Carol封图 | CSDN 付费下载自视觉中国话说,你肯定也经常收到各个银行电话推销,可以办理小额贷款/信用卡账单分期/万用金,或者其他乱七八糟的名字的产品。又或者接到电话说,“石头先生,我们有留…

巧妙地在Windows搭建node服务器

夫陶公清风千古,余又何人,敢称庶几 文章目录一、 安装node1. 官网下载node.js2. 测试npm是否成功安装3. 配置npm模块和缓存的存放路径4. 安装express5. 配置npm环境变量二、安装cnpm1.执行安装2. 配置cnpm环境变量一、 安装node 1. 官网下载node.js 官…

jdk8下载

文章目录1. 官网2. windows下载链接3. linux下载链接1. 官网 https://www.oracle.com/cn/java/technologies/javase/javase-jdk8-downloads.html 2. windows下载链接 https://download.oracle.com/otn/java/jdk/8u301-b09/d3c52aa6bfa54d3ca74e617f18309292/jdk-8u301-window…

测试工程师不懂AI,还有未来吗?

阿里妹导读:近几年人工智能、机器学习等词漫天遍地,似乎有一种无AI,无研发,无AI,无测试的感觉。有人说:不带上“智能”二字,都不好意思说自己是创新。我们先暂且不评论对错,只探讨这…

redis 下载、启动 windows环境

文章目录1. 下载2. 启动1. 下载 https://github.com/MicrosoftArchive/redis/releases 2. 启动 进入redis的bin目录双击redis-server.exe