当开发人员遇上非功能性需求

640?wx_fmt=gif

在开发产品时,你是否考虑过关注功能性需求与非功能性需求的工作量?如果没有,那么你可能应该关注下了,本文将告诉你为什么。

640?wx_fmt=jpeg

作者 | Chris Horsnell

译者 | 梁蕊

责编 | 仲培艺

出品 | CSDN(ID:CSDNNews)


640?wx_fmt=png

什么是功能性需求?


简单说来,就是特性。

这是你的 App、程序、系统、项目、产品等的核心——功能/特性使其得以工作,确保其实现了预期的目的。

可以说,这些功能会让你的用户想要使用它,而没有功能,你的产品就不复存在了。

尽管这是真的,并且非常重要,但是我经常看到非功能性的需求被完全忽略,这是非常危险的!


640?wx_fmt=png

什么是非功能性需求?


1. 文档、评论、编码规范、自动化测试、构建自动化等。

2. 使你的产品更易读、更具有弹性和可持续性。

作为一名开发人员或一个团队,这是你对代码库所做的所有与产品/项目不直接相关的事情。在这一点上,向那些了解到功能需求实际上可能只是总工作负载的一部分的读者致敬。

对于那些说“好吧,还有什么?”的人来说,根据我的经验,这是一个相当普遍的反应,所以不要感到难过。也不是每个关注非功能性需求的人都会做得很好。如果某件事值得做,就值得把它做好,对吧?

基本上,你对产品所做的任何与功能无关的事情都是重要的。想花更少的时间构建?自动化。想要确保提交的代码质量?进行同行审查。想要确保审查你代码的人能够阅读它?添加注释,而且不仅仅是添加一些注释,你需要考虑它是做什么的,它是如何做的,它为什么这样做,等等。

这样的例子不胜枚举,实际上听起来工作量很大是吗?但选择这样做当然有其原因。


640?wx_fmt=png

为什么非功能性需求很重要?


如果没有它们,你的产品基本上就是一个纸牌屋,随时可能被“微风”击倒。

没有它们,你就会产生短期或长期的技术债务。

我们都有过这样的经历,把自己关在家里几天或几周,进行一场编码风暴,直到最后,才意识到自己创造了一个怪物。现在,在个人/业余项目中,这可能不是世界末日,但如果你是为客户而建,他们给的报酬也很可观,或者你是为你自己的业务而建,那么这可能就会是一个大问题。

企业可能希望在 2 到 10 年之间合理地使用此代码,他们也可能想要添加东西,修复错误,将它部署到不同的地方。他们甚至可能不喜欢你的脸,想让别人/另一家公司来接管。

当上述情况之一发生时,最好的情况是你必须亲自动手去做这些改变,或者最坏的情况是向某人解释原因。


640?wx_fmt=png

为什么被忽视?


“我们没有时间。”

我听到的第一个借口是团队/开发人员没有时间。这是目光短浅且危险的,将直接影响到产品的可持续性和可维护性。如果不提前投入这些时间,总有一天会因此陷入麻烦——新员工会挣扎,现有的开发人员会忘记他们头脑中曾经新鲜的东西,你会失去几天或几周的时间来做那些可以自动化的事情,并且你现在正在浪费时间和金钱,而这本来是可以通过你的洞察力来避免的。

一般来说,这是缺乏技术领导的结果。面对现实吧,开发人员想要编写代码并解决问题,文档化、注释、确保代码覆盖等,与客户刚刚要求的新功能相比,这些并不是很吸引人。对于经验不足的开发人员来说尤其如此,他们还没有经历过忽视可持续发展意味着什么。

高级开发人员、技术总监、CTO、Scrum Master、产品所有者、顾问都应该意识到忽视非功能需求的危险。当团队和产品理解这些非功能性需求的必要性时,所有这些角色都为他们提供了更多的价值。

如果没有这些决策者的战略规划或至少施加压力,很难吸引技术人才。如果不拿出丰厚的奖金,任何有经验的开发人员都不会愿意接近你。这意味着你只能得到那些没有经验的人,然后不断重蹈覆辙。


640?wx_fmt=png

为什么软件项目需要可持续和可维护?


软件是一种资产,它需要具备业务可行性。

