Chinaunix首页 | 论坛 | 博客
  • 博客访问: 271193
  • 博文数量: 88
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 840
  • 用 户 组: 普通用户
  • 注册时间: 2014-04-20 21:13
文章分类

全部博文(88)

文章存档

2022年(1)

2017年(1)

2016年(2)

2015年(1)

2014年(83)

分类: IT业界

2014-06-30 22:10:42

关于观看《编程方法学》系列视频的一些感受。

我看了视频和与卡雷尔学java相关的几个pdf,明白了这个课程讲的其实是编程思维和方法。

这个课程使我对一些思想有了一定的思考。关于面向对象,就是把程序根据功能模块划分成很多的小单元,以达到复用和增加可读性,现代语言如java就强调了这种编程方式,即面向对象模式。在面向对象的模式下,程序员的注意力从程序的结构转移到构建模块和抽象行为上面。在“卡雷尔学java”程序中,我们看到卡雷尔懂的仅仅是一些基本动作,我们毫无疑问可以直接写一个结构化程序,从头到尾,从上到下逐步求精。但是我们使用卡雷尔来编程时,自然的就把卡雷尔当成了一个人,它在走路,我们用对象的方式去思考。卡雷尔有自己的属性,也有自己的一些方法即动作,当然还可以扩展很多复杂的动作。

另外,使用这个程序去编程和结构化的控制台程序有很大的不同,例如在迷宫算法中,如果使用控制台程序来写,则是采用坐标来控制卡雷尔的行动,应该采用回溯法寻路和栈来存路线。但是面向对象下,就可以有很不同的思考方式,我们发现卡雷尔可以每走一步就做一次判断,就像真实的人一样,它可以一步一步地走,如果发现自己走错了,可以走回去,走出错误的圈子去。在面向对象中,一个简单的向右转、向左转的动作,在结构化程序中就要使用复杂的坐标来表示,而且坐标很僵硬。

关于程序中功能的划分,我觉得应该尽可能的保持定义私有化,总体来说是一个好的编程习惯。在有机会为大项目工作之前,这么做的理由,很难体会到。但是,基础的思想是,这些类应该试着尽可能多的封装信息,这意味着这些类不仅可以聚集在一起工作,而且尽可能的限制(这些类之间互相的)访问信息。大型程序在它们包含的项目的细节数量上很快变得非常复杂。如果一个类被设计的很好,它将通过隐藏尽可能多的额外信息来寻求降低系统的复杂性。这种属性被称为信息隐藏,是面向对象哲学的一块基石。“卡雷尔学java”就很好的阐释了这一点,有些属性我必须使用对应的函数才能获得,我确实不明白!这就是开闭原则的体现吧。

我从文档上了解到如何分解程序的问题。选择一个适当的分解,将变成编程中比较困难的一个方面。但是,在一定程度上依赖以下原则:

1.每一个子问题应该执行一个在概念上是很简单的任务。一个子问题的解决方案也许需要许多条命令,也许在内部操作条件方面相当复杂。即便如此,它最终应该完成一些在概念上容易描述的任务。如果你给出的动作名字能成功的概括出一个合理的任务,是一个好迹象。如果你可以通过一个简单的描述性名称,准确的定义(这个动作)它的作用,你可能已经选择了一个很好的分解方案。另一方面,如果你最终使用了像 approachAndFillPothole 这样的复杂名称,这个分解方案不像有前途。

2.每个子问题应该执行尽可能具有通用性的任务,这样,这个(子问题)就可以在几个不同的场景下调用。如果一个分解方案的结果只能在一个特定的场景中使用,而手上的另一个在几个不同的相关场景中都能工作的同样好,你应该选择更通用的那个。

把起初的一个问题,分解为许多要解决的小问题,这叫自上而下设计或逐步求精,它是出自软件工程的,最重要的方法论发展。你把整个问题分解成小块,然后解决每一块,如果有必要,那些分解的块还需要进一步的分解。

从我的实践来看,宏观上的功能划分通常不会有太多问题,但是到了细节上,比如是用一个方法还是用几个方法实现或者构造新的类,这个时候,通常会疏忽。很多时候,在拿到任务以后,通常没有更深的思考就冲着完成功能去了。比较悲惨的结果就是写了一个巨大无比的方法,几百行的代码,若干循环分支嵌套,纵然是用visio画的图也是密密麻麻,让人眼花缭乱。这时候再写什么样的注释,别人,甚至自己都无法完全看懂。有时候会通过一些硬性规定来避免这样的情况,比如,每个方法或者函数不能超过150行之类的。这样会有一些效果,但是,更多的时候,应该思考下,有没有更好的方法。

最后就我大学里面学的C、C++、JAVA谈一下对编程方法论的理解。毫无疑问,这个课程中“卡雷尔学java”部分就是用来训练不会编程的学生来练成一种编程思维的。即把一切问题的解决,步骤化,模块化,复杂一点的,就是控制,复用,循环。如此下来,我不禁要问,编程真的有那么难吗?无非就是把一个问题按照上面所说的进行分解,得出详细的步骤而已。但是,觉得大部分人都编不出很实用的程序。究其原因,就是当问题变得复杂时,事情就不那么简单了。

首先是数据的结构,这个其实和建模非常相关。我们要解决现实世界中的问题,就要使计算机能明白这个现实世界的东西,所以就有了数据结构。我们常常说抽象出事物的主要特征,那么什么是主要特征?怎么就知道它是主要的了?这就和我们要解决的问题有关,例如处理年龄问题的程序就不会关心身高。所以说,哲学思想中,“物有本末,事有终始。知所先后,则近道矣。”得到了体现。我们只关心相关的东西。

