经典永不过时!重温设计模式


导语:

在软工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案。这个术语是由埃里希·伽玛(Erich Gamma)等人在1990年代从建筑设计领域引入到计算机科学的,设计模式是针对软件设计中常见问题的工具箱,其中的工具就是各种经过实践验证的解决方案。即使你从未遇到过这些问题,了解模式仍然非常件有用,因为它能指导你如何使用面向对象的设计原则来解决各种问题。


大家好,我是Alex,今天谈一谈设计模式,一名优秀的开发,应该多少都需要了解一些常用的设计模式和使用场景,让我们一起来重温一下那些年经典设计模式;

本文主要内容


为什么要掌握设计模式

历史的教训

时间回到 20 世纪 80 年代,当时的软件行业正处于第二次软件危机中。根本原因是,随着软件规模和复杂度的快速增长,如何高效高质的构建和维护这样大规模的软件成为了一大难题。无论是开发何种软件产品,成本和时间都最重要的两个维度。较短的开发时间意味着可比竞争对手更早进入市场;较低的开发成本意味着能够留出更多营销资金,因此能更广泛地覆盖潜在客户。

设计模式是银弹吗?

代码复用是减少开发成本,减低复杂度最常用的方式之一,这个想法表面看起来很棒,但实际上要让已有代码在全新的上下文中工作,通常还是需要付出额外努力的。组件间紧密的耦合、对具体类而非接口的依赖和硬编码的行为都会降低代码的灵活性,使得复用这些代码变得更加困难。设计模式目标就是帮助软件提高内聚,减低耦‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍合,‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍使用设计模式是增加软件组件灵活性并使其易于复用的方式之一。

变化是程序员生命中唯一不变的事情,客户需求可能经常会变,紧急上线的版本,要不要下次重构一下,还是继续打各种补丁, 技术债会越积越多,因此在设计程序架构时,所有有经验的开发者会尽量选择支持未来任何可能变更的方式。可扩展性成为了程序设计必须要考虑指标,而设计模式是可以借鉴的,成熟的优化程序设计的解决方案;

总体来说,深刻理解设计模式会给我们带来很多好处:

  1. 可以和面试官"畅谈"设计模式相关问题.

  2. 很多开源软件框架大量使用了设计模式,比如Linux系统,Redis,Spring,C++STL等等,可以把帮你加快理解开源软件框架。

  3. 当你写的代码越来越优美后,你的代码鉴赏能力就会提高,对团队code review贡献也会更大,在个人影响力也会提高。

  4. 你不会再畏手畏脚,你的工具箱里面工具很多后,可以帮助你,应对各种大型项目的代码设计和开发。

  5. 每个领域都会一些成熟"套路", 编程也不例外,熟悉这些套路,可以更好方便交流和更快速地解决问题;

为了更好理解设计模式,我们首先要理解一些重要的设计原则,而不是片面理解设计模式哪些模式名词,要看清楚这背后的原理,这个才是最重要的。

代码设计原则

代码设计原则贯穿在整个设计模式之中,是理解其中的精华,本文讨论了一些重要的设计原则,包括通用设计原则,DRY原则,KISS原则,SOLID原则等:

通用设计原则

隔离变化

找到程序中的变化内容并将其与不变的内容区分开,该原则的主要目的是将变更造成的影响最小化。

面向接口编程

面向接口进行开发, 而不是面向实现;依赖于抽象类型,而不是具体类,要求接口标准化设计,只要对外的接口没有变,内部实现就可以任意变化,为以后留有更多优化空间,方便以后更新迭代,可以说这样的设计是灵活的。


组合优于继承

继承可能是类之间最明显、最简便的代码复用方式。如果你有两个代码相同的类, 就可以为它们创建一个通用的基类,然后将相似的代码移动到其中。但继承可能带来的问题:

  • 子类不能减少超类的接口。你必须实现父类中所有的抽象方法,即使它们没什么用。

  • 在重写方法时,你需要确保新行为与其基类中的版本兼容。这一点很重要,因为子类的所有对象都可能被传递给以超类对象为参数的任何代码,相信你不会希望这些代码崩溃的。

  • 继承打破了超类的封装,因为子类拥有访问父类内部详细内容的权限。此外还可能会有相反的情况出现,那就是程序员为了进一步扩展的方便而让超类知晓子类的内部详细内容。

  • 子类与超类紧密耦合。超类中的任何修改都可能会破坏子类的功能。

  • 通过继承复用代码可能导致平行继承体系的产生。继承通常仅发生在一个维度中。只要出现了两个以上的维度,你就必须创建数量巨大的类组合,从而使类层次结构膨胀到不可思议的程度。

