《松本行弘的程序世界》读书笔记(上)——面向对象、程序块、设计模式、ajax
1. 前言
半个月之前买了这本书,还是经园子里的一位网友推荐的。到现在看了一半多,基础的都看完了,剩下的几章可做高级部分来看。这本书看到现在,可以说感触很深,必须做一次读书笔记!
关于这本书,不了解的可以去网上查查。作者是Ruby语言的创始人,可谓是程序世界中的高手,开卷有益,不管你是哪个层次的编程人员,相信都能或多或少的汲取到你想要的营养。
下面将总结一下看完本书我记录下的一些知识点。有的是书中的原话,有的是我个人的理解,供参考。
2. 面向对象
2.1 多态性
面向对象三大原则:继承、封装和多态,其中最重要的技术是“多态性”,多态往往会用继承来表现,而封装又保证多态的独立性。多态性可以让程序只关注做什么,而不是关注怎么做。根据情况的不同,自动选择最合适的方法来处理。多态也是程序扩展性的基础。
2.2 历史
面向对象语言从60年代的Simula,到70、80年代的SmallTalk,直到后来的C++和java,java是最成功、应用最普遍的面向对象语言。本人用C#,和java差不多。UML是描述面向对象方法设计模型的图示方法(不会UML的抓紧补补吧,这也算是基础了)。
2.3 结构化编程
在很久很久以前,一些比较低级语言,是通过goto语句来执行代码的。C语言中有goto语句,一开始学的时候老师就不让用。goto语句是在出现if...else...(条件判断)和for、while等循环结构之前,人们用来控制程序的方法。大家试想,如果不让你用if..else..和for循环,通篇都是goto,那将会是什么结果??所以,用【顺序】、【条件】和【迭代】来代替goto语句,是程序开发的一大变革。
另外提一句,如果你从事.net开发,你可能有幸解除到goto语句——IL中间语言,IL相当于.net中的汇编预研。将一个简单的 if..else...编译成IL之后,结果如下:
2.4 数据抽象化
前面讲到程序结构从goto语句中解放出来,那么程序所操作的数据结构呢?也需要有一种抽象的表达方式,而不是计算式世界所能理解的二进制代码。最常见是我们常用的数组、链表、字典等结构。其实,严格来说,程序中的整数、浮点数、各国的语言文字,都是数据抽象的结果。因为计算机只认识二进制字符串。
2.5 多重继承
如果你是一名java、C#开发人员,你用不到多继承,因为他们根本就不提供。但是有些语言是支持多继承的,C++、python。现实世界中需要多继承,例如以为程序员同时也可能是一位作家,一个部门经理同事也可能是一位父亲。但是多继承如果开放到程序中,就会带来许多问题。允许一个类有多个父类,复杂度可想而知,因此java禁止使用。但是它用什么来弥补这一缺失——接口interface。
至此,大家要了解接口是因为什么才来到这个世界——因为弥补进制使用多继承而带来的问题。但是接口真的能很好的解决这个问题吗?不见得。因为接口毕竟不能像父类那样使用。
Ruby中没有接口(不是所有面向对象语言都有接口的),它通过引用程序块的方式来实现多继承。我没有深入了解Ruby的这块功能,有兴趣的朋友可以研究。
2.6 面向对象是现实世界中具体事物的反映吗?
作者认为,对“面向对象”最好的解释是“对数据的结构化”。前文讲到结构化编程是将程序流程分为顺序、条件和循环三种结构,而面向对象则是在此基础上的延伸,它将程序处理的数据进行了结构化。通过对象来组织数据,数据就成为一个整体,而不再松散。
这是面向对象最根本的意义,如果理解这一点,那么是否反映现实世界就不重要了。其实像数组、字符串,你也找不出现实世界的什么东西与之对应。
程序是处理抽象数据的。无论以后学习什么技术,都不要满足于小猫小狗之类的例子。
另外,关于“继承”,也不要看成是现实世界的真实反映,它就是一些抽象、公用功能的重用方法,这样反而更好理解。
2.7 静态语言 VS 动态语言
这里所谓的静态和动态,指的是数据类型的强弱。例如C#、java就是强类型,js、Ruby就是弱类型。强类型中,每个变量都有明确的数据类型,不能更改,也不能赋其他类型的值,要不然会报错。而在若类型中,变量的类型是随着其存储值动态改变的。
两者各有好坏。强类型可以在编译时识别类型错误,程序执行的速度会更快,但是不灵活。弱类型灵活,但是有些潜在的错误不容易发现。
我恰巧C#和js都用,在我看来,这两种方式都可以,只要你认真对待,哪个都不会出现大问题。所以了解即可,不必太纠结到底哪个好。
3. 程序块
3.1 闭包
“闭包”这个词,我是在js中第一次接触的。不过看来业界通用这个词汇,大体意思就是应用外部的变量和环境,和js中一样。作者提到Ruby中可以通过传递程序块的方式实现闭包,我没有仔细去看细节。不过读到这里,我想起了以下几点:
01. jQuery源码中用到了大量的闭包,了解到js中的闭包会影响到性能和内存。所以,我以后将会非常注意jQuery中闭包的使用,真正深入了解闭包;
02. C语言的函数指针是闭包吗?
03. C#和java中,哪些用到了闭包?
以后再遇到这种问题、知识点,将关注以下。
3.2 for循环
Ruby中实现for循环的方式是 obj.each(....) 这种方式,和jquery的each循环类似。作者在本章节的后面提到“不用for语句”,因为for语句会破坏对象的封装性。其实这一点在设计模式中也有专门的解决方案——迭代器模式。
4. 设计模式
首先,书中没有一个一个挨着讲每个设计模式。有兴趣可以看看我写的关于设计模式的博客:
大家最好要知道,“设计模式”一词来源于建筑业(曾经是我比较向往的专业,呵呵)。大家常说的设计模式,一般是指《设计模式.可复用软件的基础》一书中提到的二十三中设计模式,作者们是GoF。其实这些设计模式并不是作者们创新出来的,而是他们总结当时日常设计工作中,最常用的23中模式,给他们分组、取名,最后成就了一部伟大的作品。所以,GoF做出的贡献就是将原本没有名字的东西,给他们起名字,并让他们成为结构化的知识。这是件很了不起的事,例如美国PMI将日常项目管理工作总结为10大知识领域5大过程组一样。
4.1 设计模式和类库
类库是把常用的算法、接口封装起来,供系统其他模块使用,或者供其他系统使用,它可以“0成本”重用的。但设计模式的重用,却不是“0成本”,它是一个很抽象的东西,你要根据实际情况来具体确定。
4.2 开放-封闭 原则(简称:OCP)
业界有5大设计原则,其中最重要的就是“开放-封闭原则”——即对扩展开放、对修改封闭。了解设计原则可以查阅:换种思路去理解设计模式(上)
这里所谓的“对扩展开放”,在面向对象编程中是通过继承和多态来实现的,继承允许功能的添加,多态保证接口的稳定性。从实用主义的观点来看,面向对象的精髓就在于对OCP的实践。至于把对象看做物体理解起来比较容易,能够建立现实世界的模型等,只不过是一些锦上添花的东西。
一个优秀的设计模式,肯定能经得住OCP的考验!
5. Ajax
ajax是web开发中比较基础的东西,基本概念此处不再赘述。
5.1 Ajax中的“x”
“x”指的是“XML”。因为在ajax刚开始用的时候,都是用xml格式来传递数据,因此xml也被说成是ajax的基本部分之一。但是现在随着json越来越流行,xml的用武之地越来越少,高版本的浏览器直接支持JSON转换接口。
所以,此处了解即可。开发时该用什么用什么。
5.2 javascript——基于对象的语言
可能你会经常听到:js是以对象为基础的语言,所有的数据都是对象,js是基于原型的语言。对,js中没有“类”的概念,除了基本的值类型之外,其他的数据都以对象来处理,都可以自定义添加属性,包括函数。js是通过原型来实现所谓的继承的。
另外,js中的闭包是比较出名的,闭包在js中的应用很多,jQuery源码中大量使用闭包就是个例证。
这两个问题,不是一两句话能说明白的,说实话我现在感觉自己知道一些,但是了解的不是很透彻。不过正在努力的补充。要想把js的“对象”和“闭包”讲明白,我想还需要从其他方面下手,将会是一个比较系统的工程。后期我定会搞定它们,并以某种方式讲出来。此处点到为止。
6 MVC和“猴子补丁”
6.1 MVC
感觉作者本文中只是讲述了MVC这个理念,并用小例子解释。由于我没有真正参与过MVC的项目,也只是日常的了解,所以对这块感触不是很深。
6.2 猴子补丁
所谓的“猴子补丁”,其实就是C#中的部分类和扩展方法。在不改变原来代码结构的基础上,添加新代码。个人不建议这种做法,如果重复这样做,将会导致代码松散难以维护。
-----------------------------------------------------------------------------
推荐一下我录制的《asp.net petshop4.0源码解读》教程,免费学习!
-----------------------------------------------------------------------------
今晚先到这里,明天继续写:
7. 文字编码
8. 正则表达式
9. 整数与小数
(个人感觉“文字编码”和“整数与小数”两章,作者介绍的很好)
《松本行弘的程序世界》读书笔记(下)——文字编码、整数、浮点小数