Showing posts with label 读书. Show all posts
Showing posts with label 读书. Show all posts

Jan 6, 2009

读《破解咨询的40个困惑》

正好赶在马哲考试前,复习这门课显然是浪费时间;可开始看投资又有点不靠谱,毕竟马哲还没考完,不用紧张兮兮。于是看了Alan Weiss的《破解咨询的40个困境》一书。我觉得书写得蛮好,可意外的是几乎没有什么名气,也许是因为作者只是个自由职业者,没有有名气的公司做后台;也许又是因为出版社推广不力的缘故吧~从这本书里我了解了关于咨询的很多东西,从工作生活到待人处事都一些,而且都说得很实在。咨询也是做项目,软件开发也是类似,结合起来看更有心得。由于找不到其他的现成笔记,下面的笔记都是我自己整理的。当然,目录是copy的。

第一篇 应对营销挑战


第1章 缺乏行业经验

做一个流程顾问而非内容咨询顾问

第2章 细分市场过小
自身or外部环境?
通往死胡同的标志:相同的客户,老一套的方法,在狭窄的领域越走越窄。
生活中似乎也是如此?
保持现有市场,积极开拓:密切相关的领域,关联性领域,可转换的技能
技术学习?
商业敏锐性

第3章 资源匮乏
虚拟?
与能提供帮助的专业性人士建立长期的联系
对于“专业性人士”来说呢?
值得信赖的跑腿人员
生活中的维护,水电煤?
培育客户

第4章 远程营销成本
预支费用
有自己的标准
把握收款时机

第5章 知名度不高
名字,媒体,开发产品
啥时写本书?……

第6章 项目来源渠道枯竭
了解营销渠道
被动销售?销售自身。
要看些销售的书籍
优势--财富;邮件名单;做项目的同时,请他们推荐;敏锐的嗅觉;维护人际关系网。
我的弱项

第7章 经济低迷或经济发展不确定时期

不景气的相对性,经济危机了,网游不更火了么!
任何情况下都运行良好的企业;茅台?
曾经一起工作过;希望与之一起工作的人
营销推广
考虑新的机会
即不要逆流而上,也不要顺流而下

第8章 如何持续赢得咨询项目
一些征兆,拒绝不是坏事,满口应承才是坏事
欲速则不达,行动太快会吓着别人。交往--达到互信--其他与人交往也是这样吧~
1.下次见面的日期
2.打电话不超过三次
3.每打次电话都发送一封Email
4.较短的时间内不要采取后续行动

第9章 差异化的困境
a.避免使用专业术语
b.给自己定位
c.著书立说
d.创立一个或更多的品牌
e.使用你的名字
坚持!

第10章 自我定位不准确或定位不适时
激情!

第二篇 应对销售挑战

第11章 价格竞争
不良做法:公开收费标准,采用按天收费的方式,在提交项目建议书前讨论收费标准,屈服于压力,与非真正的客户打交道,严格遵守《项目招标书》规定?询问预算,高估竞争对手,无法提供独特的方案,无法和客户建立联系
用价值衡量价格!

第12章 《项目招标书》(RFP)
规避

第13章 害怕和恐惧
自尊和无畏,建立互利互惠、平等的关系
着装得体,谈吐得体,运用幽默,不要无事道歉,尽量选择合适的位置坐好,做准备工作,予以还击,展现智慧,主动出击,绝不胆怯

第14章 咨询项目价格过低
原因? -- 保持敏感性并尽量避免 -- 摆脱
重新讨论遗漏的情况
重新确定能给客户提供的价值
将差异化的因素转换成或有费用
考虑放弃

第15章 “中间人”和设置障碍者
中间人--可能的买家 对求职者来说,也许是HR?
与中间人建立关系的目的只是为了确定谁是真正的客户
合理的借口?晓之以情动之以理。

第16章 项目启动时间推迟

第17章 无人答复/无人回电
如何避免:做好准备工作,提出有价值的建议,有利的证明和认可的依据,制造紧迫感
确实对方回电的最好方法是提及双方都熟悉的第三方
积极跟进而非纠缠不清

第18章 避免拙劣的“推销方式”
不要想当然地认为对方已经“病入膏肓”
不要操之过急
不要自我辩护
问一些引人深思的问题
在你的例子中利用潜在客户所处环境的因素
让买卖双方共同进行诊断
不要使用任何技术?
用你曾经经历过的例子来解释你要做的事情,不断联系
将球踢给对方
准备好走人
前几条很像求职的注意事项,毕竟求职就是推销自我,真诚第一!
谈论客户需要的结果,而不是咨询方法
要表现出你了解客户的情况,了解其所在的行业和竞争的情况
尽可能保障这种会谈是互动性质的
逻辑使人思考,情感使人行动

第19章 客户让低层人员应付你
绝不主动或被动地离开客户!
避免被降级的预防措施:
不要太快地进入推销模式
专注与客户建立关系
强调公司目标的同时,也要强调其个人价值
提及已经合作过的其他客户,最好这些客户与潜在客户处于同一级别
必须让客户把你视为同等的人

第20章 跟进工作不得力

第三篇 应对项目运作挑战

第21章 提防暗中破坏者
修正的原因是出现了失误,失误导致推卸责任和可能的不合作

第22章 咨询范围不断扩大
软件开发中的需求管理是同样的道理,也许是项目的共性之一
达成共识,采取预防措施;
应付偶然出现的范围扩大现象

第23章 应对国际挑战

第24章 客户方发生意外变化并造成损失
最初的反应--启动紧急预案
查明发生了什么,联系客户,拟定新的有价值的项目建议书,有坚强的意志力
随后的反应--组织资源
改正和修补,适应和调整,应对和接受

第25章 项目失败
分析可能的原因:目标,客观因素,主观因素
总结经验教训

第26章 客户未能实施项目
咨询顾问 客户
精简人员 解雇部分员工
改组 降低部分员工的级别
引进技术 降低当前利润
设定职责 提供负面的反馈意见
以身作则 改变舒适的行为方式
倾听 接受负面的意见
需要站在对方的角度思考问题,在自己看来理所当然,在对方看来也许艰难。

第27章 应对“公司政治”

第28章 未能就进展和贡献与客户达成共识

第29章 客户“空头支票”式的支持
为什么会有空头支票?也许是内心害怕

第30章 项目管理挑战
变化--唯一不变的就是变化!

第四篇 应对咨询管理挑战


第31章 现金流
税前税后问题

第32章 学习和进步
终身学习,学习如何学习,而不是被教
持续学习的四个维度:带着理解读;带着感情写,带着感情说;带着鉴别听

第33章 客户拖延付款

第34章 日常管理费用及利润
为什么不应该雇人--这些理由在中国也许不是理由

第35章 知识产权遭剽窃

第36章 生病与残疾

第37章 出差食宿行及生活质量

第38章 合理合法避税
不是你赚了多少,而是你省了多少
争取最有利的缴税计划

第39章 不断出现新技术
分清潮流和趋势

第40章 生活目标及平衡

没有完美的平衡

Jan 5, 2009

读《点击世界顶级咨询公司》

今天看了《点击世界顶级咨询公司》一书,主要想对这个行业多一些了解。草草看完后的确有一些收获。在咨询公司中能接触到很多案例,能锻炼与人交往的技能,能接触到一些新的东西,不断地追求专业,在自我提升的同时也能为社会创造尽可能多的价值,得到客户的认同。这和我的目标是吻合的。

在公司方面,这本书介绍了进十家世界性的咨询公司,其中在信息技术咨询方面,IGS(IBM全球服务),Accenture(埃森哲),EDS(Electronic Data System + 科尼尔),PWC(普华永道),HPC(惠普咨询)这五家公司在做的尤为突出,需要多加关注。据书中说,PWC在美国是十佳IT雇主,普华永道成了IT公司?IGS全球有13w+的雇员,占IBM全球雇员数的一半以上?真正的服务为王!IT并非只意味着技术,IT是为了创造价值!然后查了下IGS,HPC的招聘,IGS在招很多掌握Oracle和SAP技术的人员,这也许说明领先的服务型IT企业已经超越了产品技术的壁垒,而是以为客户提供整合的产品和价值作为自己的目标。

BI这类专业性强且和业务紧密相连的技术方向很可能成为将来信息系统咨询的热点,在ERP整合了企业的业务后,BI也许将在企业信息整合上发挥重要作用;同时在IGS的招聘职位上,我也发现了对BI人才的较大需求。这也许是个不错的方向。

Dec 21, 2008

《Head First 设计模式》9-13章

Chapter 9:迭代器和组合模式--管理良好的集合
我们能学习如何让客户遍历你的对象而又无法窥视你存储对象的方式;也将学习如何创建一些对象超集合,能够一口气就跳过某些让人望而生畏的数据结构;还将学写到一些关于对象职责的知识。

迭代器模式:提供一种方法顺序访问一个聚合对象中的各个元素,而不是暴露其内部的表示。
迭代器模式让我们能游走于聚合内的每一个元素,而不是暴露其内部的表示。
把游走的任务放在迭代器上,而不是聚合上。这样简化了聚合的接口和实现,也让责任各得其所。

设计原则:一个类应该只有一个引起变化的原因。
类的每个责任都有改变的潜在区域。超过一个责任,意味着超过一个改变的区域。
这个原则告诉我们,尽量让每个类保持单一责任。

组合模式:允许你将对象组合成树形结构来表现“整体/部分”层次结构。组合能让客户以一直的方式处理个别对象以及对象组合。
组合模式让我们能用树形方式创建对象的结构,树里面包含了组合以及个别的对象。
使用组合结构,我们能把相同的操作应用在组合和个别对象上。换句话说,在大多数情况下,我们可以忽略对象组合和个别对象之间的差别。
统一处理个别对象和组合对象。



空迭代器
NullIterator,返回一个迭代器,而这个迭代器得hasNext永远返回false。

要点
迭代器允许访问聚合的元素,而不需要暴露它的内部结构。
迭代器将遍历聚合的工作封装进一个对象中。
当使用迭代器的时候,我们依赖聚合提供遍历。
迭代器提供了一个通用的接口,让我们遍历聚合的项,当我们编码使用聚合的项时,就可以使用多态机制。
我们应该努力让一个类只分配一个责任。
组合模式提供一个结构,可同时包容个别对象组合对象
组合模式允许客户对个别对象以及组合对象一视同仁。
组合结构内的任意对象称为组件,组件可以是组合,也可以是叶节点。

在实现组合模式时,有许多设计上的折中。你要根据需要平衡透明性和安全性


Chapter 10:状态模式--事务的状态

策略模式和状态模式是双胞胎,在出生时才分开。


策略模式是围绕可以互换的算法来创建成功业务的。
状态模式通过改变对象内部的状态来帮助对象控制自己的行为。
1 定义一个State接口。在这个接口内,糖果机的每个动作都有一个对应的方法。
2 然后为机器中的每个状态实现状态类。这些类将负责在对应的状态下进行机器的行为。
3 我们要摆脱旧的条件代码,取而代之的方式是,将动作委托到状态类。


状态模式:允许对象在内部状态改变是改变它的行为,对象看起来好像修改了它的类。
要点
状态模式允许一个对象基于内部状态而拥有不同的行为。
和程序状态机PSM不同,状态模式用类代表状态。
Context会将行为委托给当前状态对象。
通过将每个状态封装进一个类,我们把以后需要做的任何改变局部化了。


状态模式和策略模式有相同的类图,但是它们的意图不同
策略模式通常会用行为或算法来配置Context类。
状态模式允许Context随着状态的改变而改变行为。
状态装换可以由State类或Context类控制。
使用状态模式通常会导致设计中类的数目大量增加。
状态类可以被多个Context实例共享。


Chapter 11:代理模式--控制对象访问


你是一个白脸,提供很好且很友善的服务,但是你不希望每个人都叫你做事,所以找了黑脸控制对你的访问。