组合是代替继承的一种方法。继承代表类之间的“是”关系(汽车是交通工具),而组合则代表“有”关系(汽车有一个引擎)。

DRY 原则

DRY-Don't Repeat Yourself(不要重复代码)

降低可管理单元的复杂度的基本策略是将系统分成多个部分。

理解这一原理是如此重要,它通常以首字母缩写词DRY来指代,并出现在Andy Hunt和Dave Thomas的书《实用程序员》中,但是这个概念本身已经有很长时间了。它指的是软件的最小部分。

当您构建一个大型软件项目时,通常会因整体复杂性而感到不知所措。人类不善于管理复杂性;他们擅长为特定范围的问题找到有创意的解决方案。降低可管理单元的复杂性的基本策略是将系统分成更方便的部分。首先,您可能希望将系统分为多个组件,其中每个组件代表其自己的子系统,其中包含完成特定功能所需的一切。

KISS 原则

KISS是使它保持简单,愚蠢的首字母缩写,是美国海军在1960年提出的设计原则。KISS原则指出,大多数系统如果保持简单而不是变得复杂,则效果最佳。因此,简单性应该是设计的主要目标,并且应该避免不必要的复杂性。

SOLID 原则

SOLID 原则是在罗伯特·马丁的著作《敏捷软件开发:原则、模式与实践》中首次提出的,SOLID 是让软件设计更易于理解、更加灵活和更易于维护的五个原则的简称。

尽量让每个类或者函数只负责软件中的一个功能,这条原则的主要目的是减少复杂度,你不需要费尽心机地去构思如何仅用200 行代码来实现复杂设计,实际上完全可以使用十几个清晰的方法,这里核心是: 通过实现最基本"原子函数", 其他复杂功能都可以通过这些原子函数构建,每一层的函数语义都是单一的,通过层层封装,最终构建一个庞大可控的系统。

 

本原则的主要理念是在实现新功能时能保持已有代码不变,为什么呢,主要是修改存量代码,很可能会影响软件稳定性,很多线上代码跑了好多年了,经历很多轮迭代,各种补丁,如果考虑不全面,很容易带来风险,下图比较形象说明:

替换原则是用于预测子类是否与代码兼容,以及是否能与其超类对象协作的一组检查。这一概念在开发程序库和框架时非常重要, 因为其中的类将会在他人的代码中使用——你是无法直接访问和修改这些代码的。里氏替换原则的重点在不影响原功能。

根据接口隔离原则,你必须将“臃肿”的方法拆分为多个颗粒度更小的具体方法。客户端必须仅实现其实际需要的方法。否则,对于“臃肿”接口的修改可能会导致程序出错,即使客户端根本没有使用修改后的方法。

通常在设计软件时,你可以辨别出不同层次的类。

• 低层次的类实现基础操作(例如磁盘操作、传输网络数据和连接数据库等)。

• 高层次类包含复杂业务逻辑以指导低层次类执行特定操作。

经典设计模式

这里列举了22种设计模式,大致分为三类:创建型模式,结构型模式,行为模式

创建型模式提供创建对象的机制,增加已有代码的灵活性和可复用性

结构型模式介绍如何将对象和类组装成较大的结构,并同时保持结构的灵活和高效:

行为模式负责对象间的高效沟通和职责委派:

推荐一个经典学习网站:

https://refactoring.guru

上面每种模式配有形象图,比如工厂方法模式:

 

还提供对应的设计类图:

也提供了对应代码示例:

支持9种语言的实现:

    代码在:https://github.com/RefactoringGuru

推荐给大家,拿走别谢

更多请参考:

《设计模式:可复用面向对象软件的基础》

  https://refactoring.guru

Linux经典设计模式

内核面向对象设计模式

