软件项目中的六大质量属性
丁俊林
(石家庄铁道大学,河北省石家庄市050013)
摘要:关于在我自己编写代码以及阅读别人代码过程中对一个软件在编写以及发布过程中所必备的六大主要的质量属性的理解。关于一个软件的重要质量属性,在代码中如何具体实现,以及实现的目的是什么等重要方面。
关键词:软件;质量属性;个人理解;实现方法;
Six quality attributes in software project
Dingjunlin
(Shijiazhuang Tiedao University Shijiazhuang, Hebei Province 050013)
Absrtact: in the process of writing my own code and reading other people's code, I understand the six main quality attributes of a software in the process of writing and publishing. About the important quality attribute of a software, how to realize it in the code, and what is the purpose of it.
Keywords: software; quality attribute; personal understanding; implementation method;
关于在进行了一系列课堂讨论后,以及听其他组的报告之后以及结合自己在平时编程的经验的感受,得出了关于软件六大质量属性的感受。感觉自己在平时代码编写的时候基本没有注意到这些,结合本次思考感觉到一些应当做到的方面。
一,可用性
首先可用性的定义是指 可用性与系统故障及其后果相关。当系统不再提供其规范中所说的服务时,就出现了系统故障。系统用户可以观察到此类故障。可用性是指系统正常运行时间的比例,是通过两次故障之间的时间长度或在系统崩溃情况下能够恢复正常运行的速度来衡量的。
比方说,在制作一个网站的时候,网站的最大容量就是一个很重要的指标,当同时在线的人数超过这个指标会出现什么情况,系统怎么检测这一事件的发生,该怎么做来减少因为很多用户进行同时访问,系统访问量过大因出现崩溃而造成的影响,系统该怎么尽可能避免出现这一情况等。这些都是我们在编写代码的时候所需要提前想到的问题。
就比方说SLA:服务等级协议(简称:SLA,全称:service level agreement)。是在一定开销下为保障服务的性能和可用性,服务提供商与用户间定义的一种双方认可的协定。通常这个开销是驱动提供服务质量的主要因素。很多互联网公司都期望自己的SLA越接近100%,而全年停机5.26分钟才能做到99.999%,即5个9。依此类推,要达到6个9及更多9,可说是非常难了吧。
SLA的概念,对互联网公司来说就是网站服务可用性的一个保证。如果我们提供的服务可用性越低,意味着造成的损失也越大,别的不说,如果是特别重要的时刻,或许就在某一分钟,你可能就会因服务不可用而丢掉一笔大的订单,这都是始料未及的。所以,只要尽可能的提升SLA可用性才能最大化的提高企业生产力。
要做到更多的9,就要不断的监控自己的服务,服务挂掉能及时恢复服务。就像开车出远门,首先得检查轮胎,同时还得准备一个备胎一样的道理。
至于实现方法,就目前已知的分为四大类
1、错误检测:
这里面又分为三种方法:
命令/响应。 (在错误发生前阻止,先由本地组件进行低级判断,再通过远程高级判断)
心跳。 (定时发送信息或数据给检测组件)
异常。 (编写代码多抛出异常,多写try,catch)
2、错误恢复:
4个战术:
表决 (输出评判数据,交给表决组件表决,采用“多数规则”或“首选组件”或
其他算法判断是否进行错误恢复)
主动冗余 (通过第一个组件的响应判断恢复时间,通过备份数据来实现恢复)
被动冗余 (通过切换至备用组件来实现恢复,然后初始化新组件状态)
备件 (更换组件,重启,初始化状态)
3、重新引入:
3个战术:
shadow操作。(以前出现故障的组件可以在短期内以“SHADOW模式”运行,以确保在恢复该组件之前,模仿工作组件行为)
状态再同步
检查点/回滚 (快照,对比)
4、错误防止:
从服务中删除(例如重启新组件以避免内存泄露)
事务 (关闭绑定的有序步骤)
进程监视器
二,可修改性
关于可修改性,最重要的两点就是可以修改什么?何时以及谁进行修改。
就比方说淘宝在双十一活动的时候需要对淘宝界面进行一个打变更,此时就会出现一个问题,开发人员修改界面的时候会不会影响其他功能,比方说会不会影响用户的下单。此外就是,开发人员进行修改界面的时候,对于当前正在浏览界面的用户会不会产生不良的影响等
那么如何提高软件的可修改性呢
1,减少任务量
毕竟吧,减少了本次任务的任务量了,相应的修改代码所要花费的时间也就减少了,就比方说代码的复用就很大程度上减少了修改的任务量,在进行代码的编写的过程中,我们应当有意识的将一些可能会发生变动的常用的变量值,用一个xml文档存储起来,这样也就方便了将来对参数的修改等。
2,提高效率
可以尝试使用并发的进程来帮助我们进行程序的运行,多个工具同时运行,肯定能减少我们进行修改代码时候的任务量。
3,控制反转
可以多使用耦合度松的框架进行代码编写,比方说Spring框架中将对象的创建交给容器自己执行,由容器自己进行属性,以及方法的依赖注入等这些操作可以大大降低开发时候的代码的复杂度,耦合度
4,面向接口编程
因为网站或者其他大型项目往往并不是由一个人或者一个小组完成的,所以团队协作过程中,代码的协调往往是至关重要的作用,因此就产生了面向接口的编程,而且这类编程方法可以做到代码发生变化但代码对外的接口却是一直保持不变的。
三 ,性能
一个软件的性能往往是用户对一个软件最直观的评价,比方说淘宝对用户的响应时间,淘宝这款软件能够风靡全国,除了其先进的互联网思维以外,软件自身够硬的素质也是必不可少的因素之一。试问哪个用户能接受自己在买东西的时候,软件疯狂卡顿,或者付款的时候出现因为软件自身的问题导致用户交易失败等情况。在这方面,不得不说淘宝确实做的很成功
那么怎么样才能提升软件的性能呢
1, 代码优化
比方说在写一个循环的时候,可以将计算过程复杂的放在循环外部,使用等于不等于的时候,可以进行一个预先的判断,两个肯定有能较早到达目标值的,这样也就能减少代码运行的次数,减少运行时间。类似的方法还有很多很多。比方说计算乘法除法的时候可以替代的使用移位等操作,优化性能。
2, 缓存动态和静态内容。
如果你的Web服务器同时又充当了应用服务器,那么通过缓存动态内容就可以达到高峰期10倍的性能提升。缓存静态内容也可以有几倍的性能提升。这也是为什么主流游戏会存在客户端这一东西,就是为了大大提升玩家们的游戏体验的,试问如果有一款游戏,每次都要加载图片,模型加载半天,那还会有人愿意玩吗
3, 压缩数据
压缩同样能极大提升性能。图片、视频、音乐等文件都有非常成熟和高效的压缩标准(JPEG和PNG、MPEG-4、MP3),任何一个标准都可以把文件大小缩小一个数量级甚至更多。
文本文件,包括HTML(纯文本和HTML标签)、CSS和JavaScript代码,经常在不压缩的情况下传输。压缩这些数据对提升Web应用的感知性能有时候特别明显,尤其是移动用户的网络很慢又不稳定的情况下。
因为文本数据通过对于页面交互能够起到必要的支援作用,而多媒体数据则更多是锦上添花的作用。聪明的内容压缩可以把HTML、JavaScript、CSS等文本内容的缩小30%以上,因此能够相应地减少加载时间。
如果你使用SSL,压缩又可以减少必须经过SSL编码的数据量,从而补偿了压缩这些数据的CPU时间。
压缩数据的方法非常多。比如,“建议六”中关于HTTP/2的部分就描述了一个新颖的压缩思路,特别适合首部数据压缩。还有一个关于文本压缩的例子,就是可以在NGINX中开启GZIP压缩。预压缩文本数据之后,可以使用gzip_static指令直接发送.gz文件。
四,安全性
安全性是衡量系统在向合法用户正常提供服务的情况下,阻止非授权使用的能力。目前试图突破安全防线的行为被称为“攻击”。攻击主要有以下三种方式:
(1)未经授权试图访问数据或服务。
(2)未经授权试图修改数据。
(3)试图使用系统拒绝向合法用户提供的服务
那么怎么做到
目前常见的危害到软件的安全性的有以下方面:
1,SQL注入
所谓SQL注入式攻击,是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令。在某些表单中,用户输入的内容直接用来构造(或者影响)动态SQL命令,或作为存储过程的输入参数,这类表单特别容易受到SQL注入式攻击。
简单举个小例子,一个登录模块,让你输入用户名密码。我们一般都会老老实实的输入我们的用户名和密码。但如果我们刻意的去绕过登录认证m呢?猜想下面这个sql语句,单说用户名,开发人员很可能会这样去数据库里对比:
Select * from sys_user where username=‘XXX’
当然可能更复杂,假如我们在输入框里输入下面一句特殊的字符会如何?’or‘1=1
这是段神奇的字符,因为这样这个sql变成:
Select * from sys_user where username=‘’or‘1=1’
这样我们跳过了用户名的验证,实现了入侵。
2,修改提交数据
曾经某公司做过一个关于在线支付的商城,在安全性测试过程中,发现通过抓包抓到的提交价格(如使用火狐插件:live http headers),经过修改再发包可以通过。简单来说是本来100块钱买的东西,抓包修改为1块能成功购买。这成为了一个巨大的隐患。
3,缓冲区溢出
缓冲区溢出已成为软件安全的头号公敌,许多实际中的安全问题都与它有关。造成缓冲区溢出问题通常有以下两种原因。①设计空间的转换规则的校验问题。即缺乏对可测数据的校验,导致非法数据没有在外部输入层被检查出来并丢弃。非法数据进入接口层和实现层后,由于它超出了接口层和实现层的对应测试空间或设计空间的范围,从而引起溢出。②局部测试空间和设计空间不足。当合法数据进入后,由于程序实现层内对应的测试空间或设计空间不足,导致程序处理时出现溢出。
4, 加密弱点
这几种加密弱点是不安全的:①使用不安全的加密算法。加密算法强度不够,一些加密算法甚至可以用穷举法破解。②加密数据时密码是由伪随机算法产生的,而产生伪随机数的方法存在缺陷,使密码很容易被破解。③身份验证算法存在缺陷。④客户机和服务器时钟未同步,给攻击者足够的时间来破解密码或修改数据。⑤未对加密数据进行签名,导致攻击者可以篡改数据。所以,对于加密进行测试时,必须针对这些可能存在的加密弱点进行测试。
这些都是代码编写过程中需要考虑的部分,不过现在上市的软件或者系统基本都通过了市面上的安全监测公司的检测
五,可测试性
其定义为通过测试揭示软件缺陷的难易程度。特别地,假设软件中至少有一个错误,软件在下次测试运行时不能正常工作的可能性。
可测试性的响应度量处理的是测试在发现缺陷方面的效率以及想要达到某个期望的覆盖范围,需要用多长时间进行测试。比方说单元开发人员在完成架构和子系统的集成以后执行测试的时间,这就是对代码可测试性的集中体现。
单元测试在一个完整的软件开发流程中是必不可少的、非常重要的一个环节。通常写单元测试并不难,但有的时候,有的代码和功能难以测试,导致写起测试来困难重重。因此,写出良好的可测试的(testable)代码是非常重要的。
通常一个单元测试主要有三个行为:
初始化需要测试的模块或方法。
调用方法。
观察结果(断言)。
而编写代码的过程中经常会出现这些情况,严重影响了代码的可测试性:
1. 方法和数据源紧耦合在了一起
时间这个输入无法通过其他的数据源得到,例如从文件或者数据库中获取时间。
2. 违反了单一职责原则(SRP)
SRP是指每一个类或者方法应该有一个单一的功能。而这个方法具有多个职责:1. 从某个数据源获取时间。 2. 判断时间是早上还是晚上。SRP的一个重要特点是:一个类或者一个模块应该有且只有一个改变的原因,在上述代码中,却有两个原因会导致方法的修改:1. 获取时间的方式改变了(例如改成从数据库获取时间)。 2. 判断时间的逻辑改变了(例如把从6点开始算晚上改成从7点开始)。
3. 方法的职责不清晰
方法签名 String getTimeOfDay() 对方法职责的描述不清晰,用户如果不进入这个api查看源码,很难了解这个api的功能。
4. 难以预测和维护
这个方法依赖了一个可变的全局状态(系统时间),如果方法中含有多个类似的依赖,那在读这个方法时,就需要查看它依赖的这些环境变量的值,导致我们很难预测方法的行为。
要解决这个问题,通常可以使用依赖注入(控制反转,IoC),控制反转是一种重要的设计模式,对于单元测试来说尤其有效。实际工程中,大多数应用都是由多个类通过彼此的合作来实现业务逻辑的,这使得每个对象都需要获得与其合作的对象(也就是他所依赖的对象)的引用,如果这个获取过程要靠自身实现,那会导致代码高度耦合并且难以测试。那如何反转呢?即把控制权从业务对象手中转交到用户,平台或者框架中。
六,易用性
关注的是对用户来说完成某个期望任务的难易程度。分为以下几个方面:有效性、错误避免及错误处理、用户自信和满意度、可学习性这也是用户选择一款软件的重要决定因素。就比方说音乐软件中十分热门的网易云音乐,当年火起来并且超过qq音乐的一个重要原因就是,她能根据用户几天的听歌情况只能的推荐用户可能喜欢听的歌,而且准确度还十分的精确,这也是其深受用户欢迎的原因之一。再比方说淘宝用户能够针对用户需求推荐想要的商品,能够设计符合用户需要的搜索筛选框,且设计十分的合理。这就需要设计师针对用户做到人性化考虑,怎么样让用户用的舒服,用户才有可能喜欢你做到软件。
一般为了实现易用性需要做到以下步骤
1,上下文梳理
上下文梳理是明确研发系统与哪些外部实体存在关系。在梳理软件的上下文的时候,一般会更加关注与软件系统有直接功能交互关系的实体,有时会忽略软件系统的用户,而明确软件的用户,是易用性提升的起点。
因此,在上下文梳理时需要明确软件的目标用户。例如某个软件的目标用户是外部客户和内部服务工程师,那么在上下文分析的时候,应该明确出来
2,需求场景分析
从易用性分析出发,前面上下文分析明确了用户角色,这里要围绕用户角色来梳理用户的使用场景。使用场景表明了软件被用户用来干什么。
梳理使用场景,即基于对用户对软件业务/功能诉求的理解,进行场景的定义。基于使用场景对软件的各个大大小小相关的需求特性进行归类,便于下一步的需求分析。更重要的是,使用场景是UI设计的重要依据和输入。
3,UI架构设计
UI也是需要架构设计的。目前架构设计的实践中,更多的是关注软件功能实现的技术方案,基本没有涉及UI的设计。不过,从易用性的角度出发,UI也是需要架构设计的。
软件架构设计除了给出功能视图、部署视图、运行视图等,还要给出UI框架视图。
4,软件试用
在软件交付前尽早组织进行软件试用,是保证软件易用性的一个有效手段。这也就是软件测试中验收测试的重要组成部分。一方面由用户和设计师同时进行测试,用户测试完要求设计师进行代码修改,另一方面即为将软件发布贝特测试版,由一个或多个用户的实际使用情况进行一个反馈的测试。
以上即为我针对软件六大属性的一些个人的感悟等等。六大质量属性在软件构成过程中都占据着及其重要的地位,相信如果我们能够将其及时掌握,那么对于我们所编写的软件的质量一定会有很大帮助。当然想兼顾六种十全十美可能确实很难做到,但相信只要根据实际需要进行相应的删减,我们一定能够得到我们想要的软件,且软件的质量一定也不会令人失望。