提供同样功能、产品和服务的服务者中, 竞争力来自功能的多样化和服务品质的差异化, 无论是个体、企业还是国家。
这里的服务指功能、产品的实现程度和处理能力,以及研发/客服提供的技术支持程度(7*24, 随时响应, 沟通便捷,快速解决,温馨提示,有效指南等)。
从某种意义来说, 一切皆服务。 功能和产品只是形式, 服务才是本质。服务响应某种需求从而具备存在价值。个体、企业为社会提供某种类型、某种程度的服务,并获得相应回报。
程序员提供的服务是,在特定的工作环境和企业文化中,运用可用的资源以及自己的知识、技能、经验、时间、精力、资源,在适当可接受的开发成本下,通过将现实问题构造和组织成正确的逻辑流而获得问题的解决并持续维护的能力程度。
这种能力程度既包括服务能力本身,也包括通过这种能力所创造的服务的能力。 服务能力本身主要包括: 精通特定语言、技术、平台、架构等的技术深度; 组合技术、产品、运营、服务、商业的综合认知广度;具备多样化技能(开发、写作、外语、沟通、组织、幽默等);做事的能力素养,耐心、专注、缜密、魄力等; 具备非技术方面的特长,比如体育、音乐、文学、艺术、设计等。 通过这种能力所创造的服务, 通常是指软件、产品或服务。
如何保证服务端开发的功能和服务达到应有的品质呢?
1. 明确需要达成的品质; 知道做什么以及如何做;
2. 将服务品质尽可能量化并进行测量,做到服务品质透明化;
3. 更倾向于情感因素的服务品质,采用情感化方法处理。不在本文讨论范围内。
基本品质:
1. 正确性: 软件是否正确实现了指定的功能, 满足客户的多样化需要。
在内部实现上,是数据是否正确完整地构造、存取或销毁,且没有产生脏数据和无效数据【内部品质】。
需要建立功能实现的整个流程环路,对其中的所有细节知根究底,对交互的外部系统提供的相关服务也了如指掌。
量化: 业务数据是否合理的存取和一致。
2. 运行效率: 软件实现指定功能和服务所需时间和资源。 需要有误差范围的测量或估算。
可参考 SLA (服务等级协议)。 程序的执行效率应当在可接受的开发成本下达到最佳。
这就是说,在 "开发功能所需要的时间和资源成本" 与 "最终实现的服务能够提供的品质" 存在一个权衡。
一般来说,品质越高的服务所需要的时间和资源成本越高;无止境追求更高效率而不计成本和服务目标是不可取的。
比较理想的情况是: 通过适量改进、技术革新、管理改善等,可以使得花费较少的时间和资源成本能够获得更高的服务品质。
量化: 运行时间、 所需的存储资源、 响应时间、吞吐量、并发能力。
3. 错误处理: 软件能够捕获所有的错误条件(前提不符合、非法输入、脏数据等)和异常情况并给出合适的返回信息。
对于前端交互而言,需要友好容易理解的提示信息; 对于后台服务而言, 需要规范的错误码和错误消息。
建议先建立正确流程的业务主流程,然后对于主流程的每个环节进行推敲,找出各种错误场景并进行处理。
量化: 错误场景覆盖完全程度。
4. 易追踪性: 程序运行过程中输出适量的日志信息,便于追踪程序执行状态,快速排查错误【内部品质】。
需要适量且关键的 INFO 日志和 Error 日志。个人认为 DEBUG 日志可以通过提升代码质量来消除其必要性。
量化: 排查、定位每个问题的所需时长。
5. 易测试性: 主要是单元测试、自动化功能测试和性能测试。 单元测试和功能测试保证正确性,性能测试保证效率【内部品质】。
单元测试要求在开发过程中尽量编写具有单一职责的短小方法、类;代码对象越小,单元测试所发挥的作用越大。
功能测试要求针对具体使用场景设计有效的测试用例、测试计划和测试执行。
性能测试要求对业务处理所需的时间和资源进行测量,给出最佳值、最差值和平均值。至少要对运行时间进行测量。
量化: 业务方法的测试覆盖度、代码行、分支覆盖程度、测试用例集合、性能测试报告。
6. 安全性: 避免泄漏重要、敏感、隐私信息; 保护业务和数据不受非法访问、非授权访问的破坏; 追踪系统访问日志。
常见的方法有敏感信息识别和屏蔽、访问授权机制、 访问日志审计、代码漏洞防备。
可扩展性品质:
7. 可复用性: 要求软件中的函数、方法、类、库、模块、组件、框架等能够在同一工程或不同项目或不同产品中多次使用,便于替换更新【内部品质】。
最起码要求是在同一工程中能够尽可能复用, 避免重复代码段。每个业务方法最好不超过 60 行。
对于每个知识点、业务点和事实都有合理的抽象。
量化: 重复代码段数量; 函数、方法、类、库、模块、组件、框架的复用次数。
8. 可维护性: 要求软件容易理解、容易做出修改以满足新的需求,通常系统应具备模块化、高内聚、松耦合的特性【内部品质】。
容易理解需要可复用性的支持,同时要求代码尽可能具有自解释能力、适量注释、有效更新的设计文档。
容易修改需要快速定位一个功能服务所应对的代码集合,要求代码具有良好的组织和实现结构,
避免对多个地方做出相同或类似的修改; 避免对原有整体设计做出大幅度修改。
请参考《敏捷软件开发:原则、模式和实践》一书,尽可能满足五大设计原则(SRP, OCP, LSP, DIP, ISP),
实现“对修改关闭,对扩展开放”的境界。即:对于新需求的开发,尽可能仅仅是增加代码,而不需要修改原有代码。
量化: 理解一个功能需要的时长; 修改或扩展一个功能需要修改的代码行。
全局性品质:
9. 可用性: 程序运行中能够始终如一、持续长时间地提供正确、一致性的服务。
要求程序能够合理地使用和释放资源,监控程序的运行状态并及时发现异常情况解决。
对于高并发场景, 需要采用合适的技术进行分流,及时处理或拒绝请求,避免因为资源消耗过快过大而导致服务崩溃。
量化: 程序的持续可用性时长; 高并发能力。
10. 可靠性: 服务在严重错误情况下的可恢复能力和可替换能力,避免单点故障,保证可用性,保证用户数据的正确性和完整性。
主要包括服务的冗余、容错、备份、监控、自检测和恢复机制。
量化: 服务发生错误时是否可用; 是否可以从错误中恢复。
11. 可移植性: 软件能够在多种运行环境、平台上一致性地正确运行而只需要做出少量修改或无需修改。
使用可移植语言和平台、在实现功能和服务时尽可能遵循标准接口和行为,减少非标准行为的使用;
在底层提供接口统一不同平台的差异性;在高层使用统一接口进行处理,避免处理平台细节。
可移植性最好在系统构建之初进行考虑,比如初始采用 PHP, 后续移植到 Ruby, Python 或 Java 平台。
量化: 从一种语言移植到另一种语言或从一个平台移植到另一个平台所需要的代码行。
12. 可运维性: 服务发布后,管理大规模服务的运行、排查/诊断/解决问题的难度和速度、处理用户反馈的工作量。
服务发布后,可能产生的问题有哪些? 怎么排查? 服务的运行规模有多大? 并发程度如何?
在服务开发上,需要避免的是低级问题的产生,减少低级错误导致的工作量;
对于疑难问题,则需要提供关键的日志信息/运维文档便于排查;
对于大规模服务的运行,通常的方法是监控、报警以及可视化。
量化: 参考运维的量化标准。
13. 互操作性: 软件与其他系统交互的难易程度。主要包括通信方式、版本兼容性。
参考文章:
《用SLA保证Web服务》: https://www.ibm.com/developerworks/cn/webservices/ws-sla/
《软件质量模型》: http://www.cnblogs.com/gaochundong/p/software_quality_models.html
《细说软件质量指标》: http://developer.51cto.com/art/201104/255676.htm
《实现软件架构质量属性的战术》: http://www.uml.org.cn/zjjs/201309043.asp
《可复用性:专题》: http://focus.it168.com/200810/softwarereuse/