控制和管理访问,这就是代理要做的事。
你的客户对象所做的就像是在做远程方法调用,但其实只是调用本地堆中的“代理”对象上的方法,再由代理处理所有网络通信的低层细节。
1 先浏览并了解一下RMI。
2 我们会把GumballMachine变成远程服务,提供一些可以被远程调用的方法。
3 我们将创建一个能和远程的GumballMachine沟通的代理,这需要用到RMI。
4 最后再结合监视系统,CEO就可以监视任何数量的远程糖果机了。


方法调用是如何发生的
1 客户对象调用客户辅助对象的doBigThing方法。
2 "客户辅助对象打包调用信息(变量,方法名称等),然后通过网络将它运给服务辅助对象。"
3 服务辅助对象把来自客户辅助对象的信息解包,找出被调用的方法(以及在哪个对象内),然后调用真正的服务对象上的真正方法。
4 服务对象上的方法被调用,将结果返回给服务辅助对象。
5 服务辅助对象把调用的返回信息打包,然后通过网络运回给客户辅助对象。
6 客户辅助对象把返回值解包,返回给客户对象。对于客户来说,这是完全透明的。


RMI提供了客户辅助对象和服务辅助对象,为客户辅助对象创建和服务对象相同的方法。


制作远程服务
1 制作远程接口
2 制作远程的实现
3 利用rmic产生的sub和skeleton
4 启动RMI registry(rmiregistry)
5 开始远程服务

远程代理;虚拟代理:暂时代理初建开销大的对象


代理模式:为另一个对象提供一个替身或占位符以控制这个对象的访问。
使用代理模式创建代表representative对象,让代表对象控制某对象的访问,被代理的对象可以是远程的对象,创建开销大的对象或需要安全控制的对象。
 


要点

代理模式为一个对象提供代表,以便控制客户对对象的访问,管理访问的方式有许多种。
远程代理管理客户和远程对象之间的交互。
虚拟代理控制访问实例化开销大的对象
保护代理基于调用者控制对象方法的访问。
代理模式有许多变体,例如:缓存代理,同步代理,防火墙代理和写入时复制代理
代理在结构上类似装饰者,但是目的不同。
装饰者模式为对象加上行为,而代理则是控制访问。
Java内置的代理支持,可以根据需要建立动态代理,并将所有调用分配到所选的处理器。
就和其他的包装者wrapper一样,代理会造成你的设计中类的数目增加。

Chapter 12: 复合模式--模式中的模式
谁料得到模式居然可以携手合作?

模式常被一起使用,并被组合在同一个设计解决方案中。
复合模式在一个解决方案中结合两个或多个模式,以解决一般或重复发生的问题。

设计模式是MVC的钥匙。
MVC是由数个设计模式结合起来的模式。如果你能够看着MVC内部的各个模式,MVC的一切就会跟着开始明朗起来。

要点
MVC是复合模式,结合观察者模式策略模式组合模式
模型使用观察者模式,以便观察者更新,同事保持两者之间的解耦。
控制器是视图的策略,视图可以使用不同的控制器实现,得到不同的行为。
视图使用组合模式实现用户界面,用户界面通常使用嵌套的组件,像面板、框架和按钮。
这些模式携手合作,把MVC的三层解耦,这样额可以保持设计干净,又有弹性。
适配器模式用来将新的模型是配成已有的视图和控制器。
Model2是MVC在Web上的应用。
在Model2中,控制器实现成Servlet,而JSP/HTML实现视图。
迎接一个充满设计模式的崭新世界。

Chapter 13:与设计模式相处--真实世界中的模式

模式是在某种情境(context)下,针对某问题的某种解决方案。
情境就是应用某个模式的情况。这应该是会不断出现的情况。
问题就是你想在某个情境下达到的目的,但也可以是某情境下的约束。
解决方案就是你追求的,一个通用的设计,用来解决约束,达到目的。
如果你发现自己处于某个情境下,面对着所欲达到的目标被一群约束影响着的问题,然而,你能够应用某个设计,克服这些约束并达到该目标,将你领向某个解决方案。

反模式告诉你如何采用一个不好的解决方案解决一个问题。

要点
让设计模式自然而然地出现在你的设计中,而不是为了使用而使用。
让设计模式并非僵化的教条;你可以依据自己的需要采用或调整。
总是使用满足需要的最简单解决方案,不管它用不用模式。
学习设计模式的类目,可以帮你自己熟悉这些模式以及它们之间的关系。
模式的分类或类目是将模式分成不同的族群,如果这么做对你有帮助,就采用吧!
你必须相当专注才能够成为一个模式的作家;这需要时间也需要耐心,同事还必须乐意做大量的精化工作。
请牢记:你所遇到大多数的模式都是现有模式的变体,而非新的模式。
模式能够为你带来的最大好处之一是,让你的团队拥有共享词汇。
任何社群都有自己的行话,模式社群也是如此。别让这些行话绊着,在读完这本书之后,你已经能够应用大部分的行话了。

剩下的模式

桥接模式 Bridge Pattern
不只改变你的实现,也改变你的抽象。
生成器 Builder Pattern
使用生成器模式封装一个产品的构造过程,并允许按步骤构造。
责任链 Chain of Responsibility Pattern
当你想要让一个以上的对象有机会能够处理某个请求的时候,就使用责任链模式。
蝇量 Flyweight Pattern
如想让某个类的一个实例用来提供许多虚拟实例,就使用蝇量模式。
解释器 Interpreter Pattern
使用解释器模式为语言创建解释器。
中介者 Mediator Pattern
使用中介者模式来几种相关对象之间复杂的沟通和控制方式。
备忘录 Memento Pattern
当你需要让对象返回之前的状态时,就使用备忘录模式。
原型 Prototype Pattern
当创建给定类的实例的过程很昂贵或很复杂时,就使用原型模式。
访问者 Visitor Pattern
当你想要为一个对象的组合增加新的能力,切封装并不重要时,就使用访问者模式。

Dec 20, 2008

《Head First 设计模式》5-8章

Chapter 5: 单件模式
独一无二的单件模式:用来创建第一无二的,只能有一个实例的对象的入场券。有些对象之需要一个:线程池、缓存、对话框、偏好设置、日志。。。
静态全局变量(一开始就创建号) <--> 单件模式(可以在需要时再创建对象)
单件模式:确保一个类只有一个实例,并提供一个全局访问点。


JVM多线程
同步
:synchronized --> 可能造成执行效率的下降
急切实例化:定义时创建
双重检查加锁:volatile -- Java 5

要点

单件模式确保程序中一个类最多只有一个实例。
单件模式也提供访问这个实例的全局点。
在Java中实现单件模式需要私有的构造器,一个静态方法和一个静态变量。
确定在性能和资源上的限制,然后小心地选择适当的方案来实现单件,以解决多线程的问题(我们必须认定所有的线程都是多线程的)
如果不是采用第五版的java2,双重检查枷锁实现会失效。
小心,你如果使用多个类加载器,可能导致单件失效而产生多个实例。
如果使用JVM1.2或之前的版本,你必须建立单件注册表,以免垃圾收集器将单件回收。

Chapter 6: 命令模式--封装调用
这些绝密文件的投递箱已经促成了间谍工业的革命。我只要把需求丢进去,就有人会消失,政府一夕之间改朝换代,而我的干洗衣物也好了。我不必管何时何地或者如何完成,反正就是完成了。
在本章,我们把封装带到一个全新的境界:把方法调用封装起来。

命令模式:
将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。



命令对象将动作和接收者包进对象中。这个对象只暴露出一个execute()方法,当此方法被调用的时候,接收者就会进行这些动作。
NoCommand对象是一个空对象的例子。当你不想返回一个有一一的对象时,空对象就很有用。
客户也可以将处理null的责任转移给空对象。

命令模式的更多用途

队列请求:命令可以将运算快打包(一个接受者和一组动作),然后将它传来传去,就像是一般的对象一样。
日志请求:store(); load(); execute(); undo()
宏:顺序地执行execute();

要点
命令模式将发出请求的对象和执行请求的对象解耦
在被解耦的两者之间是通过命令对象进行沟通的,命令对象封装了接受者和一个或一组动作。
调用者通过调用命令对象的execute发出请求,这会使得接收者的动作被调用。
调用者可以接受命令当参数,甚至在运行时动态地进行。
命令可以支持撤销,做法是实现一个undo方法来回到execute被执行前的状态。
宏命令是命令的一种简单的延伸,允许调用多个命令。宏方法也可以支持撤销。
实际操作时,很常见使用聪明命令对象,也就是直接实现了请求,而不是将工作委托给接收者。
命令也可以用来实现日志和事务系统。
Chpater 7:适配器模式与外观模式--随遇而安
适配器模式与外观模式:以不同的目的,包装某些对象,让它们的接口看起来不像自己而像是别的东西。
这样就可以在设计中,将类的接口转换成想要的接口。
将所有的改变封装在一个类中,可能需要让一个适配器包装多个被适配者。
双向适配器。

适配器模式解析
客户 - 适配器 - 被适配器
客户使用适配器的过程如下:
客户通过目标接口调用适配器的方法对适配器发出请求。
适配器使用被适配者接口把请求转换成被是配置的一个或多个调用接口。
客户接收到调用的结果,但并未察觉这一切是适配器在起转换作用。

适配器模式:将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不兼容的类可以合作无间。

对象适配器:


外观不只是简化了接口,也将客户从组件的子系统中解耦。
外观和适配器可以包装许多类,但是外观的意图是简化接口,而适配器的意图是将接口转换成不同接口。
外观模式:提供了一个统一的接口,用来访问子系统中的一群接口。外观定义了一个高层接口,让子系统更容易使用。
外观没有封装子系统的类,外观只提供简化的接口。同时,依然将系统的功能完整地暴露出来。


设计原则:最少知识原则:只和你的密友谈话。

要点
当需要使用一个现有的类而其接口并不符合你的需要时,就使用适配器。
当需要简化并统一一个很大的接口或者一群发杂的接口时,使用外观。
适配器改变接口以符合客户的期望。
外观将客户从一个复杂的子系统中解耦
实现一个适配器可能需要一番功夫,也可能不费功夫,视目标接口的大小与复杂度而定。
实现一个外观,需要将子系统组合进外观中,然后将工作委托给子系统执行。
适配器模式有两种形式:对象适配器和类适配器,类适配器需要用到多重继承
你可以为一个子系统实现一个以上的外观。
适配器将一个对象包装起来以改变其接口,装饰者将一个对象包装起来以增加新的行为和责任,而外观将一群对象包装起来以简化其接口。

Chapter 8:模板方法模式--封装算法

唉!在需要进入这个洞之前他原本是个好老板的,结果这全部都编程了我的工作了。你懂我的意思吧?他根本就不见人影!
我们将要深入封装算法块,好让子类可以在任何时候都可以将自己挂接进运算里。

模板方法定义了一个算法的步骤,并允许子类为一个或多个步骤提供实现。

模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
对模板方式进行挂钩,影响抽象类中的算法流程

设计原则:好莱坞原则:别调用(打电话给)我们,我们会调用(打电话)你。
高层组件对待低层组件的方式是:别调用我们,我们会调用你。低层组建将自己挂钩到系统上。

要点
模板方法定义了算法的步骤,把这些步骤的实现延迟到子类。
模板方法模式为我们提供了一种代码复用的重要技巧。
模板方法的抽象类可以定义具体方法、抽象方法和钩子。
抽象方法由子类实现。
钩子是一种方法,它在抽象类中不做事,子类可以选择要不要去覆盖它。
为了防止子类改变模板方法中的算法,可以将模板方法声明为final。
好莱坞原则告诉我们,将决策权放在高层模块中,以便决定如何已经何时调用低层模块。
你将在真实世界代码中看到模块方法模式的许多变体,不要期待它们全都是一眼就被你认出来的。
策略模式和模板方法模式都封装算法,一个用组合,一个用继承。
工厂方法是模板方法的一种特殊版本。
良好管理的集合 “当然我把集合都好好地封装起来了”