再者就是组织这些相关的东西,就是结构体。最早的结构化编程就是这么说的。在这类学者的眼中,数据是死的。他们把数据看成是仅仅比加减乘除的对象稍微复杂一点的东西。

再后来,学者们觉得结构体还是不能很好的表示这个世界。我们知道,在结构化程序(典型的C语言)中,函数几乎就是最重要的东西。可以说没有函数就没有一切。所以,后来又发展出来了一些新的语言,如C++,他的想法其实很简单,就是把函数组合到结构体中,然后给这种结构体一个新的名字,叫类;当然还有一些其他的语言,例如函数式语言,现在有很多函数式语言把函数体当第一参数,第一变量,即闭包特性,如后来的Javascript,python等。这些都是编程方法的发展,随着不同的学者的不同想法,设计出的不同的语言。但是毫无疑问,他们都非常重视函数。这就说明,编程方法学中最最重要的就是不断的做模块,做函数体,这几乎变成了主要任务。

所以,我们会发现数据结构最终变得相当复杂了,随之而来的就是操作和组织这些数据结构的方法,亦即算法。两者综合起来,问题就变得更为复杂了。当然,我们写程序并不会总是遇到这么变态的问题。

我给我自己已经遇到的问题分个类,基本分为web网站和客户端程序。Web网站涉及到许多技术,面临许多问题,我们先只谈相关的数据结构。Web网站的主题是什么呢?毫无疑问,就是html页面,也就是超级文本。别管什么乱七八糟的web技术,定然离不开一个核心的内容,html页面。

Html页面的内容就是无格式文本。所以,数据结构就是字符串了。现代的网络编程语言java和C#,还有脚本语言Javascript,python等都提供了超强的字符串处理函数,甚至出现了正则表达式这种极其高效的处理字串的技术。对字符串的处理,如粘贴,链接,复制,截断,萃取,特征匹配等等操作。我发现,编写语言的高手都已经帮我们写好了,囧。难道我们的脑筋就不用再去为这种事纠结了么?也许是的,至少目前为止,我觉得自己还没有对这些技术彻底掌握的清清楚楚。编程方法学的另一个很不好的地方就是,走自己的路,让别人无路可走。学者们都把东西写好了,后来者不就是直接“酱油”了?(当然也有例外,Oracle告Google侵权,抄袭其JAVA的库函数代码。同行的互相监督显得很重要)我觉得到了我们真正处理某个工程时,其实并不愿意把时间花费在处理字符串的连接上面,那样看起来显得避重就轻了。我们更关心页面之间的跳转,传值,读写文件,以及软件的稳定性,健壮性,容错性,响应速度等等。这些其实已经和单纯的编程无关了。

那么编程方法学就毫无贡献吗?毫无疑问,是有的。软件的稳定性,健壮性,容错性除了和所使用的容器息息相关,更加和我们自己的代码相关。但问题规模较小较简单时,对数据结构其实没有特别高的要求,如我上面说的那样。但是,但问题的规模变得较大较复杂之后,对数据结构和算法的良好掌握的优势就发挥出来了。

例如,现在电信公司要给500万个电话号码排序,然后进行一定的操作。这种情况下,使用什么数据结构来存储呢?我的想法就是借鉴No-SQL数据库的结构,使用哈希表来存储,哈希表是比较高效的。这时就要求我们掌握这种比较复杂的数据结构,并且采用高效的排序算法。显然,使用库函数会引发灾难,也许几百年之后才会排得出结果。这时就需要我们自己思考和优化算法了。

和这个类似的问题,还有高并发量的处理,大数据的分析。如,某一秒钟,对服务器的请求达到1000万,怎么处理?用库函数显然是不能解决的,这个甚至需要自己来编写专门的服务器来进行处理。所以,这时,算法和数据结构的威力就发挥出来了。

另一个方面,要谈一下面向对象思想和软甲架构等思想对软件编程方法学的影响。为了使程序的力量更加强大,软件架构是值得思考的。当我们编写的程序只有10行时,我们必然不必想太多架构的东西。但是,若软件的模块有1000个,设计的表有100多张,而且它们之间还有各种复杂的关联,不对架构进行精心的设计,肯定是不行的。因为编写的效率到后期会越来越低,甚至会觉得根本无法写下去,那不是编程而是折磨了。

随着我对设计模式的学习的深入,我觉得,编程方法这个东西确实是值得思考的。而且,JAVA语言以我的观察,在设计时本身就大量吸收了设计模式的精华。比如,观察者模式,在JAVA中就对应有Observer类;原型模式,在JAVA中就有根类的clone()方法的支持;再比如独一无二的反射机制等等。可以说,JAVA这个语言和设计模式几乎是二位一体的,两者息息相关。

最后,我们可以看到,编程方法论,编程方法学的发展随着我们处理问题的复杂性的加强而向前迅猛发展。学好编程,第一,要对数据结构,对算法应该要很好的掌握;其次,在思想上,还应该学习软件架构相关的知识;再其次,要熟练掌握前人已经做好的技术和语言。最后,要懂一点,计算机相关的技术,会使用各种软件——我指的是服务器、开发工具这一类等。

做好这几点,则应该算是比较懂得编程方法,在软件工程学上有一定的造诣了。

阅读(1030) | 评论(0) | 转发(0) |
0

上一篇:Ruby没有Python好

下一篇:关于Arraylist的容量

给主人留下些什么吧!~~