有所期望是相当合理的。如果你构建了什么,就相当于在为一项资产投入时间和精力。它需要有修改的潜力,迭代反馈,修复 bug,确保在没有不合理开销的情况下进行修改。

同样在软件团队中,人们来来去去,但是知识必须留存下来。只把产品的大部分工作知识掌握在某些关键人物的头脑中是没用的,如果他们离开/遭逢意外/中了彩票,你需要确保信息可以被存储和访问。此外,这些信息还需要清晰、简洁,且没什么隐藏内涵。如果谁有疑问,就像对五岁孩子一样为其解释。

如果不经历这些,你将每 1 - 2 年重建一次产品,或者每当你的开发人员更换时就意味着你不再有足够的理解力来有效设计你的产品。

如果不重建,走着走着就容易掉进死胡同,项目关闭,而自己也被炒了鱿鱼。

这也会影响你的声誉,尤其是当你与外部开发团队一起工作的时候,这些开发团队必须使用你蹩脚的 API,或者你发现自己经常收到阻碍,因为系统没有按照设计的那样工作,或者每次部署的时候都会崩溃。

这一切都影响到未来发展的成本。忽略所有这些意味着最终一切都会慢慢停止。即使是最小的改变也会让你付出巨大的代价。但是通过将一些注意力转移到非功能性需求上,您可以持续降低开发成本。这通常是最大的卖点,因为客户可以直接将其与他们所了解的东西——金钱——联系起来。“如果我们忽略这一点,现在可能节省 £20000,但未来两年里可能会因此最终赔上 £100000”。


640?wx_fmt=png

战略决策


所有软件项目都需要具备可持续性和可维护性。

以下列表都是常识。如果你没有这些,你的项目就会失败。

它可能不会崩溃乃至导致整个公司关门,但软件项目的成功依赖于这些细节,需要允许迭代新特性/修复,并及时这样做。另外,如果你的整个开发团队明天就离开了,你也能借以确保连续性。

  • 文档(代码、部署、平台、架构、约定等)

  • 评论 (文档评论、内容、方式、原因等)

  • 定期在团队/知识库中分享知识

  • 利用正确的编程语言/框架来完成工作

  • 架构/结构/设计模式

  • 坚持风格指南(也许通过 linting 强制)

  • 自动化测试(单元、E2E 等)

  • 安全性和性能测试

  • 自动构建,CI/CD

  • 同行代码审查

  • 版本控制(使用某种 Git Flow 分支策略)

  • 更改日志和语义版本控制

  • 关注点分离

  • API 规范(如果适用)

  • 移情 UX

现在对于一些人来说,这似乎都是显而易见的,但是以我的经验来看,没有这些基本原则的软件团队/工程师的数量是相当可怕的。

显然没有人是完美的,并非所有项目都有时间或预算来处理所有这些事情(特别是如果你从头开始做)。在这些情况下,解释一下忽视这些事情会对最终产品及其投资回报产生什么影响——将关键涉众的决策结果告知他们。

如果你将这些概念添加到你的流程中,提高你的标准,并追求卓越,就会有好事发生。

原文:https://medium.com/@chrishorsnell/the-problem-with-developers-only-focusing-on-functional-requirements-bbef26d3a4b1

本文为 CSDN 翻译,如需转载,请注明来源出处。



 热 文 推 荐 

☞ 极客头条

☞ 平均年薪 70 万!刚刚,这类程序员又涨薪了!?佩服!

☞ 鏖战九载,Google 是否会因 Oracle 而弃用 Java?

☞ 小心!你的脸正在成为色情片主角

☞ iPhone曝严重漏洞,用户接听FaceTime前或被“监听”!

☞ 聊聊云计算:为什么构建网站时常会用到负载均衡

☞ 年度大戏!以太坊大神怒怼智能合约之父,尼克·萨博到底做错了啥?

☞ 嫁人当嫁程序员

print_r('点个好看吧!');
var_dump('点个好看吧!');
NSLog(@"点个好看吧!");
System.out.println("点个好看吧!");
console.log("点个好看吧!");
print("点个好看吧!");
printf("点个好看吧!\n");
cout << "点个好看吧!" << endl;
Console.WriteLine("点个好看吧!");
fmt.Println("点个好看吧!");
Response.Write("点个好看吧!");
alert("点个好看吧!")
echo "点个好看吧!"

