最让我吃惊的不是复杂度是什么,而是复杂度概念有自己的适用范围。
因为似乎是整天挂在嘴边的话,反倒没去仔细追究过,依照定义:
Programming complexity (or software complexity) is a term that encompasses numerous properties of a piece of software, all of which affect internal interactions. According to several commentators, there is a distinction between the terms complex and complicated. Complicated implies being difficult to understand but with time and effort, ultimately knowable. Complex, on the other hand, describes the interactions between a number of entities. As the number of entities increases, the number of interactions between them would increase exponentially, and it would get to a point where it would be impossible to know and understand all of them. Similarly, higher levels of complexity in software increase the risk of unintentionally interfering with interactions and so increases the chance of introducing defects when making changes.
程序复杂度(或软件复杂度)是对软件内部诸多影响内部关联关系的属性的描述。软件的复杂度介于complex(像讲混沌理论的《复杂》那本书中的复杂)和complicated(一般说复杂)之间:complex描述事物内部实体的关联关系、随着实体数量的增加最终不可能被完全理解;complicated是指事物难以理解但以足够的努力和知识最终是可理解的。即软件的高复杂度导致增加无意(与目的无关)的关联关系的风险,最终在做变更的时候更容易引入缺陷。在更极端的情况下,软件复杂到几乎无法修改。
The idea of linking software complexity to the maintainability of the software has been explored extensively by Professor Manny Lehman, who developed his Laws of Software Evolution from his research. He and his co-Author Les Belady explored numerous possible Software Metrics in their oft cited book,[1]
that could be used to measure the state of the software, eventually reaching the conclusion that the only practical solution would be to use one that uses deterministic complexity models.
软件复杂度最早是在Manny Lehman教授的软件演进法则中提出的,他还提出了很多沿用至今的衡量软件的指标。
比起Lehman教授的法则和每行bug数等他提的这些衡量软件的指标:
作为一名严谨的科学家,Lehman法则也即软件复杂度的适用范围确最让我吃惊:
In his 1980 article,[1]
Lehman qualified the application of such laws by distinguishing between three categories of software:
An S-program is written according to an exact specification of what that program can do
(笔者译:S类型程序是根据一个精确的规则spec来定义程序做什么内容)
A P-program is written to implement certain procedures that completely determine what the program can do (the example mentioned is a program to play chess)
(笔者译:P类型系统被开发出来执行一个明确的流程,这个流程是被精确定义的规则,例如国际象棋对弈程序)
An E-program is written to perform some real-world activity; how it should behave is strongly linked to the environment in which it runs, and such a program needs to adapt to varying requirements and circumstances in that environment
(笔者译:E类型程序是用于与现实世界打交道。这类软件的行为强烈的依赖于它存在的上下文环境,需要和各种不同的需求和环境的情况相适配)
The laws are said to apply only to the last category of systems.
软件复杂度只适用于E-type型的软件,也即体现现实世界活动的那类型软件或某个软件中的对应此部分。
如果将一个项目的代码分为项目的开发者自己维护的代码和使用的其他库、操作系统接口、其他外部接口,还有一个项目提供给外部其他人使用和调用的接口部分,所有与这些其他东西打交道的首先就自然是需要考虑复杂度的。
其次所有实现的是现实世界的人(产品经理、客户、自己)的意愿,而还未成为一个SPEC(S和P类型)的部分也都是需要考虑复杂度的。也即代码成为了最终意愿的表达,而不是先有SPEC作为表达,代码只是实现之,那么就是S和P类型了。
这似乎也与《代码大全》中指出的软件工程师到底是工程师还是技工的争论嵌合,《代码大全》中认为传统中区分工程师与技工是工程师不制造最终客户需要的标的(汽车、大楼等)工程师只产出图纸,工程师的产出是图纸(思想的载体)而不是实物,但在软件行业,代码即是思想也是产品,即是图纸也是实物,软件工程师即是技工也是工程师,软件只有一份图纸也即代码本身。
而那些可以定位为SPEC,与以一个SPEC交互的代码,是不符合复杂度规律,或者从定义上来说,是没有复杂度的!
从《代码大全》的对工程师和工人的区分看,也即产出此能完整表达的SPEC者是为工程师(虽然本人恶意的怀疑其实对绝大多数软件的目标而言,世界上不存在这样的SPEC),实现者视为工人。而《代码大全》的结论认为软件工程师无法区分工人与工程师。
初看很是震惊,细细想想并无道理。这些代码本质上就是一个SPEC的信息的具体实现,他没有复杂度定义中的complex和complicated,像举例的国际象棋的规则,他们既然已经被体现为一个清晰的已存在的SPEC在先,那他不可能complex到无法理解,也即不需要复杂度管理。但是想想实现国际象棋规则又似乎是可以再分为两部分?
这让我对相关问题的理解都有了刷新,后来看了InfoQ刚出的那本《谈谈架构》中讲解单元测试时候对代码进行分类,认为测试是测业务测实现,而不要去测跟环境打交道的代码,两者应该能清晰的区分,从而在最完美的情况下单元测试应该完全不需要mock,mock是系统测试的时候才需要的东西。
从这个S,P,E的角度看,还可作出很多新的分类,对很多问题有了一个新的视角。比如程序员的三大浪漫(操作系统 编程语言 计算机图形学)好像都不主要是E类型系统,还有redis、mysql、k8s等这些被其他软件使用或者管理其他软件的基础设施类的系统,它们对外提供定义完整的spec,自己的大部分实现也是在与定义完整的spec交互,大部分属于S和P系统。它们是否适用软件工程的复杂度管理一些思路是值得商榷的。这点就非常不同于常见的用于模拟人的活动的业务系统软件,业务软件就有很明确的复杂度管理,因为它的需求和环境情况都是多变的,并且是可以妥协商量的,于是从需求分析到DDD领域驱动设计等就有了整个目前我们熟悉的软件工程应对复杂度的技术和方法。
暂且打住,以后再想想。想到编程复杂度时候,其实吧就想到,更重要的是编程快乐。
Why is programming fun?
The below is an extract from Fred Brooks' (Frederick P. Brooks, Jr.) book, *The Mythical Man-Month. *This is one of the best explanations of why programming is so interesting. It touches on all aspects of the mystique of programming. If you haven't read the book, go out, buy it, and read it. The book was first published in 1974 and then republished in 1995. What Fred Brooks had to say then based on his experiences with the development of the OS/360 system is still relevant today.
(Begin quote)
Why is programming fun? What delights may its practioner expect as his reward?
First is the sheer joy of making things. As the child delights in his mud pie, so the adult enjoys building things, especially things of his own design. I think this delight must be an image of God's delight in making things, a delight shown in the distinctness and newness of each leaf and each snowflake.
Second is the pleasure of making things that are useful to other people. Deep within, we want others to use our work and to find it helpful. In this respect the programming system is not essentially different from the child's first clay pencil holder "for Daddy's office."
Third is the fascination of fashioning complex puzzle-like objects of interlocking moving parts and watching them work in subtle cycles, playing out the consequences of principles built in from the beginning. The programmed computer has all the fascination of the pinball machine or the jukebox mechanism, carried to the ultimate.
Fourth is the joy of always learning, which springs from the nonrepeating nature of the task. In one way or another the problem is ever new, and its solver learns something: sometimes practical, sometimes theoretical, and sometimes both.
Finally, there is the delight of working in such a tractable medium. The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air, from air, creating by exertion of the imagination. Few media of creation are so flexible, so easy to polish and rework, so readily capable of realizing grand conceptual structures. (...)
Yet the program construct, unlike the poet's words, is real in the sense that it moves and works, producing visible outputs separately from the construct itself. It prints results, draws pictures, produces sounds, moves arms. The magic of myth and legend has come true in our time. One types the correct incantation on a keyboard, and a display screen comes to life, showing things that never were nor could be.
Programming then is fun because it gratifies creative longings built deep within us and delights sensibilities we have in common with all men.
(End quote)
|