Dec 18, 2008

《货币战争》

今天早上七点半就起来了,窝床上看小说--《货币战争》。的确是颇有意味的一本书,抛开真实性不说--也许也不会有人认为这本书里讲的是真的,这本书让我了解了一下金融方面的历史学知识,我相信这些历史是是真实的,只是对这些历史的解读有些哗众取宠了。对于一些历史的解释作者的阴谋论也能自圆其说,可越到后来就出来了越多的矛盾,我不是指与历史现实的矛盾,而是书中的自相矛盾。于是越翻越快,翻到了十点半终于忍不住饥饿和口渴,翻完了这本书。不能不佩服作者的想象力、历史学知识和自圆其说的能力。有人在金庸的小说中推出了张三丰是小龙女和尹志平的私生子,也是引经据典,充满了想象力。

下面的网上的书评,看看也蛮有意思的。
豆瓣书评--货币战争
子虚乌有的货币战争

Dec 17, 2008

《Head First 设计模式》1-4章

《Head First》在去年初着实火了一把,我是年初买的这本书,然后回学校做毕业设计的时候看了几章,假期实习的时候看完了剩下的几章。那会烦心的事特别多,也没有读书的心情,看《重构》的时候发现很多设计模式方面的东西已经忘个精光,现在重读并做些笔记。部分内容来自CSDN下载的一份EXCEL格式的笔记,图片都来自GoF的经典。设计模式出来十年了,我却是在本科毕业以后才读的这本书,也许不用考研,我会早些接触模式,对我的编程实践应该会有很多的帮助。

学习的方法:

慢一点,思考得越多,需要记的就越少
勤做练习,自己记笔记
睡觉前不要看有难度的东西
多喝水
大声说出来
听听你的大脑怎么说
要有点感觉
设计一些东西

chapter1:设计模式入门
我们已经搬到对象村,刚刚开始着手设计模式……这里每个人都在使用设计模式。很快我们就会通过设计模式跻身上流社会。
把模式装进脑子里,然后在设计和已有的运用中,寻找何处可以使用。

CHANGE
设计原则:找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。
把会变化的部分取出并封装起来,好让其他部分不会受到影响。
结果如何?代码变化引起的不经意后果变少,系统变得更有弹性。

设计原则:
针对接口编程,而不是针对实现编程。
从现在开始,鸭子的行为将被放在分开的类中,此类专门提供某行为接口的实现。
这样,鸭子类就不再需要知道行为的实现细节。
"针对接口编程真正的意思是""针对超类型supertype编程"""
执行时根据实际情况执行真正的行为

设计原则:多用组合,少用继承。
has a maybe better than is a.

策略模式:
定义了算法族,分别封装起来,让它们之间可以相互替换,此模式让算法的变化独立于使用算法的客户。


良好的OO设计必须具备可复用、可扩展、可维护三个特性。
可维护的OO系统:随时想到系统以后可能需要的变化以及应付变化的原则。

模式不是被发明,而是被发现。

chapter 2:观察者模式:让你的对象知悉现状

喂,Jerry,我正在通知大家,模式小组会议改到周六晚上,这次讨论的是观察者模式,这个模式最棒了!超级棒!你一定要来呀,Jerry。

观察者模式: 定义了对象之间的一对多依赖,这样以来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

设计原则
:为了交互对象之间的松耦合设计而努力。
松耦合:依然可以交互,但不太清楚彼此的细节。


Subject:主题 Observer:观察者
要点
观察者模式定义了对象之间的一对多关系。
主题,也就是可观察者用一个共同的接口来更新观察者。
观察者和可观察者之间用松耦合方式结合,可观察者不知道观察者的细节,只知道观察者实现了观察者接口
使用此模式时,你可从被观察者处推push或拉pull数据,然而,推的方式被认为更正确
多个观察者时,不可以依赖特定的通知次序。

Java有多种观察者模式的实现,包括了通用java.util.Observable
要注意java.util.Observable实现上所带来的一些问题。
如果有必要的话,可以实现自己的Observable,这并不难,不要害怕。
Swing大量使用了观察者模式,许多GUI框架也是如此。
此模式也被应用在许多地方。例如:JavaBeans、RMI。

chapter 3: 装饰者模式
我曾经以为男子汉应该用继承处理一切。后来我领教到运行时扩展,远比编译时期的继承威力大。看看我现在光彩的样子。

装饰模式:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
可以在不修改底层代码的情况下,给代码赋予新的职责。


设计原则
:类应该对扩展开发,对修改关闭。

要点1
装饰者和被装饰者对象有相同的超类型
你可以用一个或多个装饰者包装一个对象。
既然装饰者和被装饰对象有相同的超类型,所以在任何需要原始对象(被包装)的场合,可以用装饰过的对象代替它。
装饰者可以在所委托被装饰者的行为之前与/或之后,加上自己的行为,以达到特定的目的。
对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象。

要点2
继承属于扩展形式之一,但不见得是达到弹性设计的最佳方案。
在我们的设计中,应该允许行为可以被扩展,而无须修改现有的代码。
组合和委托可用于在运行时动态地加上新的行为。
除了继承,装饰者模式也可以让我们扩展行为。
装饰者模式意味着一群装饰者类,这些类用来包装具体组件。
装饰者类反映出被装饰的组件类型(他们具有相同的类型,都经过接口或继承实现)
装饰者可以在被装饰者的行为前面与/或后面加上自己的行为,甚至将被装饰者的行为整个取代掉,而达到特定的目的。
你可以用无数个装饰者包装一个组件。
装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型。
装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂

只有针对抽象组件类型编程时,才不会因为装饰者而受到影响。
通常有工厂或生成器之类的模式创建。

Java String
FilterInputStream: 一个抽象装饰者。
chapter 4:工厂模式--烘烤OO的精华
认识工厂方法模式
所有工厂模式都是用来封装对象的创建
工厂方法模式通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的。

组成元素
创建者Creator类
它定义了一个抽象的工厂方法,让子类实现此方法制造产品。
创建者通常会包含依赖于抽象产品的代码,而这些抽象产品由子类制造。创建者不需要真的知道在制造哪种具体产品。
产品类:工厂生产产品。对PizzaStore来说,产品就是Pizza。

另一个观点:平行的类层级
为什么产品类和创建者类是平行的?都是抽象类,且都有许多具体的子类,每个子类都有自己特定的实现。
NYPizzaStore所封装的是关于如何制作纽约风味的比萨。工厂方法就是封装这种知识的关键所在。

工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。

要点:

Creator是一个类,它实现了所有操作产品的方法,但不实现工厂方法。
Creator所有的子类都必须实现这个抽象的factoryMethod方法。
所有的产品必须实现一个共同的接口,这样一来,使用这些产品的类,就可以引用这个接口,而不是具体类。
ConcreteCreator实现了factoryMethod,以实际制造出产品。
ConcreteCreator负责创建一个或多个具体产品,只有ConcreteCreator类知道如何创建这些产品。
concrete具体的adj

设计原则:要依赖抽象,不要依赖具体类。
依赖倒置原则,不能让高层组件依赖低层组件,而且不管高层或低层组件,2者都应该依赖于抽象。
所谓高层组件,是由其他低层组件定义其行为的类。
例如,PizzaStore是个高层组件,因为它的行为是由比萨定义的。
依赖倒置原则,究竟倒置在哪里?
避免OO设计中违反依赖倒置原则
1 变量不可以持有具体类的引用。
如果使用new,就会持有具体类的引用。你可以改用工厂来避开这样的做法。
2 不要让类派生自具体类。
如果派生自具体类,你就会依赖具体类,请派生自一个抽象(接口或抽象类)
3 不要覆盖基类中已实现的方法。
如果覆盖基类已实现的方法,那么你的基类就不是一个真正适合被集成的抽象。基类中已实现的方法,应该由所有的子类共享。

抽象工厂模式
提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
比较工厂方法和抽象工厂。。。
要点1:
所有的工厂都是用来封装对象的创建。
简单工厂,虽然不是真正的设计模式,但仍不失为一个简单的方法,可以将客户程序从具体类解耦。
工厂方法使用集成:把对象的创建委托给子类,子类实现工厂方法来创建对象。
抽象工厂使用对象组合:对象的创建被实现在工厂接口所暴露出来的方法中。
所有工厂模式都通过减少应用程序和具体类之间的依赖促进松耦合。
工厂方法允许类将实例化延迟到子类进行。
抽象工厂创建相关的对象家族,而不需要依赖它们的具体类。
依赖倒置原则,知道我们避免依赖具体类型,而要尽量依赖抽象。
工厂是很有为例的技巧,帮助我们针对抽象编程,而不要针对具体类编程。

《UNIX》超级工具

《UNIX超级工具》也是暑假的时候买的,两本,打五五折的时候买的,可还是花了七十多。有点Geek的味道。随便地翻了很久,要说学到啥也谈不上,这两本书本来就是随便翻的。不知不觉,这两部书已经做满了记号,趁现在有些时间,做个简单的整理。

有人说程序员的七种武器是:正则表达式、编程语言、数据库、算法、软件调试、开发环境;在UNIX环境下,灵巧而强大的工具已经充斥其间,我们所缺的只是一个善于思考的大脑。在UNIX下,你可以不必关心一些细枝末节的东西,从而把注意力集中到真正的思考上,工具和思想在这里充分地协调起来。在这本书里充斥着技巧、工具和表格。简洁而实用。唯一不足的地方就是体系混乱,不过既然是随便翻翻,这个缺点也就不能称之为缺点了。

我基础还太差,看这种充满技巧的书有只见树木不见森林之感。因而要在这本书里整理出什么来还真是个琐碎而吃力的过程,打算以后系统地学习LPI LINUX教程时再结合本书做些整理。在此就先搁置吧。

Dec 16, 2008

《执行》--突破

刚刚考完的高等数理统计,是我进入上财以来遭遇的最大的失败,考前拼死拼活看了两天书,结果看来是挂了。觉得有些惭愧,完全违背了我读研的本意,要照这样下去,我还不如退学找个工作实在。

我不能说不努力,开学到现在三个月,我自己觉得也很累。脑子累,心累,身体也累。一直用力寻找着突破,可结果是让自己越来越累。大学时每学期或多或少都能有些收获,都能对自己的履历有所充实,可现在三个月过去了,除了累,除了不好的成绩,我好像并没有得到什么。

现在的我比任何时候都更需要一种简单的哲学,一种上进而充满张力的方式。前几天抽空看了下《执行--完成任务的学问》,现在顺便写些心得,同时也当作对自己的勉励。

Execution 
--the discipline of getting things done。我并不认为执行是一个新鲜的事务,“实事求是”,“实践是检验真理的唯一标准”,这些话说了好多年,可说多了反而忘了确切的含义,到现在反而要老外来告诉我们实事求是的含义,不能不说有点可悲。在我看来,执行不光是一个企业的事情,在自身的层面上,我们更需要这种实事求是的精神。在《卓有成效的管理者》这本书中,作者认为所有的知识工作者在某种意义上来说也是管理者,在时时刻刻地管理着自己的时间、精力和行为。我目前面临的困境只有通过实事求是的分析和卓有成效的执行才能突破,我依然坚信我的选择,同时,就算我做错了,我也无路可退。

下面的读书笔记摘自“三真阁”

执行是一门学问,是战略的一个内在组成部分。执行是一套暴露现实并根据现实采取行动的系统化的流程。执行应当是一个组织文化中的核心元素:执行必须渗透到企业的回报系统和行为准则当中,它既是企业文化,也是塑造企业文化的方法。