640?wx_fmt=png喜欢就点击“好看”吧!
展开阅读全文

当GPL遇上MP

01-25

[align=center]当GPL遇上MP[/align]rnrn[align=center]莫华枫[/align]rnrn GPL,也就是General Purpose Language,是我们使用的最多的一类语言。传统上,GPL的语法,或者特性,是固态的。然而,程序员都是聪明人(即便算不上“最聪明”,也算得上 “很聪明”吧:)),往往不愿受到语法的束缚,试图按自己的心意“改造”语言。实际上,即便是早期的语言,也提供了一些工具,供聪明人们玩弄语法。我看的第一本C语言的书里,就有这么一个例子,展示出这种“邪恶”的手段:rn #define procedure voidrn #define begin rn #define end rn 然后:rn procedure fun(int x)rn beginrn ...rn endrn 实际上,它的意思是:rn void fun(int x)rn rn ...rn rn 这可以看作是对初学C语言的Pascal程序员的安慰。这种蹩脚的戏法可以算作元编程的一种,在一种语言里创造了另一个语法。不过,实在有些无聊。然而,在实际开发中,我们或多或少地会需要一些超出语法范围的机制。有时为了完善语言,弥补一些缺憾;有时为了增强一些功能;有时为了获得一些方便。更新潮的,是试图在一种GPL里构建Domain Specific Language,或者说“子语言”,以获得某个特性领域上更直观、更简洁的编程方式。这些对语言的扩展需求的实现,依赖于被称为Meta- Programming(MP)的技术。rn 另一方面,随着语言功能和特性的不断增加,越来越多的人开始抱怨语言太复杂。一方面:“难道我们会需要那些一辈子也用不到几回的语言机制,来增加语言的复杂性和学习使用者的负担吗?”。另一方面:“有备无患,一个语言机制要到迫在眉睫的时候才去考虑吗?”。但MP技术则将这对矛盾消弭于无形。一种语言,可以简洁到只需最基本的一些特性。而其他特定的语言功能需求,可以通过MP加以扩展。如果不需要某种特性,那么只要不加载相应的MP代码即可,而无需为那些机制而烦恼。rn MP最诱人的地方,莫过于我们可以通过编写一个代码库便使得语言具备以往没有的特性。rn 然而,全面的MP能力往往带来巨大的副作用,以至于我们无法知道到底是好处更多,还是副作用更多。语言的随意扩展往往带来某些危险,比如语法的冲突和不兼容,对基础语言的干扰,关键字的泛滥等等。换句话说,MP是孙悟空,本领高强。但没有紧箍咒,是管不住他的。rn 那么,紧箍咒是什么呢?这就是这里打算探讨的主题。本文打算通过观察两种已存在的MP技术,分析它们的特点与缺陷,从中找出解决问题的(可能)途径。rnrn[size=16px]AST宏[/size]rn 首先,先来看一下宏,这种远古时代遗留下来的技术。以及它的后裔,ast宏。rn 关于传统的宏的MP功能,上面的代码已经简单地展示了。但是,这种功能是极其有限的。宏是通过文本替换的形式,把语言中的一些符号、操作符、关键字等等替换成另一种形式。而对于复杂的语法构造的创建无能为力。问题的另一面,宏带来了很多副作用。由于宏的基础是文本替换,所以几乎不受语法和语义的约束。而且,宏的调试困难,通常也不受命名空间的约束。它带来的麻烦,往往多于带来的好处。rn ast宏作为传统宏的后继者,做了改进,使得宏可以在ast(Abstract Syntax Tree)结构上执行语法的匹配。(这里需要感谢TopLanguage上的Olerev兄,他用简洁而又清晰的文字,对我进行了ast宏的初级培训:))。这样,便可以创造新的语法:rn syntax(x, "<->", y, ";")rn rn std::swap(x, y);rn rn 当遇到代码:rn x <-> y;rn 的时候,编译器用std::swap(x,y);加以替换。实际上,这是将一种语法结构映射到另一个语法结构上。而ast宏则是这种映射的执行者。rn 但是,ast宏并未消除宏本身的那些缺陷。如果x或者y本身不符合swap的要求(类型相同,并且能复制构造和赋值,或者拥有swap成员函数),那么 ast宏调用的时候无法对此作出检验。宏通常以预编译器处理,ast宏则将其推迟到语法分析之时。但是此时依然无法得到x或y的语义特征,无法直接在调用点给出错误信息。rn 同时,ast宏还是无法处理二义性的语法构造。如果一个ast宏所定义的语法构造与主语言,或者其他ast宏的相同,则会引发混乱。但是,如果简单粗暴地将这种“重定义”作为非法处理,那么会大大缩小ast宏(以及MP)的应用范围。实际上,这种语法构造的重定义有其现实意义,可以看作一种语法构造的“重载”,或者函数(操作符)重载的一种扩展。rn 解决的方法并不复杂,就是为ast宏加上约束。实际上,类似的情形在C++98的模板上也存在,而C++则试图通过为模板添加concept约束加以解决。这种约束有两个作用:其一,在第一时间对ast宏的使用进行正确性检验,而无需等到代码展开之后;其二,用以区分同一个语法构造的不同版本。rn 于是,对于上述例子可以这样施加约束(这些代码只能表达一个意思,还无法看作真正意义上的MP语法):rn syntax(x, "<->", y, ";")rn where x,y is object of concept (has_swap_mem or (CopyConstructable and Assignable))rn && typeof(x)==typeof(y)rn rn std::swap(x,y);rn rn 如此,除非x,y都是对象,并且符合所指定的concept,否则编译器会当即加以拒绝,而且直截了当。rn 不过,如此变化之后,ast宏将不会再是宏了。因为这种约束是语义上的,必须等到语义分析阶段,方能检验。这就超出了宏的领地了。不过既然ast宏可以从预处理阶段推迟到语法分析阶段,那么再推迟一下也没关系。再说,我们关注的是这种功能,带约束的ast宏到底是不是宏,也无关紧要。rnrn[size=16px]TMP[/size]rn 下面,我们回过头,再来看看另一种MP技术——TMP(参考David Abrahams, Aleksey Gurtovoy所著的《C++ Template Metaprogramming》)。对于TMP存在颇多争议,支持者认为它提供了更多的功能和灵活性;反对者认为TMP过于tricky,难于运用和调试。不管怎么样,TMP的出现向我们展示了一种可能性,即在GPL中安全地进行MP编程的可能性。由于TMP所运用的都是C++本身的语言机制,而这些机制都是相容的。所以,TMP所构建的 MP体系不会同GPL和其他子语言的语法机制相冲突。rn 实际上,TMP依赖于C++的模板及其特化机制所构建的编译期计算体系,以及操作符的重载和模板化。下面的代码摘自boost::spirit的文档:rn group = '(' >> expr >> ')';rnrn expr1 = integer | group;rnrn expr2 = expr1 >> *(('*' >> expr1) | ('/' >> expr1));rnrn expr = expr2 >> *(('+' >> expr2) | ('-' >> expr2));rnrn 这里表达了一组EBNF(语法着实古怪,这咱待会儿再说):>>代表了标准EBNF的“followed by”,*代表了标准EBNF的*(从右边移到左边),括号还是括号,|依旧表示Union。通过对这些操作符的重载,赋予了它们新的语义(即EBNF的相关语义)。然后配合模板的类型推导、特化等等机制,变戏法般地构造出一个语法解析器,而且是编译时完成的。rnrn 尽管在spirit中,>>、*、|等操作符被挪作他用,但是我们依然可以在这些代码的前后左右插入诸如:cin>> *ptrX;的代码,而不会引发任何问题。这是因为>>等操作符是按照不同的类型重载的,对于不同类型的对象的调用,会调用不同版本的操作符重载,互不干扰,老少无欺。rnrn 但是,TMP存在两个问题。其一,错误处理不足。如果我不小心把第二行代码错写成:expr1 = i | group;,而i是一个int类型的变量,那么编译器往往会给出一些稀奇古怪的错误。无非就是说类型不匹配之类的,但是很晦涩。这方面也是TMP受人诟病的一个主要原因。好在C++0x中的concept可以对模板作出约束,并且在调用点直接给出错误提示。随着这些技术的引入,这方面问题将会得到缓解。rnrn 其二,受到C++语法体系的约束,MP无法自由地按我们习惯的形式定义语法构造。前面说过了,spirit的EBNF语法与标准EBNF有不小的差异,这对于spirit的使用造成了不便。同样,如果试图运用TMP在C++中构造更高级的DSL应用,诸如一种用于记账的帐务处理语言,将会遇到更大的限制。实际上TMP下的DSL也很少有令人满意的。rnrn 所以说,TMP在使用上的安全性来源于操作符复用(或重载)的特性。但是,操作符本身的语法特性是固定的,这使得依赖于操作符(泛化或非泛化)重载的TMP不可能成为真正意义上的MP手段。rnrn 那么,对于TMP而言,我们感兴趣的是它的安全性和相容性。而对其不满的,则是语法构造的灵活性。本着“去其糟粕,取其精华”的宗旨,我们可以对TMP做一番改进,以获得更完整的MP技术。TMP的核心自然是模板(类模板和函数/操作符模板),在concept的帮助下,模板可以获得最好的安全性和相容性。以此为基础,如果我们将模板扩展到语法构造上,那么便可以在保留TMP的安全性和相容性的情况下,获得更大的语法灵活性。也就是说,我们需要增加一种模板——语法模板:rnrn templatern syntax synSwap=x "<->" y ";"rn require SameType && (has_swap_mem || (CopyConstructable and Assignable)rn rn std::swap(x, y);rn rnrn 这里我杜撰了关键字syntax,并且允许为语法构造命名,便于使用。而语法构造描述,则是等号后面的部分。require沿用自C++0x的concept提案。稍作了些改造,允许concept之间的||。 论坛