Linux虽然是面向过程的c语言写成的,但是却可以表达面向对象的思想,Linux内核大量使用面向对象的编码风格,我们可以从中至少学习到两点:

  • 说明在大型软件开发中,OOP编程思想很重要,和具体语言无关;

  • 同时展示了怎么用c语言实现OOP编程,值得广大C语言开发者学习。

我们用例子来说明。

封装

以内核proto定义为例:

struct proto 定义传输层接口方法和相应成员数据,类似C++的class定义;可以根据这个class生产很多实例,比如TCP实例,可以通过统一接口访问TCP实例的方法和数据。

继承

以内核套接字体系为例:

基于此继承体系,对于一些接受 struct sock* 形参的接口,就可以直接把上述的子类套接字实例 struct udp_sock* sk作为实参传进去(当然,这里需要指针强转一次(struct sock*)sk)。这里就是OOP中“is a"的public继承关系,子类对象可以直接作为父类对象使用,并且这种实现只支持单继承。

多态

用C实现多态需要自己维护继承关系中的虚函数体系,C++有编译器自动生成、维护vtbl与vptr。Linux内核的实现中,将系列函数指针放入结构体,即视其为“虚函数”,亦或是专门定义一个xxx_ops结构,里面放上一堆函数指针,作为“虚函数表”。仍以套接字体系为例,在基类 sock 中,有协议结构体指针 struct proto *skc_prot; 这个proto即可大体上视为一个虚函数表vtbl,内有具体协议的函数指针,而这个skc_prot指针,即可视为虚指针vptr。

在套接字创建时,根据参数中的协议族、协议类型、协议号信息,调用协议族的create函数执行创建,绑定具体协议proto指针到该vptr上,自此实现了静态类型到动态类型的绑定。之后,当调用虚函数时,即可直接通过这些函数指针进行多态的调用 , 比如下面例子socket调用connect接口:

这里第一个参数sk即可看做this指针,不同socket对象,会访问对应协议接口,从而实现多态访问:


list 设计模式

list作为常用数据结构,写代码时候经常会遇到,可以看一下传统list设计和内核list设计有什么不一样。

一般的双向链表一般是如下的结构:

  • 有个单独的头结点(head)

  • 每个节点(node)除了包含必要的数据之外,还有2个指针(pre,next)

  • pre指针指向前一个节点(node),next指针指向后一个节点(node)

  • 头结点(head)的pre指针指向链表的最后一个节点

  • 最后一个节点的next指针指向头结点(head)

传统list如下图:

传统的链表不同node类型,需要重新定义结构,不够通用化,还需要为node实现脱链、入链操作等。

我们需要抽象出一个“基类”来实现链表的功能,其他数据结构只需要简单的继承这个链表类就可以了。

内核list设计如下:

  • 链表不是将用户数据保存在链表节点中,而是将链表节点保存在用户数据中

  • 链表节点只有2个指针(prev和next)

  • prev指针指向前一个节点的链表节点,next指针指向后一个节点(node)的链表节点

‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

如下图:

这样设计的好处是链表的节点将独立于用户数据之外,便于把链表的操作独立出来,和具体数据节点无关,这里可能有些人会问,数据节点怎么访问呢?  内核通过一个container_of的宏从链表节点找到数据节点起始地址:

找到数据节点起始地址后,通过数据节点定义就可以访问数据了,内核红黑树rbtree也是同样的设计。

设备驱动框架设计模式

 

从Linux2.6开始Linux加入了一套驱动管理和注册机制—platform平台总线驱动模型:

当调用platform_device_register(或platform_driver_register)注册platform_device(或platform_driver)时,首先会将其加入platform总线上,依次匹配platform总线上的platform_driver(或platform_device),然后调用platform_driver的.probe函数。其中platform_device存放设备资源(硬件息息相关代码,易变动),platform_driver则使用资源(比较稳定的代码),这样当改动硬件资源时,我们的上层使用资源的代码部分几乎可以不用去改动。

这里设计通过中间bus层,把强耦合Device和对应Driver进行了解耦隔离,定好match,probe等标准通信接口,就可以独立开发,通过总线bus进行关联通信,有点类似中介模式。

C++ Idioms(设计习语)

由于篇幅优先,这里列举一些非常重要且非常实用的C++专有的设计模式。

RAII-Resource Acquisition Is Initialization

