|
板凳
楼主 |
发表于 2011-10-22 18:32:10
|
只看该作者
8.8 应用与设计
应用越来越接近人了,比如web2.0,3.0的出现,这是指软件产品的应用,实际上在软件被作为产品被产生出来时也作了靠近人的调整,编程领域的三个东西,问题域,方案域,人都在相互影响,这种影响产生了一些技术,导致了一些编程的变革,并最终与人们的观念结合,比如OO,比如设计模式,这也将导致架构变成软件的功能性"实现"要考虑的,在某个维度上加深了复杂度,然而却在另外一些维度上提供了简单的形式和更有效的应用
互联网的最初灵感来自对学术自由和开放的向往,而现在它已成为由企业和运营商控制的商业平台。企业应用与网络的发展密不可分,这二者相互发展,成为影响软件工程界的二大主力
多维这个字眼本身就提倡从多个方面(可见多维就是多方面,当我站在某个维度为我自己说话时,我将同时失去另外其它的维度)
某些东西越来越统一和规范了,这加大了学习的门槛,比如xml出现,就统一了文档交互的格式,并导致了很多逻辑知识,产生了一些新的逻辑,需要被学习,但这是合理的,因为形式更加简单了统一了,并改变了一些应用的形式,比如软件分发delopy的统一形式等,
另外一趋势,应用越来越分布了和趋向web,这实际上是很多年前某些大公司的战略,总有那么一群人(有些人研究应用形成架构,有些人研究编程低层形成架构和思想),先知先觉地认识到一些东西,比如.net的出现,网上的资源服务器越来越变成一般应用服务器,富客户端的flex,silverlight等等,只是它们是慢慢被民间所识所学习.
一切技术都是面向被应用,因此人无论如何都是主导.将反过来最终影响技术的被利用形式而隐藏了低层实现,一些离最终应用跨度太大的低层实现不必知道其原理,靠近人的一端要提供尽量简单的形式,比如xml,比如oo,面向机器的一端永远有它的实现.
8.9 与软件有关的哲学 联系
范意上的设计是广泛的,不仅限于计算机的,也不限于软工抽象(软工和计算机是二个完全不同的抽象,虽然没有人提出过计算机抽象到底是什么,软工抽象到底里面有哪些抽象存在,我们仅能站在某个或某些维度上给出一个描述性的概念而不是有限集,如果能站在一个大全的维度上说明到软工的全部抽象,虽然这是不可能的,但我们还是给得出的这个结果取个名字,叫范式,范式总是某些维度上的产物而不是大全的维度产生,学习计算机的很多哲学思维可以解决其它域的哲学),设计并不仅仅面向于创新,有时是形式的重组,而不是内容的创新,应用形式的改观,设计出的产品,要源端是面向人的,因此要提供足够简单的使用和访问形式,在目标端是要达到足够丰富的应用逻辑(比如XML统一文档交换,但可由node,root这些形式导致足够丰富的深层功能,深层这里是指上层),因此越复杂越大而全越好(但是如果没有足够人力,我们应考虑设计出别人想不到的商机),应用形式和应用逻辑作为设计中应主要考虑到的问题,
在设计软件时,我们主要用UML工具,但是这东西是静态语言用的
.
8.10 与软工有关的哲学 唯物主义
没有绝对科学的东西科学,维度给了我们一切答案,永远有更偏更僻的维度存在,因此拿唯物主义来说,如果它仅仅是表达那么一种"理"(它仅仅只需要说明这点),而没有宣扬它是正确的(实际上唯物论本身站在另外一些唯度上看就是片面的,而片面就是一定程序上的不正确),那么唯物论在这个维度上就算是做到科学了
唯物主义表明事物是不以人的意志为转移的,但是这里面的最基础的一个说法都不科学,什么是事物?哲学都没有从一种形式上去说明这个问题(就像字典内对"强间"应如何定义呢,法律范式内应如何对这个词进行界定呢)
当然我们讨论问题时并不需要把所有涉及到的逻辑都拿来解释一通,但是作为哲学维度的"事物"是应该被深入和专门界定的,而且"事物"这个字眼本身就是不严格的,而对象对象中的OO中的O,在计算机内存中,它是一个运行单元,在表达出的思想所指时,它又是不可形式化的.(在内存中总是那种形式,然而却可以产生不同的逻辑,这就是形式与逻辑的关系)
如果我们曾把生命中一段时间用于考虑这些哲学知识,那么我们就会与常人"分裂",正如写小说的人如果想说出与众不同的小说故事到达到无人深入之境,就必定要付出和得到一些灵魂,,产生排拆他人的想法,但是要知道,世俗的维度是我们生活所在的维度集,我们如果能认识到这种客观性,并尊重它,那么我们就不会分裂,
人只能是简单的,人只能是一个行者,在有生之年接受有限的知识,进行自认为或世俗认为正确的观点和作法并行动.而不可能永远是一个哲学者,没有人有足够的生命力来最终解释自己,得到的解释也只能在一个维度上成立而在另外一个维度显得可笑,,选择需要学习的人类知识去学,不要做一个大而全的学习者,在利用所得知识进行设计自己的应用时,应根据经济学所指,做别人没有的东西,才会显得有优势,你不必在任何一个方面都出色,但一定要在一个方面最出色(实践要达到"别无它,唯手熟而这样的境界"),这就是你的资源优势,可以转化为经济优势
逻辑
很多逻辑的意思都是不可言传的或者难以言传的,所以要看别人的代码时,除非别人在类文件形式的逻辑,组件形式逻辑的命名上直接让你明白很多信息,?否则你就不能有效地明白作者写这些程序时的想法,所以读人家的程序是难的,因此虽然你是面向源程序形式,但你其实是在求索别人的思想,更要命的是,你明白了这个类文件是什么意思,你还不能很有效地告诉别人这个类写了什么东西,,体现了什么逻辑,这是感觉是窒息的
软件的本质就是一种逻辑的叠成物,,某某牛人说过,一切问题和功能的达成都是逻辑!!软件的眼光里,一切皆逻辑,,在这个软工年代,最终的产品是多人合作代码的产物,因此相互之间能明白对方的源程序里到底能提供什么功能是重要的,,在以前的程序="数据结构+算法"的年代,程序员之间很容易在这方面获得沟通,而在现在这个软工年代,程序=数据结构+算法+架构"的年代,你还得明白人家程序逻辑是如何组织的,哪些是功能级的实现,哪些是架构级思想级的东西(这些东西为了以后的可扩展而存在,虽然一定维度上也可以称为功能级的实现),,
所以逻辑该如何命名,,我们只能满足于用特定的,固定的形式去描述性地表达它们,比如用类文件的名字,组件的名字,,设计模式的中间用词,等等.
8.11 真正的设计模式
我讨厌在讲授一些思想的时候提供大量的代码,因为我觉得接受思想的过程应该是一种快乐的如同阅读一本小说的过程,而不是花大量脑力研究某个细节的过程
而且这个世界,往往知识都只是相互转载,国内没有多少人会像那些欧美大师特立独立发明一些新的思想和论述,而我愿意写出我的一些思想与你们共享
每一个设计模式中都出现了一些角色,然而使用某个设计模式的个体(Client)不属于设计模式的某个角色,而只是使用这个设计模式的客户,,设计模式的目的就是为客户提供一个好的对现有对象的访问方法,设计模式是一种高于任何成码的思想和经验模式,因此不能直接用某个工具建模下来,在使用设计模式的过程中,,,总会产生一些新的抽象(而且有时不只一层抽象),,这些抽象隔离和解偶了客户(Client)与现有代码之间的关系,,,在它们中间作为中间抽象出现,而所谓抽象,,往往都以一个类的方式存在,(因为JAVA中一个类默认只承担一项责任或实现一个对象数据描述,因此一个抽象往往就是一个类,当然,抽象有时以方法的形式存在,某个设计模式也会以方法的形式存在,比如工厂“方法”模式,一般来说,设计模式都会形成某几个抽象类,对应该设计模式中的几个角色Actor),,
设计模式终归是一种迂回的方法(因为增加了抽象所以代码变得有点难于理解而且类层次增加这变得运行时变慢了一点),,然而这种方法成全了一种好处,,那就是:它部分或完全都解偶了使用者与现有代码之间(实际上设计模式可用在开发的各个阶段)的关系,,,这使得以后的对软件的维护工作和修改需求变得易管理和易实现,使软件不致于由于当初设计上的欠缺而变得难于修改而濒于死去.
8.12 设计模式与数据结构
对于设计模式,一般有下面几种理解: 重构时的设计模式。修补式的设计模式(client角色浓重) 大设计时的设计模式。全新式的设计模式(可以没有client角色在某一套模式中)
其实。不妨把设计模式称为抽象模式更好(我们知道抽象问题领域是设计中的一个重要步骤),,因为它更多地跟着眼于解决具体事物有关(就跟数据结构一样,不是跟具体语言有关,不是属于某种代码结构。)正如数据结构是择“数据”这个维度来抽象对现实事物映射到计算机解法的做法一样,设计模式是择“模式中的各个角色和关系”来映射对现实事物的模型,从而求得一个现实问题到计算机的解法一样(就目前所提出的一些设计模式来看,他们都是抽象现实事物模型的初步组件,一般有倾向于用面向对象语言来实现的趋势比如四人帮那书)。数据结构和设计模式都不会跟某种语言和语言机制有关,跟“面向对象”这样的代码抽象有本质上的差别,是实现模式,实现结构,而不是代码结构。着眼于如何解决和抽象问题,而不是如何抽象代码以进行更好能被复用这样的软工目的(当然,这二者是不分家的)。
我在《OO为什么不是银弹-过度抽象的利与弊》中谈到,OO并不是银弹,银弹是那些能统一人类思想,形成契约文化,经验的东西(比如我们写小说的那些套路),而不是简单的class这种面向复用的小技俩。 设计模式正是上述所谓“契约文化,经验”之类的初步体现(不可否认,我们所看到的设计模式跟具体现实事物还是有很大距离的),等到有一天,所有的问题都用设计模式来抽象的时候,成千上万的设计模式会被提出来。人们会倾向于用大大小小的设计模式来解决问题。那么设计模式就会到达它的颠峰。
然而对于程序员来说不利的是,数据结构已经被很好地映射到C语言中,而设计模式几乎在C语言中找不到它的影子。这正是它不成熟的地方。也许有一天会有一套“设计模式”专用语言出现。
8.12 设计模式之基础
研究数据结构我们目的从来不是那些底层的东西,,而是抽象的比如优先队列,多重集等。
四人帮的那本书是基于面向对象来谈设计模式的,因此它先提出一些面向对象的知识,比如一个类的class和type(interface)的区别,提倡对接口编程而不是对class定义即实现编程,提倡对象的组合而不是继承。而且它稍后提到的诸多设计模式中,都有对象,职责,请求,之说,这些都是OO里面的知识。。
不要小看了这里的对象组合它实际上是对接口编程的小化说法
8.12 真正的开闭原则
我们应该对扩展开放,的同时(注意这三个字),,,保证对修改的关闭(一个工程,应该在设计时就要考虑到将来修改的需要,而且要保证未来修改时能尽量降低工作量,对于一个真正的工程级的规模,人力管理工程应该尽量简化),
几乎没有接确过设计模式的人(除了完全外行和真正的编程高手外)看到这句话都会感到疑惑,而且会产生一个很普遍的疑问:不修改何来扩展?
高手与低手的差别就在于这里,高手往往看重的思想(即设计能力,,,识别架构和建立构架的能力,但是因为计算机能理解的设计只能是多范型设计,因此高手着重的这种思想往往也是受计算机实现的限制的设计),而低手考虑问题的第一切入点就是源码本身,因此产生“不修改源码何来功能扩展”的疑问也就很自然了
而其实,在高手的眼里,只要定义一些抽象,产生一些迂回就可以解决问题了,这些迂回(实际上就是产生一些高层逻辑,这些逻辑就是具体某个设计模式中的某些角色Acotr)可以让我们clients通过这些高层迂回避免直接接确到低层的实现(虽然我们client无论如何最终是要进入到具体实现的,但我们可以不直接而间接迂回地进入啊!!这些低层的实现就是现有代码了,是实现部分(可能是某个你要使用到的第三方库代码),我们经常要对实现部分修改,或者说对现有代码的修改,而要求要有最少的工作量,而一个没有定义抽象或者没有定义好合理抽象的工程要涉及到很多修改工作),而这,,真真实实就是解偶的意义所在。。
我们再来说这些逻辑,其实这些逻辑都可以称为中间逻辑,,然而这些逻辑的地位又是不同的,,有与具体实现接近的那一端的逻辑,,这些逻辑也是高层逻辑,,但是把与接近client使用者的逻辑看作为相对更高层的逻辑。。
说个故事吧!
《西游记》大闹天空时,要求当天庭大官,太白金星向玉皇献记说让孙悟空当弼马温,太白金星的智慧就体现了开闭原则,一方面,在孙悟空方面,太白向孙悟空说明玉皇已同意他上天(对扩展开放),,另一方面实际上只是给了他一个放马的差,实际上按天庭规则(系统原有结构)孙悟空是不能上天的(),然而迫于孙悟空的力量(修改的需要),太白只是稍微迂回了弯子(增加了一层抽象),就暂时平息了玉皇(玉皇本人不知道如何扩展这个需求,因为这是与天规相背的)和孙悟空二边.
8.13 真正的通米特原则
之所以不称通米特原则为通米特法则是因为在设计模式领域内实在不存在一个法则之说,
通米特法则也称为最小知识原则,一个事物对另外一个事物知道得越少,那么它本身就越安全(这可以联系武侠小说里小人物碰巧目睹了对杀手杀人的整个过程,那么这个小人物就会有杀身之祸,),
这里的安全是指对修改关闭
实际上无论对象组合还是继承都会造成类与类之间的引用,都会造成不可复用的问题,然而,相比继承来说,组合可以极大地减少这种复用的偶合程序,而继承压根就是不可分离的,因为本质上组合是一种Has-A的关系(组合对象与被组合对象),而继承关系是一种Is-A的关系(基类与继承类,或称父类与子类,注意这二个概念还是有点区别的,一般说到父与子关系时就是指父对象与子对象,而说到基类与继承类时往往描述类与类之间关系的用词~~)
还有一种关系是Link-A的关系,这种情况下的不可复用性按情况下来定,,Is-A的准确意思是什么呢(这里的意思指语义)?如B is a A,,那么“B是一个A”,,可能是一个A,但是不一定必定是一个A.而且如果B是一个A,,那么反过来就不能成立(子类化,虽然站在类型转换的场合下可以但是现实生活中这样理解不通)
一个代码的修改量应只取决于它最低层的实现,如果某个低层引用了过多高层逻辑接口的实现,那么这只能说明,对这个实现的解偶还没有规划到家,理想的情况是,应该只让这个实现的修改不触动到任何间接使用它的高层逻辑!!(因为自顶向下的引用对于顶来说,如果底部被修改顶部是不用作任何改变的,而如果是自底向顶引用,那么当底发生改变时,一定要涉及到顶部也要改变,,而这就是不恰当的高层抽象,违背了好莱坞原则和通米特原则) |
|