当移动遇上

07-02

近年来,在网络技术更新、数据业务种类不断丰富,以及智能终端迅速普及的推动下,网络流量长期呈现高速增长的态势,为应对这一挑战,运营商不断地扩容网络,但由于数据类业务的经营者大多数情况下不是运营商而是内容提供商,导致网络投资增长与营收增长形成越来越大的剪刀差。rnrn流量仍将维持高速增长已成为业界共识,要避免剪刀差日益扩大,须考虑如何降低网络投资的增速,可喜的是,我们已经能够看到实现这一目标所需的技术日渐成熟,这其中包括了目前广受关注的几个领域,即NFV(网络功能虚拟化)、SDN(软件定义网络)和云计算。rnrn相对于固网而言,移动网络的投资增速更加显著,移动运营商对降低投资增速的需求也更加迫切,在全球范围,移动运营商已开始在网络的各个层面引入新技术以实现上述目的。包括在RAN部分实施云化提升网络利用率;在分组核心和IMS引入NFV,降低对私有硬件的依赖并减少投资;在DC和承载网引入SDN,提升网络利用率和灵活性等。rnrn移动云网络引领新浪潮rnrn在2014年MWC期间,中国移动联手阿尔卡特朗讯展示了NFV领域的研发进展。在多厂商环境下,采用阿尔卡特朗讯基于概念验证的LTE RAN虚拟化BBU和虚拟分组核心演进vEPC解决方案,两家公司成功展示了开放性移动云网络在增强网络敏捷性、效率性和规模方面的效用。此外,还展示了vEPC、vIMS、vRAN产品,其中利用软件作为基础的vEPC,其效能已经在全球最大的两个LTE网络上得到验证,公司目前正在与5家运营商开展vEPC的相关研究与试/商用。rnrn作为IP网络和超宽带接入专家,阿尔卡特朗讯帮助包括中国移动在内的客户解决在其网络上面临的问题,全力投入开放性的运营商级虚拟化解决方案的研究。rnrn中国移动研究院首席科学家易芝玲博士表示:“长期以来,中国移动和上海贝尔强强联合以提供创新的解决方案,推动电信技术不断向前发展,本次在NFV领域的合作也是其中的一部分。此次我们成功展示了云网络环境在帮助更多客户提供更快、更好服务方面的重要作用。这将帮助我们满足移动数据需求的爆炸式增长,并促进我们进一步创新,推出新的服务产品。”rnrnCloudband+Nuage SDN=强健云平台rnrn这些虚拟化产品都在阿尔卡特朗讯的Cloudband2.0 NFV平台中承载和管理。Cloudband 2.0版本扩展后已经能够支持更强的网络控制、更广泛的开放式行业标准技术和虚拟网络功能。它还集成了阿尔卡特朗讯的SDN投资公司Nuage Networks的虚拟服务平台(VSP)。Nuage Networks公司的软件定义网络(SDN)解决方案提供高度自动化的、可编程和快速反应的网络,能够在云时代里支持IT和电信应用。rnrn通过一个简单的场景,即可了解Cloudband与Nuage SDN是如何协同工作,并支持NFV的(如图)。首先,运维人员将MME扩容指令由5620 SAM网管发出;由于vMME建构于Cloudband平台,因此该需求将送至Cloudband管理系统,在Cloudband平台中,提供众多的XaaS功能,大部分的NFV功能将使用cPaaS(Carrier-PaaS)提供,与MME对应的为vMME cPaaS,cPaaS使用预先创建的扩容脚本来创建虚机,该脚本定义了虚机的具体配置及承载的MME功能属性;当新的vMME虚机创建成功后,下一步就要将其加入vMME Pool-承载Cloudband Node的Nuage SDN可检测到新的虚机生成,并知晓其MME特征,据此创建新的vMME虚机与原vMME Pool的连接;加入后,vMME将向5620 SAM回送操作结果。rnrnCloudbandrnrnCloudband方案提供一个运营商级别的架构来建立和管理一个运营商云服务的发布环境。rnrn作为Cloudband管理系统的一部分,Carrier PaaS帮助运营商完成在云平台上的应用部署,实现对电信应用生命周期的管理,并充分利用云平台开放的全部能力创建一个开放的,有弹性的,自动化的,多租户和自我服务为导向的运营商级PaaS环境。rnrnCarrier PaaS位于云计算IaaS平台之上,使用IaaS平台所提供的北向API。从层次结构上来看,Carrier PaaS是一个基于IaaS平台接口之上的一个中间件环境,通常它与IaaS平台的管理系统以紧耦合的形式集成在一起,但它的独立性较好,也可以从管理系统中拆分出来独立运行,避免由于Carrier PaaS层的出现错误而导致管理系统内其他模块受到影响。Carrier PaaS将IaaS和PaaS平台所提供的各类API进行聚类和整合,提供给应用开发者和应用运维部门使用。rnrnNuage SDNrnrnNuage SDN解决方案虚拟化业务平台(VSP)是一个完整的多用户云数据中心网络服务解决方案,由三部分组成:VSD、VSC、VRS,分别负责策略,集中控制和虚拟路由交换。通过这三个关键部件,Nuage VSP全面介入数据中心网络的服务平面,控制平面和转发平面。rnrn在一个使用了阿尔卡特朗讯SDN解决方案的云服务架构中,管理员如果想创建和交付一个新的云服务,可方便地按照应用的需求进行网络服务设计。rnrnNuage SDN检测并响应虚拟机的创建和释放,并自动地按照既定的策略调整网络服务。无缝配合虚拟机的迁移,不受边界限制(如机架、集群、区域等)。消除那些人为界限,使网络服务可以在数据中心内甚至跨越多个数据中心间移动。rnrn目前,阿尔卡特朗讯已签署了5个关于提供Nuage Networks SDN解决方案的合同。rnrn尤为值得一提的是,除了在移动分组核心网推进虚拟化,阿尔卡特朗讯还在IMS中积极引入NFV ——目前已经将PCRF、HSS等功能迁移至Cloudband平台,通过采用全新的开放性云技术,可以使其在100%负荷的最大规模通信网络中规模运行时仍保持高性能状态。阿尔卡特朗讯的vIMS已经在现网部署,并且正与8家vIMS云客户进行测试。rnrn在承载网方面,阿尔卡特朗讯已成功实现RR(Route Reflector)的虚拟化,此前,RR基于专有的路由器硬件平台,其特点为计算、查询密集,但并不涉及转发等动作。在某些网络上,为应对高密度的RR需求,甚至独立部署一台高性能路由器来完成此工作,这同时也浪费了路由器的核心价值。通过将RR部署至云平台,可充分利用其计算优势,并可随需伸缩。rnrn阿尔卡特朗讯致力于加快行业NFV的部署,目前正服务于3个Cloudband NFV客户合同以及10个试验项目,积极参与ETSI NFV咨询委员会和设立Cloudband生态系统计划,并帮助中国运营商有序、平稳地推进移动网络云化。rn 论坛

没有更多推荐了,返回首页