注意:本系列博文需要对templates和STL有一定掌握。
软件设计的多样性以及全功能型介面的失败
软件工程,也许比其他工程展现出更丰富的多样性,因你可以采用多种正确做法完成目标,个体之间存在无尽的细微差别。每一个新的选择,都会创建一个新的软件面貌,一个新世界,且伴随各样变化。这些变化会徘徊于每个软件阶段,大至系统结构,小至程式片段。------------所谓软件设计,就是解域空间中的一道选择题。
让我们先想象一个简单的入门级别程式雏形:一个Smart Pointer。
这种class可被用于单绪或多绪之中,可以运用不同的拥有权策略,可以在安全与速度之间相互协调,也可支援或不支援【自动转为内部指标】。以上的特性要是都能自由地组合起来,那么结合出最适合你应用程式的那个方案,不就是所谓的软件设计答案了吗?
设计的多样性不断地困惑新手。当存在一个软件设计问题时,什么才是最优的解法?是Events?还是Objects?Observers?Callbacks?Virtuals?Templates?根据不同的规模和层次,许多不同的解法似乎一样地好。
专业的软件设计师跟新手的最大不同之处在于,前者知道什么可以让程式有效运作,什么不可以。任何设计结构上的问题,都有许多合适解法,然而他们各有不同规格且优缺点齐全。对眼前的问题可能适合也可能不适合。白板上可接受的方案,不一定真的具有实用价值。
设计一个软件系统很困难,因它需要你不断地作出正确的抉择。然而软件设计犹如人生路,抉择是困难的。
经验老道的设计师们知道怎样的抉择会引领出好的设计。但对于新手来说,每一个设计抉择都是通向未知的未来。很是彷徨。有经验的设计者就像一名好棋手,可看出棋后的局势风向。但这需要时间来学习,或许这就是为什么编程可以很年轻就能展现才华,而软件设计却需要更多的时间才能成熟展现。
除了困惑新手,设计时【各种决定的组合】也常困扰程式库撰写者,为了将有用的设计实做出来,程序库设计者必须将各种常见情况加以分类融合,并给出一个开放架构,如此一来应用程式员便能根据个别情况组合出他所需要的功能。
更确切的说,如何在程序库中包装出既富有弹性又设计优良的组建?和让使用者自行装配这些组件?如何在合理大小的程式码中对抗“邪恶的”多样性?这是本类别博文试图去解答的问题。
“在一个全功能型介面实作所有东西”的做法并不明智。比较深刻的负面影响首当包括智力上的负荷,以及程式体积大小的爬升跟效率的考量。庞大的Classes并不能视为成功。因它们会导致沉重的学习负荷,并且会让人怀疑规模是否需要那么大。使得程式码远比人体制作还慢(或许夸张了)。
一个过于丰富的介面,最大的问题或许在于缺乏静态类型的安全性。系统架构的一个主要原则是:“以设计实现某些抽象映射原则”,例如你不能产生两个A物件,或不能产生B族系物件之类的等等。理想上,一个良好设计应该在编译期强制表现出大部分约束条件与规范。
在一个“什么都有”的大型介面上履行这样的约束条件是相当困难的。一般来说,一旦你选择了某一组设计的约束条件,大型介面内疚只有某些子集能够维持其有效语义。因程式库的运用向来在“语法有效”和“语义有效”之间存在间隙。程序员可能写出越来越多的概念,他们虽然“语法有效”,却“语义无效”。
如果程式库将不同的设计实作未各个小型的classes,每个class代表一个特定的范围解法,那会如何?这种做法的问题就是产生大量的设计组合,最后让实作者跟使用者眼冒金星。因此明显地,这不是一个好方法。面对如此之多的潜在组合,千万别试图使用暴力列举的方法。
这样不仅造成大量的智力负荷,也是极端死板的。一丁点轻微的“定制”震荡,例如试着以一个特定值为预先构建好的classes设定初始值,都可能会造成整个程式库变得毫无用处。
设计师为了履行约束条件。因此,以设计为目标的程式库必须邦族使用者完成自我设计,以实现自己的约束条件,而不是事先预先定义好的约束条件。范围设计不通用于以设计为目标的程式库。当然了,一些“最普遍的,受推荐的”范围解法将受到大众的欢迎,只要客户端程序员必要时能够改变它们即可。
低阶通用型与特化型程式库的大量存在,而用来直接辅助设计的程式库却几乎没有,这程式库的目前水平让人感到遗憾。这其实很矛盾,因任何不那么平淡无奇的应用程序都有其自己的设计存在,一个以设计为目标的程式库更应该通用于绝大多数的应用程序,真是矛盾!
框架试图填补这样的缺口,但这样却把应用程序限制在特定设计内,而不是让使用者选择并且定制设计,如果程序员需要实作出自己的设计,那么必须要从classes,functions等等开始。

本文探讨了软件设计中的多样性问题,分析了专业设计师与新手的区别,并讨论了如何在程序库设计中应对这种多样性,以实现既富有弹性又设计优良的组件。

4万+

被折叠的 条评论
为什么被折叠?