贯彻执行文化的基础是要在企业中推行坦诚、实事求是的交流活动和企业文化,而这就要求领导者通过亲身参与推动文化变革、战略制订乃至运营计划 落实和跟进,充分了解自己的企业和员工,尽一切机会对管理人员进行影响和指导,但这不等于要求领导者事必躬亲,而是要按照一个事先制订的跟进计划,对关键 点和关键环节的执行进行关注、对结果及时评估和应变,就像柳传志在专文推介中说的,“有效的执行是需要领导者亲力亲为的系统工程,而不是对企业具体运行的 细枝末节的关心。”
  
执行的关键就在于把战略与企业的实际情况、实际能力结合起来,建立相辅相成、近乎一体的战略、人员与运营流程。

人员流程的关键是,在战略的高度进行人力资源管理,把人员的招聘、评估、培养和调动与岗位需求切实的统一起来——而岗位需求恰恰是建立在企业的战略和运营要求之上的,以坦诚的态度、统一透明的评估标准、及时并集思广益的评估和沟通活动,来推动人员流程发挥作用。

战略流程的关键是,在制订的时候就充分考虑其可执行性,也就是人员的要求是否满足,是否能够落实为运营计划。战略制订和评估过程中,要充分调 动真正的执行者参与讨论,确保对竞争环境和执行能力已经具有充分准确的了解,保证战略在执行部门得到充分的理解和支持,在人员和运营计划的落实上没有问 题。领导者还可以通过此过程指导员工,推动文化变革,凝聚团队,激发斗志。领导者还要在战略评估结束之后的跟进中确认讨论共识,并将其作为战略实施过程中 的进程指标,强调在战略、人员和运营之间建立必要的联系。

运营流程的关键是,通过更广泛的参与(各部门的执行团队,甚至所有成员),对竞争环境和未来变化假设进行更仔细的考察讨论,对可能开展的项 目对照战略方向进行取舍,将战略计划落实为更详细的企业目标、行动计划和跟进措施(及时的评估和应急计划),为工作开展提供明确的指导方向。通常情况下, 一份运营计划包括了你的企业准备在一年之内完成的项目——与企业预算和财务目标相结合,而预算和财务目标恰恰应该根据企业的运营计划来确定。

本书其他细化内容其实就是各门科管理科学的论述、操作实务和案例分析,有益于对照自查。

Nov 30, 2008

Code Complete PART 6

System Considerations

chapter 27: How program size affects construction
随着项目的增大交流需要加以支持
放大轻量级的方法要好过缩小重量级的方法,最好使用适量级的方法

1. Commmnication and size

2. Range of project size
3. Effect of project size on errors
4. Effect of project size on productitivity
5. Effect of project size on development activite

交流、计划、管理、需求分析、设计、架构、集成、测试、文档的非线性增长
程序 -- 产品 -- 系统 -- 系统产品
Methodology and size 方法论和规模

Chapter 28: Managing construction
一般管理 > 软件管理 > 构件管理
贯彻标准,使用更为灵活的方法 --> 好的编程实践
程序员和管理人员都是人
1. Encouraging good coding
Techniques for encouraging good coding
逐行检查、要求代码签名、安排好的代码示例、代码是公有财产、奖励好的代码
2. Configuration management
SCM: Software configuration manangement
Requirements and design changes
遵循某种系统化的变更控制程序
成组地处理变更请求
评估变更成本
提防大量的变更请求
变更控制委员会
Tools:
cvs, svn, Machine configurations, Backup plan
降低程序员的额外负担;避免对项目的过度控制
3. Estimating a construction schedule
Estimation approaches
评估软件;算法方法:Cocomo 2
建立目标
为评估留出时间并做出计划
清楚说明软件需求
在底层细节层面进行评估
使用不同的评估方法并进行比较
定期做重新评估
Estimation vs. Control
what to do if you are behind:
项目并不能在后期把时间补回来,只会越拖越坏
扩充团队?缩减项目范围。
4. Measurement
留心度量的副作用
反对度量就是认为最好不要知道真实
5. Treating programmers as people
程序员并非只是与硅芯片打交道的有机物。
How do programmers spend their time
Variation in performance and quality
Individual variation
Team variation
Religious issues 信仰问题
编程语言、缩进风格、大括号、IDE、注释风格、效率 vs. 可读性、方法的选择、编程工具、命名习惯、goto、全局变量
6. Managing your manager
人性的弱点

Chapter 29: Integration
1. Importance of the integration approach
结果也许正确,但错误的过程依然会导致失败
2. Integration fraquency -- phased or incremental
Phased integration
测试、编码、测试、调试。单元开发
将这些类组合成系统(system integration)
测试调试(system dis-integration)
Incremental integration
开发模块,测试调试模块,集成到系统
Benefits of incremental integration
易于定位错误
及早在项目中取得系统级的成果
改善对进度的监控
改善客户关系
更充分地测试系统的各个单元
能在更短的开发进度计划内建造出整个系统
3. Incremental integration strategies
Top-down Integration
能较早地测试系统的控制逻辑
Bottom-Up Integration
容易定位错误
要求在开始前,已经完成整个系统的设计工作
Sandwich integration
Bottom-UP + Top-down
Risk-Oriented integration
困难部件优先集成法
鉴别风险级别
Feature-Oriented Integration
以一组构成一项可确认功能的类为单位进行集成
T-Shaped Integration
选中特定的竖直块,及早地进行测试和集成
4. Daily build and smoke test
使一些工作及早地浮出水面
每日构建(daily build)
检查失败的build
每天进行冒烟测试
编译自动化
但有意义时,才将修订加入到build
代码添加到系统前进行冒烟测试
为即将添加的代码准备暂存区

Code Complete PART 4

Statements
Chapter 14. Organizing Straight-line code
主要原则:按照依赖关系进行排列
1. Statements that must be in a sepcific order
设法组织代码,使依赖性变得非常明显
利用子程序名、子程序参数显示依赖性
用注释对不清晰的依赖关系进行说明
2. Statements whose order doesn't matter
making code read from top to buttom
localized --> short live time
grouping related statements
不应该交叠,但可能嵌套

Chapter 15: Using conditionals
1. if statements
plain if-then statements
先处理正常情况,然后其它
确保对于“==”是正确的
把正常的情况处理放在“if”后面
让if语句后跟随一个有意义的子句
chains of if-then-else statements
用布尔函数简化复杂的检测
最常见的放最前
2. case statements
choosing the most efficitve ordering of cases
字母序、正常放最前、频率序
tips for using case statements
简化每种情况对应的操作
不要为使用case刻意制造一个变量
default子句只用于检查真正的默认情况
避免代码执行跨越一条case子句的末尾

Chapter 16. Controlling Loops
1. selecting the kind of loop
counted loop; coutinously evaluated loop; endless loop; iterator loop
when to use while loop
预先不知道迭代的次数
with test at the beginning & end
when to use a loop-with-exit loop
终止条件出现在循环的中部
break; goto
把所有的退出条件放在一处,用注释阐明意图
when to use a for loop
执行固定次数的循环,不需要循环内部控制
when to use a foreach loop
消除了循环内务处理
2. Controlling the loop
减少影响循环的因素数量,把循环内部当作子程序
entering the loop
只从头部进入
初始化代码紧反正循环前
用while表示无限循环
在while适用的时候,不使用for
processing the middle of the loop
避免空循环
循环的内务操作反正循环的开始或结尾
一个循环只做一件事
exiting the loop
终止确认条件
避免依赖循环下标的最终取值
考虑使用循环计数器
小心break&continue
带标号的break
checking endpoints
using loop variables
使用有意义的名字:提高可读性,避免下标串话
把循环下标的作用域限制在本循环内
how long should a loop be
尽可能短,嵌套在三层以内
把长循环的内容移到子程序内
3. Creating loops easily - from the inside out
inside out; 使用字面量
4. Correspondence between loops and arrays
密切联系但不是必然的

Chapter 17: Unusual contorl structures
1. Multiple returns from a routine
如果能增强可读性,就使用return
用guard clause(早返回或退出)来简化错误处理
2. Resursion
tips for using recursion
确认递归能够停止
使用安全计数器防止无穷递归
限制在一个子程序内
递归 or 循环 -- 阶乘
3. goto
万不得已才使用goto
goto导致的效率的提升需可以估量
尽量在每个子程序中最多使用一个goto
尽量让goto先前跳转而不是向后
goto标号
确认goto不会产生执行不到的代码

Chapter 18: Table-driven methods
Table-driven is a scheme -- 从表里查找信息而不是用if or case
复杂逻辑和复杂继承结构的替代方案
1. General considerations of using Table-Driven methods
查询记录的方法:
Direct access
Indexed access
Stair-step access
2. Direct access tables
Date-in-Month example
Flexible-Message-Format Example
Logic basied vs. Object-Oriented vs. Table-Driven
Fudging lookup keys
复制信息从而能直接使用键值
转换键值使之能直接使用
把键值转换提取成独立的子程序
3. Indexed Access tables
4. Stair-step Access tables
把每一区间的上限写入表中,使用循环按照各区间的上限检查分数
留心端点
二分法查找,索引访问?
最好是去选择一个好的方案同时避免灾难,而不是试图寻找最佳的方案。
5. Other Examples of Table loopups

Chapter 19: General Control Issues
1. Boolean expressions
Using the true and false for boolean tests
Making complicated expressions simple
拆分复杂的判断并引入新的布尔变量
将复杂的表达式做出布尔函数
用决策表代替复杂的条件
Forming boolean expressions positively
I ann't not no undummy. 我并非不是一个不傻的人。
用狄摩根简化
Using parantheses to clarify boolean expressions
Knowng how boolean expressions are evaluated
Writing numeric expressions in Number-line 2order
Guildines for comparisions to 0
隐形地比较逻辑变量
和数值表达式相比使用显示写法
指针 -- NULL
Common problems with boolean expressions
C家族中,应该把常量反正比较的左端

2. Compound Statements(Blocks)

3. Null statements

4. Taming Dangerously deep nesting

重复检查条件中的某一部分来简化嵌套的if

使用break来简化

if --> if-then-else

if --> case

抽取并放入子程序

对象和多态派分

5. A programming foundation: Structured Programming

structured goofing off 结构化混日子

The three components of structured programming

sequence; selection; iteration

6. Control structures and complexity

应用程序的复杂度是由它的控制流来定义的

General guidelines for reducting complexity

How to measure: decision point

if; while; repert; for; and; or; case

0-5: good; 6-10; 10+

Nov 17, 2008

Code Complete PART 3

Variables
chapter 10. General issues in using variables
1. Data Literacy
2. Making variable declarations easy
3. Guidelines for initializing variables
在声明变量时初始化
靠近变量第一次使用时初始化
理想情况下,靠近第一次使用的位置声明和初始化
final & const
counter & accumulator  --- i, j, k, sum, total
在constructor中初始化类的数据成员
检查是否需要重新初始化
一次性初始化具名常m量--使用可执行代码
使用编译器设置
利用编译器警告
检查输入参数合法性
初始化工作内存。 0xCC & 0xDFADBEEF
4. Scope
visibility -- 可见性 作用域
Localize references to variables
span -- 跨度
生存时间
General guidelines for minimizing scope
在循环开始之前再初始化循环中使用的变量
直到变量使用时才为其赋值
把相关语句放到一起
提取子程序
开始时采用最严格的可见性,之后再扩充
Comments on minimizing scope
intellectual manageablility -- 智力可管理性
5. Persistence
数据的生命期
6. Binding time
绑定时间:
编码时 -- 神秘数值
编译时 -- 具名常量
加载时 -- 外部数据源读取
对象实例化时
即时
绑定时间越早灵活性越差,但复杂度越低。
7. Relationship between data types and control structures
Jackson.
Sequential data
selective data
interative data
8. Using each variable for exactly one purpose
每个变量仅有单一用途
避免让变量有隐含意义
确保使用了所有已申明的变量

