(1)架构为什么需要演进
(2)他们是怎么演进的
(3)带来的好处
3、Google搜索关键字:架构设计
(1)知识概要
(2)个人小结
作为一只编程经验并不怎么丰富的程序猿来讲,我一直觉得架构师是一个比较神秘的职业,架构设计就更加的高大上了。经过今年的几个项目,之前曾发文叙述我的从MVC到MVP项目重构实战经验,也曾说过我准备对目前手底下的项目进行重构。但是,前段时间,我改变了我的想法。
开发模式的重构,仅仅只是换了一个套路,也许在重构的过程中对业务的逻辑进行了一次梳理,也是在基于前人的代码设计上进行了一些优化。但是,这远远还不够,这不是我理想中的开发场景。
在项目开发的过程中,也发现存在许多的问题,但是都是一些零散的问题,我很多时候希望能够改变现状,更加优雅地编程,然后实际的情况却是陷入了迭代功能开发和bug修复的死循环。现在回过头来想想,我理想中应该是开发应该是一种由规划和设计指导的开发,那么架构设计就显的尤为重要了。
仅看完了《架构之美》的第一部分:论架构,对架构有了一个大概的认识。下图是这部分的知识点概要:
书中很受启发的概念:
这里仅仅通过Google搜索各个app在架构演进方面的一些文章,从中分析他们为什么要演进?怎么演进?带来了哪些好处? 简单的整理如下:
搜索引擎对于我们来说是最棒的学习工具,我通过搜索架构设计等关键字,阅读了一些文章,并仔细研读Keegan小钢的博客文章《小钢的架构思考》系列。这几篇文章在发表之初曾阅读过,但是当时并不怎么理解,大概是对架构还没有一个大概的认识。在请教一位前辈的时候,他和说了对架构的一个理解,并再次推荐了这几篇文章。所以我再次阅读了好几遍。下图是文中关于架构设计的知识概要。
架构分为三个阶段:规划、设计、构建,每个阶段架构的设计有不同职能。在规划阶段,考虑的是产品的需求、质量的需求,技术的可行性分析以及预研。在设计阶段,考虑的如果将一个复杂的系统拆分,并设计如何进行组织这些拆分的模块。在构建阶段,考虑的就是具体的实施问题,并且要保证一定的伸缩扩展性,因为架构是不断演进的。文中引用了《软件架构设计》一书的一个模型图,我觉得有必要在此贴出来。最近也在思考软件模块化的设计,模块化的设计也许各有理解,在此先不做讨论。如下图:
这张图我起初理解不是很透彻,我曾尝试自己去画一些图来表达我的一些想法。但是,当我再次回过头看到这张图的时候,才恍然大悟。 架构的设计可以从两个维度来考虑,一是架构思维,二是架构原则。思维是我们的思考方式,是我们解决问题的方法。原则是我们思考问题的方向,是我们解决问题的一些标准。
对于架构的定义,业界都各有看法,也曾微信私信请教过一些行业内有丰富经验的前辈。《软件架构设计》一书则将架构定义总结为组成派和决策派:
keegan小钢在《小钢的架构思考:什么是架构》文中提到:软件架构是规划、设计和构建软件的过程和结果。《架构之美》一书在1.1.3架构的含义中提出:架构说明了设计和构建一个系统所使用的结构。《Software Architecture in Practice,Second Edition》中提出:一个程序或计算机的软件架构是系统的一种结构或一组结构,它包含软件元素、这些元素的外部可见的属性,以及元素之间的关系。
本人并没有经历过大型的软件系统,做过的也只是移动端App的开发,所以个人也只敢从移动端app的架构设计出发,给出我一个狭义的理解。我认为,移动端的app架构是一种基于产品和技术的进行统筹管理最终所形成的共识。可能大部分的app开发尤其是小团队app的开发大多是由产品驱动的开发,需求来了,那就技术实现。需求变了,那就改。毕竟,应用层的开发是对业务负责的,必须保证正常的发布。所以大多数的情况下,程序猿不得不在产品经理面前妥协,这样对于开发人员的工作就会变的很被动。所以,就出现了程序猿和产品狗的撕逼笑谈。这种现象的原因在于项目各个相关利益人员没有对产品和技术达成共识,这正是移动端架构设计所要解决的问题。
产品,是我们产品经理们设计的结果,也是开发人员开发的最终成果,是前后两种人群的共同目标。作为软件的架构设计者应该充分理解产品的设计理念,除了明白已经设计的功能业务,还得具有一定的预见,掌握产品的发展趋势。下面主要从开发的角度来谈一谈产品。
作为一名开发人员,我不能很专业的来谈产品的设计,但是这里我还是希望以一个开发人员的角度来讲产品设计。什么是产品设计,我觉得可以从以下几个方面来思考。
顾名思义,我们设计开发出来的产品最终是让人用的。所以首先我们得定位产品的用户是谁?用户群体代表了我们产品的市场。所以产品做的好不好,最终市场说了算,用户说了算。离开了用户,不理解用户,不注重用户的体验,一切都是无用功。
你知道你最每天累死累活一行一行敲出来的是什么样的产品吗?可能对于我们开发人员很容易陷入到一个版本一个版本的迭代当中,这些永无止境的工作叫人忘记了思考,忘记了问下产品人员,我们最终是要做的什么?一年后我们的产品将是个什么样的状态,我们的最终愿景是什么?我们将会怎么一步步去实现我们最终的愿景?可能你会说,这些和我开发有什么关系。接到需求,我把他开发出来实现不就ok了。然而,在我们的小组里不乏有这些怨言,产品人员不断的修改,我TM代码改过来改过去。我们的leader在这方面很强调我们开发人员应该拥有自己的主动权,可以反驳产品不合理的设计。但是,前提是你至少理解产品的核心理念,我们最终要做什么。
对于一个产品,用户的需求是很多的,而且随着时间不断改变的。需求可以分两种,一种是人性本能的需求,还有一种,是我们的产品催生的需求。这两种需求都是合理的,也正是我们需要满足用户的。对于各式各样的需求我们怎么有计划的去实现呢?在敏捷开发中,我们将这些需求放到一个“需求池”中,然后进行计划安排在不同版本的迭代中。这个工作,不仅是产品人员去决定,开发人员也应该起一定的决策作用。产品人员需要从产品的角度去考虑,开发人员需要从技术实现的角度去考虑,最终的计划应该是两者的共同决策。特别注意的是,根据产品的特性,技术人员也应该提出技术方面的需求。合理的迭代计划可以保证正常的开发节奏,完成迭代目标。
在《人件》一书中提到了软件开发中人的因素很重要,合理配置开发团队是非常重要的。一个App的开发团队至少需要5个角色,即产品、交互、UI、软件、测试。不同角色也分不同的层次,比如软件分初级、中级、高级。不同角色、不同层次合理搭配,才能够获得更高的工作效率,保证产品开发顺利进行。
产品最终呈现给用户的是数据,数据分两种。一种是私有的数据,是由开发商自己生产的数据。一种是平台自生的数据,是由用户生产的。如果是自己生产的数据,就得考虑数据来源,数据的覆盖率,数据的准确性,合法性等。如果是用户生产数据,就得考虑用户生产数据的动力、入口以及数据安全性、传播性等。
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
万事俱备,只欠东风。完成一款app开发,需要一支专业的开发团队,这里的人力成本也是很高的。当然我这里只谈开发的预算,至于运营就不说了。我们得考虑,开发周期多长、需要多少人、后期维护怎么办。比如一个APP需要5个人开发,2个月的时间,开发两个版本,按照每人1W的工资来计算的话,也需要 10W。这估计是最低级别的算法了。所以,如果是创业公司,我们在组建开发团队的时候,也得看看预算是多少,多少钱能办多大事,当然如果是那些拿到投资无所谓的老板来时得另算了,不过今年死的太多的公司以前都是大手笔。钱烧完了,也就没有了。如果是大公司,可能不带这么抠门的。不过也应该去考虑,开发团队会消耗公司多少资源,我们能否获得相应或者更高的产出。
目前的开发而言,很多资源是可以寻找第三方合作的。比如,服务器、云存储、支付接口、登录接口、内容数据以及开发过程中的一些开源框架等等。我们需要选择、商务谈判直到集成到自己的APP中。
现在对于我们来说,用户体验是一个说烂了的词。那是因为,用户体验真的很重要,决定了一个产品的成败。产品开发完成后,最终到达用户的手中。产品好不好,用户说了算。哪些因素影响到用户体验呢?我想大概可以从5个角色各自的职责出发来看,产品的设计是否直达用户痛点?交互是否符合人的喜好、习惯,UI是否让用户觉得舒适?软件的性能好不好?软件的缺陷是否多不多?
从技术的角度来讲,我们可以通过软件的性能来分析一个软件产品的质量。今年许多的技术文章都在谈性能优化,软件的性能主要从软件的启动速度、流畅度、内存、功耗、流量、apk体积等几个方面来评判。如果想做好一个应用,性能优化应该纳入到日常的开发中持续进行。具体如何优化,这里就不再多说了。
产品的安全性可以从两个角度来看,产品的生产商和产品的最终用户。对于生产商而言,有许多的内容是需要受到法律保护的,有许多的敏感信息,核心技术、网络接口等是不可以泄露的。对于用户而言,我们肯定在本地或者服务器存储了大量的用户信息,比如账号密码,一些信息一旦泄露将严重伤害到用户的个人利益。所以,为了保护自己以及用户利益,我们必须要生产一个安全可靠的产品。那么对于一个应用端的开发者而言,我们的编译出的apk最终会到用户手中。所以,我们需要通过代码混淆、数据加密、权限限制等一些技术手段来保护我们的应用。
一个应用做的好不好,我认为可以主要从上述用户体验、软件性能、产品安全三个维度来进行评判。那么,我们该如何组织这些评判工作呢?我们有在进行这些工作吗?就目前而言,我相信大多数的产品、开发、测试人员都或多或少的参与到这些工作当中,但是也许没有将一些数据量化、没有系统的组织这些工作。目前大部分的应用都集成了行为采集,产品的下载量、用户的活跃度等也都是体现产品用户体验的主要参数。开发团队内部一直在进行性能优化的工作,比如异常修复、bug修复、内容泄露,过度绘制,apk瘦身。我们也进行了代码混淆、数据加密、apk签名加密的工作。但是,你知道你的产品质量如何吗?相比同类产品来,你哪些做的好,哪些做的不好吗?所以,我觉得将上述这些零碎的工作有系统的组织起来,将一些影响因素进行量化,让我们更加清楚的了解我们的产品质量是一件非常有意义的事情。
人是善变的,尤其对于IT来说,人员的流动就更加的频繁了,公司内部的调整,员工跳槽等等。所以,对于一直开发团队,必须要考虑到人员变动的风险。如果,某某不在了,项目是否可以正常运行。开发团队之间是否能够交叉熟悉各自之间的业务。
是否经历过一个项目做到一大半业务被停掉了的情况?而这个时候,你做的是个半吊子。如果出现了这种情况,我们该怎么办?假设就在刚才你的老板说你现在的项目不做了,那么如何才能最大程度的挽回损失?如何进行项目的收尾工作?而不至于在项目又突然重启的时候接收的是一个烂摊子。
我们在项目开发的时候会进行评审,然后按照迭代计划开发,但是在开发过程中一定会有许多问题影响我们的预期,比如需求变动、技术难题等等。项目延期在软件项目的开发中是普遍存在的问题,对于某些迭代而言,可能并不对整个项目造成重大影响,但是这个问题是一定需要考虑的。并且,我们应该严格的掌控项目的进度,平衡这些问题,保证能够按时交付产品。
我们应该随时能够提供一个稳定的版本,这是我们的leader所要求的。软件的缺陷存在是正常的,我们不停的写bug,也在不停的修改bug,对于那些隐藏很深的bug也许没有让测试测出来,最后流通到用户的手中,这个时候我们如何完成紧急修复?如何快速响应能给到用户一个稳定可靠的版本。这些是我们需要考虑的,任何时候,都应该有PlanB。
前段时间,公司内由于操作失误,上架更新一个apk的时候不小心发错了机型,导致使用该机型的用户升级后程序无法使用。然后,由于这个机型缺少维护,找不到代码,仅仅只能找到一个apk文件,然后只能考虑反编译升级等等。我想,类似于这类的人为失误还有很多,比如代码提交错误,集成路径出错等等。人总有一不小心的时候,所以,我们在设计的时候,应该将这些因素考虑进去,如何在出现失误的时候主动警告,如何在用户错误已经发生的时候启动紧急方案,将不良影响降到最低。
在敏捷迭代开发中,我们基本上能够一周提交两个测试版本。我们开发一部分、修复一部分,都可以提交一个可测试的版本,这样可以最大程度的降低开发风险,有利于软件的稳定性。
如果你产品的用户量够大,这个时候发布新的版本就得慎重考虑,用户才是你的产品的检验员。目前基本都是使用灰度发布的策略,先给少量的用户发布,看看用户的反馈,而后逐步发布给所有用户。
我们在开发过程中有许多的版本,也有很多分法。如debug和release版本,有的时候还需要给内容提供测试数据的data版本,还有的时候上一个版本还没有正式发布我们就需要开发下一个版本的功能。我们如何去管理各个版本的代码以及如何通过版本名来区分这些版本?我们需要制定一定的管理规范,并且这一规范是否在开发团队中达成共识,就显得非常重要。
前面啰嗦了很多,终于写到这里了。对于一个开发人员来说,怎么做才是我们的关键问题所在。只会Android开发,所以以下只讨论Android。我主要从以下几个方面来谈一谈怎么做这个问题。
移动端的开发目前主要是两大阵营Android、IOS,其他的就不多说了。
Java、Kotin、Grovvy、SQL等等;
MVC、MVP、MVVM、clean等,各有优缺点,在此不做详细说明;
都说了不要重复造轮子,因为你造的轮子不一定不人家的好用,对于我们开发者而言,有一件非常好的事情就是我们有太多的开源免费的第三方库供我们使用,这样给我们省去了大量的工作,做到更加高效的开发。但是,如何选择,是否引入使我们需要考虑的一个问题。下面列出一些常用的第三方库,更多请点击。
软件开发而言,新技术的发展相当迅速,然而我们实际落地到项目中却需要很长的时间,因为新的技术刚出来一是需要学习成本,二是需要承担新技术不够成熟,存在缺陷带来的一些风险。当然,我们应该积极的引入好的新的东西,跟得上时代的步伐才好。下面列举的一些也许都算不上新的东西,但是也是近年来大家所追捧的新技术。
我们在进行业务拆分的时候,我认为可以将业务分成三类:
基础业务主要是我们的app的一些基础功能,像我们公司有BFC团队给我们开发了文件上传下载、网络请求、行为采集、账号系统等SDK,免除我们一些重复的劳动工作。怎么去定义什么业务才是基础业务呢?我觉得可以这么去区分。如果你的业务在行业普通的应用app都有需要,那么这些这些就是具有普遍适用性的基础业务。我们根据不同的功能进行拆分。
通用技术业务我觉得是和自己app相关并且有技术性很强的业务,可能是你应用的核心技术部分,比如美颜这一类软件的图片处理,小猿搜题这类的图片识别等就是一项通用技术型业务。通用技术业务的特点就是在和你同一类的app都会有需要使用的技术,我们可以根据不同的技术领域进行拆分。
特定功能业务就是属于你自己app的特定功能了,一般可以按照功能进行拆分成不同模块。比如说我目前的一键搜(类似于小猿搜题)主要有搜题、查单词、翻译三大功能。那么就可以分拆为三大块。搜题要经过拍照、框题、图片处理、网络请求等步骤,每个步骤都可以看成一块小业务,以此进行拆分。特定功能业务大部分仅适用于你自身的APP。
以上的说法仅从自身的经验出发来进行描述,在我们实际的开发中可能会有一些特殊情况,或者有不同的拆分分方法。总之,业务的拆分还需要根据实际情况来。
世上本没有架构,关注点一分离就有了架构,我们将一个软件系统的开发从多个维度将我们的工作进行拆分,对于每个领域进行设计,将各个领域有系统的组织起来,这种组织结构就是架构。然而如何将一个复杂的系统将关注点进行合理的分离,这个是非常有挑战的。
抽象,这是在请教一位前辈时最后给我强调的一点。如果你对app是跟着交互走、一个页面一个页面写的,那么很显然,你没有对你的业务进行抽象,而只是在实现。作为java的设计思想也很强调抽象的概念。那抽象到底是什么呢?抽象就是你要做什么!更简单的理解就是,写interface而不是class。不知道大家有没有这样的经历,在我们的MVP的开发当中,我们有个Model,也有一个IModel,但是我们写完了Model才知道怎么写IModel,最后成了粘贴复制的体力劳动。如果你是这么做的,你可以自己思考下,假如我们先写是IModel,而不是Model,那就是怎么样的体验呢?这就是将你的业务进行抽象。在架构的设计当中,你只需要知道你要做些什么?而不需要去过多的关注你具体怎么去实现它,这才是设计。
众所周知,在C语言的开发中,我们的逻辑大多是根据任务的流程走。这是面向过程的典型例子。面向过程关注的是工作的流程、一步一步的完成任务。
Java语言作为面向对象开发的典型代表,这是我们所熟知的。我们将计算机按照人的思维来进行设计,每一个对象都持有自己的属性,并且持有自己的操作方法。对象之间有继承,组合等关系,通过组织这些关系来完成我们的程序。就像社会的人和物一样,人与人之间各种复杂的关系组合完成了社会各项活动的运转。
面向切面是为弥补面向对象中的一些缺陷而生的,我们将某些功能封装到一起,提供对外的接口,方便在任何地方调用。就如SharedPreferences, Json, Xml, File, Device, System, Log, 格式转换等,这些通常会在until包里边。它就相当于一个横截面,我们可以随时面向这个横截面完成操作,而自己的逻辑里边不再需要重复的设计。
面向服务是将系统进行拆分,分成一个个独立的程序或组件,并对外提供某一项服务。每项服务之间通过某种协议进行通信,并进行分开部署,如HTTP,从而达到松耦合的目的。
的人和物一样,人与人之间各种复杂的关系组合完成了社会各项活动的运转。
面向切面是为弥补面向对象中的一些缺陷而生的,我们将某些功能封装到一起,提供对外的接口,方便在任何地方调用。就如SharedPreferences, Json, Xml, File, Device, System, Log, 格式转换等,这些通常会在until包里边。它就相当于一个横截面,我们可以随时面向这个横截面完成操作,而自己的逻辑里边不再需要重复的设计。
面向服务是将系统进行拆分,分成一个个独立的程序或组件,并对外提供某一项服务。每项服务之间通过某种协议进行通信,并进行分开部署,如HTTP,从而达到松耦合的目的。