‘资源获取即初始化‘(简称 RAII)是C++防止内存泄露一个很好解决方案,它结合构造函数和析构函数,把资源生命周期和对象生命周期绑定起来,在构造函数中获取资源(这些错误会引发异常),然后将其释放到析构函数中(永不抛出),并且不需要显式清理,从而防止忘记释放资源;

 

C ++STL库很多类遵循RAII设计原则,比如std :: string,std :: vector,std :: thread等。


Policy-based class Design

基于策略设计又名policy-based class design 是一种基于C++计算机程序设计模式,以策略(Policy)为基础,并结合C++的模板元编程。就是将原本复杂的系统,拆解成多个独立运作的“策略类别”,每一组policy class都只负责单纯如行为或结构的某一方面。多重继承由于继承自多组 Base Class,故缺乏型别消息,而Templetes基于型别,拥有丰富的型别消息。多重继承容易扩张,而Templetes的特化不容易扩张。Policy-Based Class Design 同时使用了 Template 以及 Multiple Inheritance 两项技术,结合两者的优点,看下面例子:

ResourceManager则称为宿主类别(host class),只需要切换不同 Policy Class(ReadPolicy or WritePolicy),就可以得到不同的功能实体。Policy不一定要被宿主继承,只需要用委托完成这一工作。但policies必须遵守一个隐含的constraint,接口必须一样,故参数不能有巨大改变,policy 的一个重要的特征是,宿主类别经常(并不一定要)使用多重继承的机制去使用多个 policy classes.  因此在进行 policy 拆解时,必须要尽可能达成正交分解,policy之间最好彼此独立运作,不相互影响。

Pimpl - Pointer to implementation

Pimpl是一种广泛使用的削减编译依赖项的技术, 看下面例子可能就明白了:

  

因为Widget的成员变量有std::string,std::vector和Gadget,那么这些类型的头文件在Widget编译时必须出现,这意味Widget的用户必须包含“gadget.h”。这些增加的头文件会增加Widget用户的编译时间,而且这使得用户依赖于这些头文件,即如果某个头文件的内容被改变了,Widget的用户就要重新编译。标准库头文件不会经常改变,但是“gadget.h”可能会经常修改。所以需要Pimp技术来消除这种变化影响--隔离变化;

 

这样Widget头文件里面就不需要包含“gadget.h”文件了,再CPP文件中再声明具体的类型:

  

在这里,我展示了“#include”指令,只为了说明所有对头文件的依赖(即std::string,std::vector和Gadget)依然存在。不过呢,依赖已经从“widget.h”(Widget用户可见的和使用的)转移到“widget.cpp”(只有Widget的实现者‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍才能看见和使用),这样就把widget头文件变化影响隔离在内部实现中,对外接口不变,这里就体会到这种设计模‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍式的好处。

CRTP -The curiously recurring template pattern 

CRTP (奇异递归模板模式)是一种在编译期实现多态方法,是对运行时多态一种优化,多态是个很好的特性,但是动态绑定比较慢,因为要查虚函数表。而使用 CRTP,完全消除了动态绑定,降低了继承带来的虚函数表查询开销。

CRTP包含:

  • 从模板类继承,

  • 使用派生类本身作为基类的模板参数。‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

 

这样做的目的是在基类中使用派生类。从基础对象的角度来看,派生对象本身就是对象,但是是向下转换的对象。因此,基类可以通过将static_cast自身放入派生类来访问派生类。

总结

为什么要掌握设计模式,软件危机带来刚性要求,设计模式提倡的高内聚,低耦合,代码复用,可扩展性等思想,可以给我们软件设计带来一些思考,有了思考,就会产生一些积极变化;

理解设计模式前提,是要理解背后的设计原则,这是整个设计模式的精华;

经典的设计模式包含22种设计模式(没有解释器模式,日常开发中,很少使用),大致分为三类:创建型模式,结构型模式,行为模式;

Linux系统里面包含大量设计模式思想,面向对象设计,List/Rbtree抽象设计,驱动框架bus总线解耦设计,都值得我们学习;

每种编程语言都会有一些独特特殊习惯用法,Java的MVC,Golang的对象池模式(Object Pool)等,文中列举的C++一些常见的惯用法RAII,Policy-based Design ,Pimpl,CRTP等,对C++开发来说,了解和掌握他们,对于特定场景问题多了一些好的解决方案;