Chapter 11. The power of variable names
1. Considerations of choosing good names
完全 && 准确
problem orientation
what, not how
length: 10 - 16
限定词放在变量名的最后:
Total, sum, average, max, min, record, string, pointer...
NumXXX: a total number
XXXNum: 下标
begin/end
first/last
locked/unlocked
min/max
next/previous
old/new
opened/closed
visible/invisible
source/target
source/destination
up/down
2. Naming specific types of data
Naming loop indexes
i, j, k
XXXindex, XXXCount
to avoid index cross-talk
Naming status variables
'flag' is not good
Naming temporary variables
警惕临时变量,弄清其实际用途
Naming boolean variables
典型的boolean名:
done, error, found, success or OK.
Naming enumerated types
使用前缀
3. The power of naming conventions
why:
when:
degrees of formality:
4. Informal naming comventions
Guidelines for a language-independent conventions
区分变量名和子程序名
区分类和对象
标识全局变量
标识成员函数
标识类型申明
标识具名常量
枚举类型的元素
格式化命名
Guidelines for language-specific conventions
5. Standardized perfixes
User-defined type abbreviations
UDT: user defined type
ch, doc, pa, scr, sel, wn
Semantic perfixs
c: count
first & last
g: global var
i: index
lim: limitation -- first <> last <> lim : llim = last + 1
m: class var
max && min
p: pointer

Chapter 12: Fundamental data types
1. Numbers in genaral
avoid Magic number.
avoid mixed compare
be careful of warning
2. Integers
检查整数除法。地板除,真实除
检查整数溢出
检查中间结果溢出
3. Floating-point Numbers
避免数量级相差巨大的数之间的加减
避免等量判断
处理舍入误差问题 --使用更高的精度,使用BCD
4. Characters and strings
避免使用神秘字符及神秘字符串
Unicode
在程序生命期中尽早决定国际化/本地化策略
ISO 8859 or Unicode
采用某种一致的字符串转换策略
5. Boolean variables
用布尔变量来简化复杂的判断
需要的话创建自己的布尔类型
---typedef int BOOLEAN;
6. Enumerated Types
提高可读性,可靠性,可修改性。作为布尔变量的修改方案。
7. Named constants
single-point control
在数据申明中使用具名常量
避免使用文字量
用具有适当作用域的变量或类来模拟具名常量
统一地使用
8. Arrays
考虑用容器来代替数组,或将数组当作顺序化的容器来处理
检查数组的边界点
提防下标串话
9. Creating your own types

Oct 23, 2008

Code Complete PART2

PART2: 创建高质量的代码
chapter 5: Design in Construction 软件构建中的设计
1. Design Challenges
Design --> wicked: 只有通过解决或部分解决才能明确的问题 现实<-->理论
Sloppy process --> tide result
方法论;优劣的差异;good enough?
Tradeoffs & priorities
Restrictions
Nondeterministic
Heuristic process
Emergent 自然而然
2. Key Design Concepts
Primary Technical Imperative: Managing Complexity
Accidental and Essential difficulties
失控的复杂度 --> 失败 --尽量减少在任一时间需要考虑的程序量
Desirable characteristics of a design
Minimal complexity --避免“聪明”
Ease of maintenance --self-explanatory
loose coupling
extensibility
reusablity
high fan-in --good use of utility classes
low fan-out --7
portability
leanness --完成->不能删除任何东西:伏尔泰
stratification
standard techniques
Level of design
System --> subsystem 子系统:业务规则、GUI、DB、对象依赖性
--> classed --> routines --> internal routine
3. Design Buildng Blocks: Heuristics
find real-world objects
辨识对象及属性 --> 确定自身操作 --> 对其他对象的操作 --> 可见性 --> 公开接口
Form consistent abstractions
抽象是一种让你关注某一概念的时候可以同时放心地忽视其中一些细节的能力--在不同的层次处理不同的细节。
Encapsulate Implementation details
房屋建造
Inherit -- when inheritance simplifies the design
Hide secrets (Information Hiding)
封装,模块化 冰山
隐藏复杂度、隐藏变化源
障碍:信息分散 循环依赖 类内数据->全局数据 性能损耗
价值:修改 设计
Identify areas likely to change
寻找 分离 预防
易变化的区域:业务规则 输入输出 非标准语言特性 困难的设计和构建 状态变量
anticipating different degrees of change
让变化的影响范围和发生变化的可能性成反比
有用的最小子集 --> 扩充
keep coupling loose
criteria: 规模(连接数) 可见性 灵活性
kinds of coupling:
simple data parameter coupling
simple object coupling
object-parameter coupling
syntictic coupling: 控制标志 假设。。。
Look for common design patterns
现成抽象 --> 减少复杂度
细节制度化 --> 减少出错
多种方案 --> 启发
高层次 --> 简化交流
4. Design Practices
Iterate Divide and conquer Top-down and botton-up design approaches
top-down: 易上手,但易受底层复杂度影响
botton-up: 复杂,但可早期鉴别出系统的复杂度,设计出更好的高层类
experimental prototyping collaborative design How much design is enough
最大的设计失误在于自我认为做的很充分,事后却发现做得不够。
最大的悲哀莫过于大厦快要完工时地基出了问题。 ——罗素
Capturing your work
doc in source, wiki, mail, DC, picture, CRC(类、职责、合作者), UML
5. Comments on popular methodologies
Big design up front --> little design up front or enough design up front
Design in General
Couceptul Blockbusting: A Guide to Better Ideas
How to Solve it: A New Aspect of Mathematical Method
How to Solve it: Modern Heuristics


chapter 6: Working Classes 可以工作的类
1. Class Foundations: Abstract Data Types(ADTs)
Benefits: 隐藏实现细节 支持改动 接口提供更多信息 易提高性能 正确性验证 自说明性 数据传递 实体操作
ADT + 继承、多态 --> 类
2. Good Class Interfaces
Good Abstraction
抽象是一种以简化的形式看待复杂操作的能力 混杂-->一致
类接口应展现一致的抽象层次
理解类所实现的抽象 精确!
提供成对的服务
转移不相关信息 --> 模块内聚
让接口可编程,而不是表达定义
谨防破坏接口的抽象
抽象性 and 内聚性
Good Encapsulation
限制类和成员的可访问性(accessibility)
不公开暴露成员数据
避免把私有的实现细节放入类的接口
不要对类的使用者做出任何假设
避免使用友元类(friend class)
让阅读代码比编写代码更方便
警惕在语义上破坏封装性:针对接口编程 --> 透过接口针对内部实现编程×
3. Design and Implementation Issues
Containment("has a" relationships)
使用包含 万不得已使用private继承 警惕超过七个数据成员的类
Inheritance("is a" relationships)
更精简的代码
成员函数:对派生类可见?有默认实现?能被覆盖?
数据成员:对派生类可见?
要么对继承做详细的说明,要么不使用继承
Liskov替换原则:派生类必须能通过基类的接口被使用,且使用者无需了解两者之间的差异
确保只继承需要继承的部分
注意:继承接口 --> 继承实现 继承实现 --> 继承接口
只想要实现 继承?包含!
不要“覆盖”(语法角度)一个不可覆盖(语义角度)的成员函数!
把共用的接口反正继承树尽可能高的地方
只有一个实例:新的对象?新的类?
只有一个派生类:提前设计?
覆盖但没做任何操作:怀疑!
类型检查?多态!
让所有数据都是private
对继承持有歧视的态度!
Member functions and data
子程序的数量 类调用子程序的数量 对其它类的子程序的间接调用: 尽可能少!
尽量减少类与类间相互合作的范围。
Constructors
尽可能在构造函数中初始化所以数据成员
private constructors --> singleton property
deep copies >> shallow copies
4. Reasons to Create a Class
建模 降低复杂度 隔离复杂度 隐藏实现细节 限制变动的影响范围 隐藏全局数据 让参数传递更通畅 建立中心控制点 易于重用 为程序族做计划 包装相关操作 实现特定重构
Classes to avoid
god class; 无关紧要的类; 用动词命名的类

chapter 7: High-quality Routines 高质量的子程序
small intimate viaible flexible
1. Valid reasons to create a routines
降低复杂度 引入中间、易懂的抽象 避免代码重复 支持子类化 隐藏顺序 隐藏指针操作 提高可移植性 简化逻辑判断 改善性能
创建类的理由也是创建子程序的理由。
2. Design at the Routine Level
functional cohesion: 只执行一项操作
sequential cohesion: 步骤 共享数据 完成完整功能
communicational cohesion: 同样的数据,无其它联系
temporal cohesion: 需要同时执行
procedural cohesion: 子程序的操作按特定顺序
logical cohesion: 控制或“逻辑”是子程序组织的原因
coincidental cohesion
3. Good Routine Names
描述子程序所做的所有事情
避免使用无意义、含糊、表意不明的动词
不使用数字形成不同的子程序名
函数命名时对返回值有所描述
过程命名时使用语气强烈的动宾形式
准确使用对账词
为常用操作确定命名规则
4. How long can a routine be
适中最好 一屏 打印1到2页
5. How to use routine parameters
按输入-修改-输出组织
一致的排列顺序
使用所有的参数
状态或出错变量放最后
不要把子程序的参数用于工作变量
在接口中对参数的假设做出说明:I or M or O? unit? scope?
个数限制在大约7个以内
IN Modify OUT的命名规则
子程序的接口要达到何种抽象?
6. Special considerations in the use of functions
函数 vs 过程
如果一个子程序的用途是返回由其名字所指明的返回值,那么就应该使用函数,否则使用过程
检查所有可能的返回路径
不要返回指向局部数据的指针
7. Macro routines and Inline routines
把宏表达式整个包含在括号内
把含有多条语句的宏用{}包围
节制使用inline: 暴露细节

chapter 8: Defensive Programming 防御式编程

1. Protecting your program from invalid inputs
garbage in, garbage out
in: 检查源于外部的数据 检查数据输入 决定如何处理错误的输入数据
2. Assertions
开发时使用的让程序在运行时进行自检的代码
assert a != 0 : "a is unexpectedly equal to 0"
IN and OUT, state, value of variable, pointer check, container
Guidelines for using assertions
错误处理代码:预期会发生 断言:绝对不应该发生
避免把需要执行的代码放在断言中
用断言来验证前条件(运行前确保为真)和后条件(运行后确保为真)
先使用断言后使用错误处理代码
3. Error-Handling Techniques
返回中立值 下一个正确的数据 与前次相同的数据 最接近的合法值 log error-code
Robustness vs. correctness
correctness: 永远不返回不准确的结果
robustness: 尝试采用。。继续运转
4. Exceptions
通知机制
只有在真正例外的情况下才抛出异常:由于调用子程序的代码需要了解被调用代码可能发生的异常,因而弱化的封装
不能用异常来推卸责任
避免在构造和析构函数中使用异常,除非在同一地方捕获
在恰当的层次抛出异常:抛出的异常也是程序接口的一部分
在异常消息中加入导致异常发生的全部信息
避免使用空的catch语句
集中的异常报告机制 异常使用标准化 考虑异常的替代方案
5. Barricade your program to cotain the damage coused by errors
让软件的一部分处理“不干净”的数据,另一部分处理“干净”的数据,大部分代码就无需承担错误检查的任务
outside error-handling | assertions inside
6. Debugging Aids
Use offensive programming
对待异常:开发时--显现,运行时--自我修复

chapter 9: the Pseudocode Programming Process (PPP) 伪代码编写过程
1. Summary of steps in building classes and routines
steps in creating a class
类的总体设计 类中的子程序 复审并测试整个类
steps in building a routine
设计 检查 编写 检查
2. Pseduocode for Pros
类似英语,精确描述
避免使用目标语言的语法元素
在意图的层次编写伪代码
在足够低的层次上写伪码
3. Constructing routines by Using the PPP
Design the Routine
检查先决条件
定义问题:要隐藏的信息,输入输出,前条件后条件
子程序命名
决定如何测试
在标准库中寻找可用的功能
考虑错误处理
考虑效率问题
研究算法和数据结构
编写伪代码:头部注释+目的
考虑数据
检查伪码
Code the routine
写出子程序的声明
将伪码转为高层次的注释
在注释下填充代码
检查代码:重构?递归应用routine编写方法
收尾
check the code
脑海中检查:
桌面检查(desk checking)
同行评审(peer review)
走查(walk-through)
详查(inspection)
编译子程序
hacking and compiling 拼凑加检查×
将编译器的警告级别调到最高
使用验证工具(validators),C: lint
消除错误消息和警告的所有根源
在调试器中逐行执行代码 测试代码: 测试用例 消除程序中的错误
clean up leftovers
检查接口 检查整体设计质量 检查变量 检查语句和逻辑 检查布局文档及注释
4. Alternatives to the PPP
Test-first development
refactoring
design by contract
hacking×

Oct 15, 2008

Learning python 读书笔记 PART 6

PART 6: Classes and OOP
Chapter 19. OOP: The Big Picture
classes: instance factories, data + function
Instances: represent the concrete items in a program's domain
attributes searching at runtime, lower level to higher level
Coding Class Trees
Class C1(C2, C3): multiple inheritance
Attributes --> class  :  assignments made within class statements
Attributes --> instances  :  assignments to self inside class statements
>>> class C1:
    def setname(self, who):
        self.name = who       
>>> I1 = C1()
>>> I1.setname('xyz')
>>> print I1.name
xyz
initialization: def __init()

Chapter 20. Class Coding Basic
Class: namespace, generating multiple objects, namespace inheritance, operator overloading
Module: namespace
Classes VS. Instances
Class objects probide default behavior:
attributes functions --> class <-- a class name
Instance Objects are concrete items:
call a class object like a function makes a new instance object
each instance object inherits class attributes and gets its own namespace
a new attribute can be generated on the instance
Classes are customized by Inheritance
classes and modules:
from module1 import Class1
class Class2(Class1): ...
Classes can intercept Python Operators
def __init__(self, value): ...
def __add__(self, other):
    return ...
def __mul__(self. other):
    self.data = ...

Chapter 21. Class Coding Details
The Class Statement
class <name>(superclass,...):
    data = value
    def method(self, ...):
        ....
Methods
instance.method(args...) == class.method(instance, args ...)
Calling superclass constructors:
class Sub(Super):
    def __init__(self, x):
        Super.__init__(self, x)
        ......
Inheritance
Abstract superclasses:
class Super:
    def method(self): ...
    def delegate(self):
        self.action()
    def action(self):
        assert 0, 'action must be defined!'
Operator Overloading
__init__: Constructor
__del__: destructor
__add__, __radd__, __iadd__: +, right-side + , +=
__or__:  |
__repr__,__str__ : printing
__call__ : X()
__getattr__ : X.a
__setattr__ : X.a = value
__getitem__ : X[key], for loops, in tests
__setitem__ : X[key] = vlaue
__len__
__cmp__, __lt__, __eq__
__iter__
user-defined iterators
def __init__(self, start, stop):
def __iter__(self)
    return self
def next(self)
    ....
__getattr__ and __setattr__ catch attribute references
__getattr__: is not called if Python can find the attribute, used to deal with undefined attributes
__setattr__: if defined, self.attr = value --> self.__setattr__('attr', value)
    self.__dict__['name'] = x
__repr__ VS. __str__
>>>x  :  run __repr__
>>>print x  :  run __str__
add:
>>>x + 1 #__add__
>>>1 + y #__radd__
__call__:  x(attr)
__del__: run automatically when an instance's space is being reclaimed
Namespaces: The Whole Story
instance -- __class__ --> class
class -- __base__ --> higher superclasses

Chapter 22. Designing with Classed
Python and OOP
inheritance polymorphism encapsulation
Overloading by Call Signatures
*class C:
     def meth(self, x): ...    #a
     def meth(self, x, y):...  #b
 a will overwrited
*class C:
     def meth(self, *args):
          if len(args) == 1: ...
*class C:
     def meth(self, x):
          x.operation()
Classed as Records
OOP and Inheritance: "is-a" relationship
OOP and Composition: "has-a" relationship
OOP and Delegation
Multiple Inheritance
search process depth-first all the way to the top
Classes are objects: Generic Object Factories
apply function:
def factory(aClass, *args)
    return apply(aClass, args)
Methods are objects: Bound or Unbound
Unbound: class, no self
object1 = Spam()
t = Spam.doit
t(object1, 'lalal')
bound: instance, self + function pairs
object1 = Spam()
x = object1.doit
x('lalal')
Documentation String Revisited
import docstr
a.__doc__, a.b.__doc__
Class Versus Modules
they are both namespacefiles
Modules:
Are data/logic packages
Are created by writing Python or C extensions
Are used by imported
Classes:
Implement new objects
Are created by class statements
Are used by being called
Always live within a module

Oct 9, 2008

Learning python 读书笔记 PART 5

PART 5: MODULES
Chapter 15. Modules: The Big Picture
a.code reuse b.System namespace partitioning c.Implementing shared services or data
Python Program Architecture
import and from statements execute and load another file at runtime
How Imports Work
Find it --> Compile it(Maybe) --> Run it
Find it
The module search path:

a. home directory of the top-level file
b. PYTHONPATH directories (if set)
c. Standard library directories
d. The contents of any .pth files (if present)
current working directory
sys.path: the actual search path, is configured by Python at program startup
Compile it
.py & .pyc
Run it
import operation executes the byte code of the module
def: run at import time to create functions

Chapter 16. Module Coding Basics
Module Creation
module --import--> variables (name)
they should follow the normal variable name rules
<directory>m.<extension>
import a --> a.b
from a import b --> b
from a import * --> b
imports happen only once
Later imoort operations simply fetch an already loaded module object.
def, import, from are executable statements
import and from are assignments!
from small import x,y
x = 42 #change my x only
import small
small.x = 42 #change x in other module
equivalence from module import name
is euqal to
import module
name = module.name
del module
Module Namespace
attributes --namespace--> module ojbect
Module statements run on the first imoort: create an empty module object and execute the statements inside the module
Top-level assignments create module attributes
Module namespace: attribute__dict__, or dir(M) --> a directory object
Attribute Name Qualification
Import Versus Scope: function <--> module
Namespace Nesting
Reloading Modules
reload currently only works on modules written in Python; C extension modules cannot.
Reload Basics:
Reloads impact all clients that use import to fetch modules
Reloads impact future from clients only

Chapter 17. Module Package
Package import Basics
import dir1.dir2.mod --> dir0/dir1/dir2/mod
__init__.py
package initialization: run automatically
module namespace initialization
from* statement behavior
from Versus import with packages
import dir1.dir2.mod as mod #short name
from dir1.dir2 import mod

Chapter 18. Advanced Module Topics
_X: prevent being copied out in from* statement, but still not import statement
__all__: from* will only copy out those names listed in the __all__ list
can be used in __init__.py
__all__ = ["b","c"]
from __future__ import featurename
__name__ and __main__
run at top level: __name__ <-- "__main__"
if __name__ == '__main__'
tester()
from module import longname as name
Module Design Concept
you're always in a module in python
Minimize module coupling: global variables
Maximize module cohesion: unified purpose
Module should raraly change other module's variables

Code Complete PART 1: Laying the Foundation

Chapter 1. Welcome to Software Construction
What is Software Construction Activity:
problem definition
requirements development
construction planning
software architecture (high-level design)
detail design
coding and debugging
unit test
integration testing
integration
system testing
corrective maintenance
chapter 2. Metaphors for a Richer Understanding of Software Development
Metaphors: analogy --> modeling
Metaphors: heurstic, subject to chance Algorithm: predictable, deterministic, not subject to chance
common software Metaphors
Writing code: trial and error
Growing a System: incremental, iterative, adaptive, evolutionary
Building Software:
problem definition --> architectural design --> construction --> optimization (review and inspections)