设计模式是银弹吗?不是,就像软件工程也不是银弹一样,这些都只是工具,关键还是看是否真正理解其背后反射出的设计精髓,我们需要多一些批判性的思考,没有绝对好坏,软件设计的最终方案很多时候都是权衡(trade-off)结果,但我们的长期目标始终没有变化。

‍‍‍‍‍‍‍‍‍‍‍‍

更多精彩推荐
☞三个月前被 K8S 弃用,Docker 火了!获 2300 万美元融资☞一招上手!这样设计扛住亿级流量活动系统☞Kubernetes 稳定性保障手册(极简版)
点分享点收藏点点赞点在看

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

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

相关文章

抖音实战~项目关联UniCloud

文章目录一、云存储1. 登录UniCloud2. 创建服务空间3. 详情查看二、项目关联UniCloud2.1. 创建云开发环境2.2. 关联云服务空间2.3. 效果验证一、云存储 1. 登录UniCloud 链接:https://unicloud.dcloud.net.cn/login 云存储空间:https://unicloud.dcl…

Flutter+FaaS一体化任务编排的思考与设计

作者:闲鱼技术-古风 FlutterServerless三端一体研发架构,客户端不仅仅是编写双端的代码,而是扩展了客户端的工作边界,形成完整的业务闭环。在新的研发模式落地与实践的过程中,一直在思考如何提高FaaS端研发体验与研发…

抖音实战~实现App端视频上传、发布、落库

文章目录一、API阅读1. 选择或拍摄视频2. 云函数API~文件上传3. 视频截帧二、App端视频上传流程2.1. 上传流程图2.2. 流程简述三、前端源码实战3.1. 选择/拍摄短视频3.2. 短视频上传3.3. 进度条页面3.4. 补充短视频内容3.5. 视频发布3.6. 视频预览四、后端源码实战4.1. 短视频发…

从微服务到 Serverless | 开源只是开始,终态远没有到来

开源只是开始,终态远没有到来。 从微服务开源,到 Serverless 开源,我们正持续将阿里沉淀的技术能力进行开放。 只是这一次不同的地方在于,借助 Serverless 能力的释放,将帮助前端进入一个崭新的时代,只需…

从Python到AI,这条路好走吗?

大家都在学Python的时候,怎么才能让自己更有竞争力?Python 的应用方向有很多,基本每个方向都是大热门,但至今为止,人工智能行业仍处于人才稀缺的情况。正因这样,近几年来,AI 成为了广大 Python …

Flutter瀑布流及通用列表解决方案

作者:闲鱼技术-夜澜 背景 目前闲鱼业务中无论是首页还是搜索页都有大量可以落地瀑布流的场景,而在Flutter原生中只提供了ListView, GridView,无法提供自定义布局的能力。 而在社区中,一般瀑布流的解决方案都是基于SliverMultiB…

闲鱼的商品结构化是如何演进的(超详细)

作者:闲鱼技术-吴白 引言 商品的信息结构化程度在某种意义上来说决定导购效率的天花板。闲鱼商品结构化和淘宝/天猫最大的区别在于闲鱼卖家都是个人用户,无论是专业程度还是行动力远不及淘宝卖家。为了不阻碍商品发布,闲鱼一直倡导轻发布&a…

一文看懂5G射频的“黑科技”

作者 | 小枣君来源 | 鲜枣课堂(ID:xzclasscom)手机,作为移动互联网时代的标配,已经走进了我们每个人的生活。有了它,我们可以随心所欲地聊天、购物、追剧,享受美好的人生。正因为手机如此重要&a…

抖音实战~首页视频~下拉刷新

文章目录1. 配置下拉刷新2. 下拉刷新监听3. tab监听索引4. 控制台监控5. 父子组件调用6. 效果图1. 配置下拉刷新 在pages.json配置文件中添加如下配置: "enablePullDownRefresh":true //开启下拉刷新2. 下拉刷新监听 // 当前页下拉刷新onPullDownRefre…

支付宝研究员王益的建议:“学好语文,才能写好代码”