Chapter 3. Measure Twice, Cut Once: Upstream Prerequisites
根本目标:降低风险
流程 --> 质量
Importance of Prerequisites
Causes of Incomplete Preparation:
Non't konw How --> 如果不能做好,做再多也没用!
尽快开始编码:WIMP(why isn't Sam Coding?)
Determine the Kind of Software You're Working On
商业系统 使命攸关 性命攸关
Inerative Approbches --> 修正成本地,发现缺陷的时间更接近引入缺陷的时间
Choosing Between Interative and Sequential Approaches:
需求稳定性 设计是否透彻 熟悉性 项目风险 长期可预测性 后期改变需求、设计和编码的代价
Problem-Definition Prerequisite
product vision -- vision statement -- mission statement -- product difenition == problem definition
应用客户的语言书写
Requirements Prerequistite
scope --> 降低更变
The Myth of Stable Requirements
Handing Requirements Changes During Construction: 评估,通报,建立程序,开发方法
Architecture Prerequistite
system architecture -- high-level design -- top-level design --> architecture specification
Typical architecutral components
program organization: 维护设计的缘由 <--> 维护设计本身
major classes: rules and relationship
data design: files & database
business rules
user interface design: 模块化,便于更换
resource management: 数据库连接、线程、句柄、内存
security: threat model
performance: 资源的使用,速度、内存、成本的优先顺序
scalability: 增长以满足未来需求的能力
internationalization / Localization (I18N, L10N)
Input/output: reading scheme (look-ahead or look-behind or just-in-time)
Error processing: a coding-convention level problem
纠正 or 检测? 主动 or 被动? 错误传播 消息处理 异常处理 处理错误的层次 输入数据有效性
Fault tolerance: 检测 恢复 包容
容错策略:退回 try again;辅助代码,主代码错误时使用;表决算法,分别计算-比较;使用虚假值(phony value)
architectural feasibility
overengineering
buy-vs.-build decisions
resuse decisions
change strategy
general architectural quality: 维护概念完整性
Amount of Time to Spend on Upstream Prerequisites
工作量:10% ~ 20%
时间:20% ~ 30%

Chapter 4: Key Construction Decisions
Choice of programming language
C: 1
Fortran 95: 2
C++, Java: 2.5
VB: 4.5
Perl, Python, Smalltalk: 6
语言的表达能力--思考的能力:你思考的能力取决于你是否知道能够表达该思想的能力
Language descriptions
Cobol: COmmon Business-Oriented Language
Fortran: FORmula TRANslation
Perl: Practical Extraction and Report Language
PHP: PHP:Hypertext Processor
BASIC: Beginner's All-purpose Symbolic Instruction Code
Programming in a language (如果语言工具是初级的,那么程序员的思想也是初级的)
programming into a language (思想 --> 决定如何使用工具)

Oct 7, 2008

Code Complete 读书笔记 PART 7

Software Craftsmanship 软件工艺
Chapter 31. 布局与风格
Layout and Style
准确、一致、易读性、易维护性
Layout Fundamentals
好的布局凸显程序的逻辑结构。
人 != 计算机
经验和规矩是吻合的
Layout as Religion
Objectives of Good Layout
准确,始终如一地表现程序的逻辑结构;改善可读性;经得起修改
Layout Techniques
分组:空行,空格
空行:将不相关的语句隔开 8% ~ 16%
缩进:2 ~ 4 空格,显示逻辑
Layout Sytles
纯块结构:Basic
仿纯块结构:java
begin-end {}
行尾布局
Laying Out Control Structures
begin-end: 未缩进;两次缩进  ×
在程序中加入空行,有助于思考语句的从属
缩进策略应统一
goto:标号大写、上下空行;包含goto的语句单独为一行
Laying Out Individual Statements
空格:逻辑、数组引用、子程序参数
续行:续行需明显(“+ , && ||”);所有后续行按标准量缩进;
Using only one statement Per Line
易调试,易修改,能提供关于复杂度的正确印象,线性阅读
数据声明:一行一声明,靠近首次使用的位置,合理组织顺序
注释:缩进一致,注释前加空行
有约定比约定某个特定细节更重要
Laying Out Routines
用空格分隔程序各部分
参数按标准缩进
Laying Out Class
Class Interfaces: 头部注释(类及完整用法) 构造析构 public protected private
Class Implementations: 类文件内容 类数据 public protected private
子程序间:2~3行

Chapter 32. 自说明代码
Self-Documenting Code
好的注释才有价值
源码包含大部分关键信息,信息融入代码
好的代码本身是最好的说明
注释应用来说明代码无法说明的东西
注释应易维护
External Documentation
单元开发文件夹:UDF: uint-development folder  SDF: software-development folder
详细设计文档
Programming Styla as Documentation
良好结构、直率易懂的方法、有意义的名称、具名常量、清晰的布局、最低复杂度的控制流和数据结构
循环 -- 良好定义的子程序
尽可能采用问题领域的术语
To Comment or not to Comment
好注释 != (重复代码 or 解释代码)
注释困难 --> 代码差劲 or 没有彻底理解
代码复杂:改进代码 > 添加注释
Kinds of comments
repeat of code
×
explanation of code ×
marker in the code (fix before release?)
summary of code: good for other readers
description of the code's intent: 意图而非解决方法
information that cannot possibly be expressed by the code itself
Commenting Efficiently
采用不会被打断和易于修改的注释方法
用伪码编程法减少注释时间
1 comment per 10 lines
Commenting Techniques
行尾注释:代码块,数据声明
数据声明:数据单位、允许范围、编码含义、输入数据限制、位标志

Chapter 33. 个人性格
Personal Character
谦虚,求知欲,诚实,创造性,纪律,高明的偷懒
好性格 -->正确的习惯
软件开发:建造材料=个人才智;工具=自己,其实在研究人的智力、性格
20/80,10:1
Intelligence and Humility
理解一个程序,需要很强的吸取细节的能力并能同时消化
《The Humble Programmer》:大部分编程工作都是在弥补我们有限的智力。承认自己智力有限并通过学习来弥补
减轻脑力负担:
系统分解,复查、详查、测试,程序尽量短小,尽量高层,规范
Curiosity
在开发过程中建立自我意识
试验!学会制造错误-->收获;利用小程序
阅读解决问题的方法
在行动之前做分析和计划:分析<-->行动
学习成功项目的开发经验:Programming Pearls, The Mythical Man-Month
阅读文档,RTFM!^_^
向专业开发看齐
入门级:某语言的基本功能,运用语言特性
中级:多中语言基本功能,熟练使用一种语言
熟练级:对语言和环境有专业技能
技术带头人级:人
Intellectual Honesty
了解代码,了解进度,如实反馈
Communication and Cooperation
代码可读性,编程首先是和人交流,其次才是计算机
Creativity and Discipline
在非关键之处设立规范,从而在更重要的地方发挥创造性
Form is liberating.
Laziness
拖延:逃避思考,实在懒
迅速完成:用最少时间做完不喜欢的工作。开明懒
编写某个工作完成不喜欢的任务:一劳永逸的懒
Characteristics that don't matter as much as you might think
persistence: 固执己见 or 坚韧不拔 知道何时放弃
experience: 软件开发行业的经验比书本知识价值要小,工作10年,是得到10年的经验还是1年经验的10次重复
Habits
精神品德,编程品德
态度端正,积极思考 --> 习惯
不能用没有习惯来代替坏习惯
Additional Resources
《The Humble Programmer》
Dijkstra:编程的本质任务就是驾驭计算机科学的极端复杂性,编程是唯一一个需要掌握从最底层到最高层9个数量级细节差异的人类活动。

Chapter 34. 软件工艺的话题
Themes in software Craftsmanship
编程的目的之一是管理复杂性
过程对产品有深远影响
团队:广泛沟通;单人:自我交流
编程应基于问题域而非解决方案
注意警告信息
迭代:软件质量
丰富的工具箱

Conquer Complexity
降低复杂度几乎和衡量程序员成果的最重要依据
方法:划分子系统,类、接口,保持接口抽象性,避免深层次的继承,避免深层的循环、条件判断,不用goto,不滥用异常(需以系统的观点使用),不让类过度膨胀,子程序短小,使用不言自明的变量,子程序参数尽量少,规范和约定
Pick Your Process
团队成员 --> Process --> 质量。
避免不成熟的优化
坏的过程损耗脑力
Write Programs for People First, Computer Secon
目标:算法精准,结构紧凑,性能好,注释清晰得体
Program into your Language, Not in It
要什么 --> 怎样用工具实现。
Fous Your Attention with the Help of Conventions
规范是一套管理复杂度的质量工具
规范能精确地传达重要的信息
规范能免除各种风险:禁止,要求 --> 防范
规范能增加对低层工作的可预见性
规范能弥补语言的不足之处
Program in Terms of the Problem Domain
尽可能工作于最高的软件层次
顶层代码:说明解决的问题
Separating a Program into Levels of Abstraction
Level 0: Operating-System Operations and Machine Instructions
Level 1: Programming-Language Structures and Tools
Level 2: Low level of implementation Structures 粘结层
Level 3: Low level Problem-Domain Terms 提供框架
Level 4: High level Problem-Domain Terms 基于问题域的术语
Watch for Falling Rocks
艺术  工艺(craft) 科学
良好的个人判断
玄机代码 maybe 差劲代码
设计的度量 反映 设计的质量
警告信息
重复,“不自在,不惬意”
不容易写注释,不易命名变量,不易将问题分解
难以理解,不安,猜测
找不到错误的原因仅仅因为是忽视
Iterate, Repeatedly, Again and Again
反复评估 --> 精确
开发:逐步精化,实证而非证明
迭代的代码调整
Thou Shalt Rend Software and Religion Asunder
software Oracles & Eclecticism
Experimentation
基于实验结果改变思路
“试图没有错误”是最大的错误
设计是仔细规划小错误以避免更大的错误
试验可用在很多层次上


Chapter 35. 更多信息

Software Construction
Pragmatic Programmer
Programming Pearls
Extreme Programming Explained: Embrace Change
Writing Solid Code
The Practise of Programming
Topic Beyond Construction
Facts and Fallacies of Software Engineer
Professional Software Development
The Psychology of Computer Programming
Software Engineering Overviews
Software Engineering: A Practitioner's Approach
Software Engineering 6th
Periodicals
Software Development www.sdmagazine.com
Dr.Dobb's Journal www.ddj.com
IEEE Software www.computer.org/software
Communications of the ACM www.acm.org/cacm/
A Software Developer's Reading Plan
Introductory Level
Conceptual Blockbusting: A Guide to Better Ideas
Programming Pearls
Facts and Fallacies of Software Engineering
Software Project Survival Guide
Code Complete
Practitioner Level
Software Configuration Management Patterns: Effective Teamwork, Practical Integration
UML Distilled: A Brief Guide to the Standard Object Modeling Language
Software Creativity
Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and the Unified Process
Rapid Development
Software Requirements
Professional Level
Software Architecture in Practice
Refactoring: Improving the Design of Existing Code
Design Patterns
Principles of Software Engineering Management
Writing Solid Code
Object-Oriented Software Construction

Oct 5, 2008

Learning python 读书笔记 PART 4

PART FOUR. FUNCTIONS
Chapter 12. Function Basics
calls:  myfunc(argv)
def, return, yield: def adder(a, b=1, *c): return a+b+c[0]
global:  def function(): global x; x = 'new'
lambda:  funcs = [lambda x: x**2, lambda x: x*3]
1. Coding Functions
def is a executable statement which create an object and assigns it to a name
arguments are passed by assignment
global declares module-level variables that are to be assigned
def <name> (arg1, arg2...):
    ...
    return <value>
def can executes at runtime
if test:
    def function():
else:
    def function():
2. Definitions and Calls
Polymorphism in Python: because python is a dynamically typed language, every operation is polymorphic in python
in python, code is not supposed to care about specific data types.

Chapter 13. Scopes and Arguments
1. Scope Rules
Name <--> Namespace
The enclosing module is a global scope
The global scope spans a single file only
Each call to a function is a new local scope
Assigned names are local, unless declared global
All other names are enclosing locals, globals, or built-ins
LEGB: local --> enclosing functions --> global --> built-in
the built-in scope
>>> import __builtin__
>>> dir(__builtin__)
zip <--> import __builtin__,  __builtin__.zip
2. The global Statements
3. Scope and Nested Functions
LEGB: statically nested scope
lambda: an expression that generates a new function to be called later, much like def statement
4. Passing Arguments
immutable arguments <--> C's "by value" mode
mutable arguments <--> C's "by pointer" mode
Avoiding mutable arguments change:
pass a copy or tuple
Simulating output parameters:
>>> def multiple(x,y):
    x = 2
    y = [3,4]  #change local names only
    return x,y #return new values in a tuple(not two values)
>>> x = 1
>>> y = [1,2]
>>> x,y = multiple(x,y)  #assign result to caller's names
>>> x,y
(2, [3, 4])
5. Special Argument Matching Modes
func(value)    : Normal argument: matched by position
func(name=value)    : Keyword argument: matched by name
self documention, more meaningful
def func(name)   
def func(name=value)    : default argument value, if not passed in the call
make some arguments optional
def func(*name)    : Matchs remaining positional args(in a tuple)
>>>def f(*args): print args
def func(**name)    : Matchs remaining keyword args(in a dict)
>>>def f(**args): print args
>>>f(a=1,b=2)
{'a':1, 'b':2}
Argument Matching
rules:
key arguments after non-keyargument
*name after normal argument
**name last
Matching steps:
non-key argus --> key word argus --> extra non-key argus --> extra key argus -->default values

Chapter 14. Advanced Function Topics
1. Anonymous Functions: lambda
lambda expression creates a function to be called later, but returns it instead of assigning it to a name
lambda argu1, argu2, argu3...arguN: expression using argus
lambda bodies are single expression, not a block of statements
example1:
L = [(lambda x: x**1),(lambda x: x**2), (lambda x: x**3)]
for f in L
    print f(2)
print L[0](2)
example2:
key = 'b'
{'a': (lambda f1),
  'b': (lambda f2),
}[b]()
is equivalent to
def f1():...
def f2():...
...
key = ...
{'a':f1, 'b':f2}[key]()
How(not) to obfuscate your python code
((a and b) or c) is roughly equivalent to:
if a: b else: c
(C's a?b:c)
2. Applying Functions to Arguments
The apply built-in
apply(func, argus) == func(argus)
argument list is passed by tuple
if <test>:
    action,args = func1, arguments_a
else
    action,args = func2, arguments_b
...
apply(action,args)
3. Functions Over Sequences
>>> counter = [1,2,3,4]
>>> def func(x): return x + 10
>>> map(func,counter)
[11, 12, 13, 14]
>>>map((lambda x: x + 3), counter)
[3,4,5,6]
map(func,[1,2,3],[4,5,6]) #[func(1,4),func(2,5),func(3,6)]
4. Functional Programing Tools
filter
>>>filter((lambda x: x>0), range(-5,5))
[1,2,3,4]
reduce
>>>reduce((lambda x, y: x+y), [1,2,3,4]) 
10
>>>import operator
>>>reduce(opetator.add, [1,2,3,4])
5. List Comperhensions
[x ** 2 for x in range(10)]
map((lambda x: x ** 2), range(10))
[x for x in range(5) if x%2 == 0]
filter((lambda x: x%2 == 0), range(5))
map((lambda x: x**2), filter((lambda x: x%2 == 0),range(10)))
the genaral structure of list comprehensions
[expression for target1 in sequence 1 [if condition]
                for target2 in sequence 2 [if condition]....
                for targetN in sequence N [if condition]]
list comperhension and map are faster than for loop.
6. Generators and Iterators
Generators yield a value rather than returning one. The yield statment suspends the function and sends a value back to the caller and allow the function to resume from where it left off.
>>> def gensqure(N):
    for i in range(N):
        yield i ** 2
>>>x=gensqure(10)
>>>x.next(), x.next()...
Iterators and built-in type: iter(L)
__iter__ method

Learning python 读书笔记 PART 3

PART THREE: Statements and Syntax
Chapter 8. Assignment, Expressions, and Print
program  are composed of  modules contains statements contain expressions create and process objects
1. Assignment Statements
a = 'a'
a, b = 'a', 'b'   #tuple assignment
[a,b] = ['a','b']    #List assignment
a = b = 'c'    #Mutiple-assignment
L = L + [3], L = L + [5,6]    #Concatenate(create a new object)
L.append(3), L.extend([4,5])    #Faster, but in-place(add at the and of memory)
L += [9,10]    #Mapped to L.extend([9,10]): the faster mothed
2. Expression Statements
3. Print Statements
print a,b,    #don't add newline at the end of text
print >>myfile a,b    #send data to myfile.write, not to sys.stdout.write
redirecting the Output Stream
import sys
sys.stdout = open('myfile', 'a')
print and stdout
class FileFaker:
    def write(self, string)  #do something with the string
import sys
    sys.stdout = FileFaker()

Chapter 9. if Tests
1. if stataments
if: elif: else:
if 1:
    print 'true'
else:
    print 'false'
switch & case:
*if choice = 'a':
    print 'aaa'
elif choice = 'b':
    print 'bbb'
else:
    print 'default'
choice = 'b'
*print {'a':'aaa','b':'bbb'}[choice]
*branch = {'a':'aaa','b':'bbb'}
  print branch.get('a', 'bad choice')
2. truth tests
2<3, 3<2   #Less-than: return 1 or 0
short circuit evaluation
2 or 3, 3 or 2   #(2,3) Return left operand if true. Else return right operand.
[] or 3   #3
[] or {}   #{}
2 and 3, 3 and 2   #(3,2) return left operand if false. Else return right operand.

Chapter 10. while and for Loops
1. while loops
while <test>:
     <statement1>
     if <test2>: break    #Exit loop now, skip now
     if <test2>: continue    #goto top of loop now   
else:
     <statement2>    #if we didn't hit break
breaks, continue, pass and the loop else
Emulating C while Loops

C assignments return the value assignment; Python assignments are just statements, not expressions
C: while ((x = next()) != NULL){process x...}
Python equivalent:
*while 1:
    x = next()
    if not x: break
    ...process...
x = 1
*while x:
    x = next()
    if x:
    ...process
2. for loops
for <target> in <object>:
    <statements>
else:
    <statements>  #if we didn't hit break
3. loop variations
range

Counter Loops
range(3)  #[0,1,2]
range(2,5) #[2,3,4]
range(0,10,2)  #[0,2,4,6,8]
*for item in X: print item
*i = 0
 while i < len(X)
     print x[i],; i += 1
*for i in range(len(x)): print X[i]
Nonexhaustive Traversals
S = 'abcdefghijk'
for i in range(0, len(s), 2) print S[i],  #manual for indexing
for i in S[::2]: print x
Changing Lists
for i in range(len(L)):
    L[i] += 1
zip and map
zip can enable us to visit multiple sequences in parallel
L1 = [1,2,3], L2 = [4,5,6]
zip(L1,L2)   #[(1,4),(2,5),[3,6]]
for (x,y) in zip(L1,L2):
    print x, y,
when argument lengths differ, zip choose the shortest length
map(None, L1, L2)
map choose the longest length and filled empty items with "None"
Dictionary Construction with zip
>>> keys = ['a','b','c']
>>> values = [1,2,3]
>>> zip(keys,values)
[('a', 1), ('b', 2), ('c', 3)]
>>> D = {}
>>> for(k,v)in zip(keys,values):
    D[k]= v   
>>> D
{'a': 1, 'c': 3, 'b': 2}
>>> D2 = dict(zip(keys,values))
>>> D2
{'a': 1, 'c': 3, 'b': 2}
File Scanners
file = open('test.txt', 'r')
while 1:
    line = file.readline()
    if not line: break
    print line
1. for line in open('test.txt').readlines(): print line
2. for line in open('test.txt').xreadlines(): print line
3. for line in open('test.txt'): print line
xreadlines loads lines on demand, "3" relies on iterators, is equivalent of xreadlines

Chapter 11. Documenting Python Code
1. the python document interlude

dir(): Lists of attributes  available on objects
__doc__: In-file documentation attached to objects
docstrings
User-defined docstrings: strings at the top of file, method and class
built-in docstring:
import sys
print sys.__doc__
print int.__doc__, print open.__doc__
pydoc
help(sys)
2. common coding gotthas
Don't forget the colons
Start in column 1
Blank lines matter at the interactive prompt:
mean the end of compound statement
Indent consistently
Don't coding C in Python:
don't embed assignment statements in while loop tests
Use simple for loop instead of while or range:
for loop is simple and fast
Don't expect results from functions that change objects in-place:
append(), sort(), append(), extend()
myList = myList.append(X)  #set myList to None
Always use parenthesis to call a function
Don't use extensions or paths in imports and reloads

Oct 4, 2008

Learning python 读书笔记(6, 7章)

Chapter 6: Lists and Dictionaries
1. List
Methods: grow, sort, search, reverse, append, extend, append
del L[x:y], L[x:y]=[a,b,c]
range(x), xrange(x,y), L.pop()
2. List in Action
Slice assignment: delete + insert
L.append(x) < -- > L+[x]
3. Dictionaries
D.keys(), D.values(), D.items():
create a new list
D.copy(), D.get(k, default),
D2.update(D1): merges the keys and values of one directory into another, blindly overwriting values of the same key.
D.has_key(k), k in D
D = dict(zip(keyslist, valueslist))
4. Dictionaries in Action
sequence operation don’t work.
Assigning to new indexes adds entries.
keys need not always be strings.(can be other immutable object)
Using dictionaries to simulate flexible lists Using dictionaries for sparse data structures
Matrix = {}
Matrix[(2,3,4)] = 88: the number at position (2,3,4) is 88
Using dictionaries as “reconds”
Dictionary interfaces
import anydbm
file = anydbm.open(“filename”)
file [‘key’] = ‘data’ #store data by key
data = file[‘key’] #fetch data by key

Chapter 7: Tuples, Files, and Everything Else
1. Tuples

simple groups of objects, cannot change in place(immutable), don't support any method calls
>>> (1,2) + (3,4)
(1, 2, 3, 4)
>>> (1,2) * 3
(1, 2, 1, 2, 1, 2)
>>> T = ('1', '2', '3')
>>> tmp = list(T)
>>> tmp
['1', '2', '3']
>>> T2 = tuple(tmp)
>>> T2
('1', '2', '3')
>>> T = (1, [2,3], 4)
>>> T[1][0] = 5 #works
>>> T[0] = 0 #Fails
2. Files
input = open('path', 'r'), output = open ('path', 'w')  #mode: r, w, a
S = input.read(), S = input.read(N) # N bytes
S = input.readline(), S = input.readlines()
output.write(S), output.writelines(L), output.close()
seek: reset current position in file, flush: buffered output write into disk
3. Type Categories Revisited
Operator Overloading:

class MySquence:
    def __getitem__(self, index):
        #called on self[index]
    del __add__(self, other):
        #called on self + other
4. Object Generality
Lists, dictionaries, and tuples can: 1. hold any kind of object 2. arbitrarily nested
Lists and dictionaries can dynamically grow and shrink.
5. References Versus Copies
No reference to the same object:

A = L[:]    #instead of: A = L (or list(L))
B = D.copy()    #instead of: B = D
empty-limit slices and copy method only do a top-level copy!
nested copy:
import copy
X = copy.deepcopy(Y)
6. Comparisons, Equality, and Truth
L1 == L2, L1 is L2    #Equivalent? Same object?
But short string: S1 = 'spam', S2 = 'spam' # S1==S2: true, S1 is S2: true
Numbers are true if nonzero
Other objects are true if nonempty
None: much like NULL in C
L = [None] * 100
bool: True, False

Oct 2, 2008

Learning python 读书笔记(1--5章)

PART ONE: Getting Started
Chapter 1: A Python Q&A Session
Chapter 2: How python runs programs
1. Source(x.py) --> Byte Code(x.pyc) --> runtime(PVM)
2. CPython, Jython and Python.net
Psyco: Just-in-Time Compiler
3. Frozen Binaries: program + PVM = binary executable program.
Py2exe(for windows), Installer(Linux & Unix), freeze(original)
Chapter3: How you run programs
1. Unix executable scripts: start with #!/usr/local/bin/python
2. raw_input trick: pause the script
3. import and reload
imports are too expensive an operation to repeat, so when we use reload() instead.
4. Attributes: import xx & from xx import yy. yy are the attributes in the python file xx.
5. IDE: IDLE, Komodo, PythonWorks, PythonWin, Visual Python(plugin for VS).
6. text editor: see http://www.python.org/editors

PATR TWO: Types and Operations
Chapter4: Numbers
1. programs  modules  statements  expressions.
2. Numbers: Normal integers(C longs); Long integers(unlimited size); Floating-point(C doubles);Octal and hex literals; Complex number literals.
3. NumPy(Numeric Python).
4. When use a variable that has never been assigned, Pythons report an error rather than a default value.
5. Numeric representation:
>>>b/a #Auto echo output: more digits
>>>print b/a #print rounds off digits.
>>>repr(num) #Used by echos: as cod form
>>>str(num) #Used by print: user-friendly form
6. Division: Classic, Floor and True
x/y: Classic division
x//y: Floor devision
>>>from __future__import division
7. >>>import math
>>>math.pi, math.e
8. >>>int(‘0100’), int(‘0100’, 8), int(‘0x40’, 16) #100, 64, 64
>>>oct(64), hex(64) #’0100’, ‘0x40’
>>>eval(‘100’), eval(‘0100’), eval(‘0x40’) #100, 64, 64
9. >>>a=3 # a: Names (reference) 3: Object
10. >>>L1 = [2, 3, 4]
>>>L2 = L1
>>>L1 = 24 #L2 is not changed
>>>L1[0] = 24 #L2 = [24, 3, 4]
Chapter 5: Strings
1. >>> s = ‘a\nb\tc’
>>> s # output is the original sequence
>>> print s #output is translated sequence
>>>len(s) #5
2. If python doesn’t recognize the character after ‘\’, it simple keeps the backslash in the resulting string.
3. Raw stirng: r’xxxx’
4. u‘xxx’: Unicode string
5. >>> abc = 'abc'
>>> for i in abc:
print i
a
b
c
>>> for i in abc:
print i,
a b c
6. Index and slicing:
>>> num = '123456'
>>> num[1:3], num[5:], num[:-4]
('23', '6', '12')
>>> num[::2], num[::-1], num[0:-3:2]
('135', '654321', '13')
7. String conversion tools:
>>>int(“42”), str(42) #Convert from/to string
>>>string.atoi(“42”), ‘42’ #older techniques
8. You cannot change a string in place(by assigning an index).
9. String formatting
>>> "%s %d %s" %('I', 4, 'you')
'I 4 you'
%s: string
%r: s, but uses repr()
%c: character
%d: decimal (integer)
%i: integer
%u: unsigned integer
%o, %x, %X: Octal, Hex, Hex uppercase
%e, %E: floating-point exponent
%f: float point
%g, %G: floating-point e or f
%%: %
%[(names)][flag][width][.precision]code
>>> x = 1234
>>> res = "integers:...%d...%+d...%-6d...%06d" %(x, x, x, x)
>>> res
'integers:...1234...+1234...1234 ...001234'
10. String methods:
X.method(arguments) == string.method(X, arguments)
list(); join(); capitalize(); center(width)…