王益,蚂蚁集团研究员,开源项目SQLFlow 和 ElasticDL 的负责人。他从10岁开始写代码。曾经用自己焊接的电路板扩展“中华学习机”来把自家的老式“威力牌”双筒洗衣机改造成了自动洗衣机;用Apple BASIC语言和6502汇编混合编程写了人生中第一个…

抖音实战~搜索页面~视频详情

文章目录一、前端部分1. 检索关键词短视频列表2. 选中某一个短视频3. 短视频详情二、后端部分2.1. 短视频入口2.2. 短视频接口层2.3. 短视频服务层2.4. 持久层-接口2.5. 持久层- xml三、效果图鉴赏3.1. 搜索页面3.2. 短视频列表3.3. 短视频详情一、前端部分 1. 检索关键词短视…

技术人的灵魂 3 问,阿里工程师如何解答?

作者 | 氐宿 阿里云高级前端技术专家 导读:在业务团队做事的工程师摸爬滚打了一段时间后,一定会有所疑问。团队同学在最初的一段时间都提出这样的疑惑:如何在业务中发现有技术价值的问题?发现问题后如何思考和发起再到解决&…

10+知识图谱开放下载,让你的学习效率提升5倍! | “右脑”开发套餐

简介: 为了让广大开发者清晰了解技术体系,打造属于自己的系统学习路径。今天,开发者社区整理了10知识图谱,供大家交流学习,持续更新中~ 知识的学习从来就不是孤立的,学习任何知识(概念、定义、…

抖音实战~分享模块~短视频下载(保存到相册)

文章目录一、可见范围1. 自己发布短视频2. 其他人发布短视频二、源码分析2.1. 底部窗口popup2.2. 实现组件uni-popup 弹出层2.3. 插件涉及组件2.4. 组件改造2.5. 关键的api三、作品鉴赏3.1. 自己发布视频3.2. 其他人发布视频3.3. 保存短视频一、可见范围 保存到相册、复制链接、…

HDC.Cloud 2021剧透:六大创新产品、开发者年度盛宴即将开启

编辑 | 宋慧 出品 | CSDN云计算 头图来源 | HDC.Cloud官网 今日,华为开发者大会2021(Cloud)(简称HDC.Cloud 2021)媒体预沟通会在京召开,华为技术有限公司高级副总裁、云与计算BG副总裁张顺茂在会上表示&am…

抖音实战~分享模块~复制短视频链接

文章目录一、可见范围1. 自己发布短视频2. 其他人发布短视频二、源码分析2.1. 底部窗口popup2.2. 实现组件uni-popup 弹出层2.3. 插件涉及组件2.4. 组件改造2.5. 关键的api三、作品鉴赏3.1. 自己发布视频3.2. 复制链接一、可见范围 保存到相册、复制链接、二维码 都是前端完成的…

莉莉丝《剑与远征》:基于阿里云全站加速提升用户体验

公司介绍 莉莉丝游戏致力为全球玩家创造好玩的游戏,坚持“全球化”与“品类进化”核心战略,通过对全球市场与品类发展阶段的深度理解,将国产手游带向了世界,代表作:《小冰冰传奇》,《万国觉醒》&#xff0c…

亚马逊云科技首次发布“三驾马车”中国业务战略

2021年3月25日,亚马逊云科技今天在北京举行媒体沟通会,首次正式发布“三驾马车,齐头并进”的中国业务战略。通过亚马逊云科技独一无二的全球优势,发挥亚马逊全球业务体系的强大支撑,并利用亚马逊的创新文化和方略&…

KubeCon 2020 阿里云推出四大企业级容器新品 ,详解云原生操作系统进化

导读:云原生操作系统进化,详解阿里云 ACK Pro、ASM、ACR EE、ACKEdge 等四款企业级容器新品。 KubeCon 2020 中国站,阿里云容器服务负责人易立会在《云原生,数字经济技术创新基石》的演讲中,分享阿里云原生如何助力数字…

抖音实战~分享模块~生成短视频二维码

文章目录一、可见范围1. 自己发布短视频2. 其他人发布短视频二、源码分析2.1. 底部窗口popup2.2. 实现组件uQRCode2.3. 插件涉及组件2.4. 组件改造2.5. 实现原理三、作品鉴赏3.1. 生成短视频二维码3.2. 微信扫描3.3. 抖音扫描一、可见范围 保存到相册、复制链接、二维码 都是前…