ZX编程随笔(一)

(2005~2006年)

  1. 结构化程序设计是过程式程序设计的一个子集,它对写入的程序使用逻辑结构,使得理解和修改更有效更容易。AdaPascal以及dBase等语言鼓励和实行逻辑程序结构。结构化程序设计通常使用自上往下的设计模型,开发员将整个程序结构映射到单个小部分。已定义的函数或相似函数的集合在单个模块或字模块中编码,这意味着,代码能够更有效的载入存储器,模块能在其它程序中再利用。模块单独测试之后,与其它模块整合起来形成整个程序组织。程序流程遵循简单的层次化模型,采用“for”“ repeat ”“while”等循环结构,不鼓励使用“Go To”语句。几乎任何语言都能使用结构化程序设计技术,大多数现代过程式语言都支持结构化程序设计。
  2. 派生是强关联!最直接的表现是:你无法使用向前引用使派生单元与引用单元解耦,大量使用派生会使软件的耦合度难以忍受。

  3. 包与架构都是演化而来的,一开始就从包与架构的设计入手,其实质就是结构化的自顶向下功能分解,实践证明是错误的。初始的时候,应专注于领域模型中小范围类的设计,随着类体系的增长、演化,设计也逐步明朗化,在恰当的时候才做出包与架构相关的重大决策(即所谓的推迟决策)。

  4. 重用LibDll都是相当笨重、不灵活的,不如直接重用源代码单元(.h/cpp)。在同名文件拷贝的情况下,追踪比较容易。

  5. 测试优先的好处
    1.轻松省力: 测试一旦通过,工作随之结束,不需要再仔细地、殚精竭虑地检查、核对代码;
    2.精简需求: 测试代表最小功能需求,不多不少,防止过度设计和冗余代码;
    3.自由重构: 重构是一项极耗精力的工作,有了测试的支持,重构可以随时随地地自由进行,不用担心引入Bug;
    4.影响设计: 测试迫使我们从程序调用者的角度去观察问题,在关注程序功能的同时,直接关注它的接口;
    5.改善结构: 可测试性迫使我们解除程序和它的周边环境的耦合,以求快速构造测试并通过;
    6.活的文档: 测试是文档,是范例,它可编译,可运行,永远最新,永无歧义;
    7.体现意图: 只有按照测试所暗示的结构去编程,才能通过测试,这称为意图导向的编程,它使程序简单、清晰、易读;
    8.忽略细节: 测试迫使程序员直接面向领域层,暂时忽略界面、数据库等细节问题。
  6. 开发项目的关键步骤:       
         搜集用户素材 ->
            {
                整理用户素材 -> 排列优先级 -> 制定迭代计划 ->
                   {
                       简单设计 -> 写测试代码 -> 写产品代码(使测试通过)
                   }
            }
    注意:在开发期间的每一环节内,添加用户素材与重构代码都是必须的。
  7. 不要完美主义 完美主义的态度排斥变化、拒绝发展,其实质是保守主义的态度。完美主义的根源在于传统的结构化、过程式设计方法:底层模块责任重大,改动困难,想不完美也不行!新的面向对象设计方法,以OCP为核心,以DIP为标志,其目的就是为了响应变化、渐进演化,其态度与完美主义正好相反,是积极的、向上的。

  8. 设计脚本参数 用例就是很好的指导,用例有参与者、前置条件、后置条件、可观察的结果,不妨按照用例的模式去设计脚本。

  9. 由概念出发设计对象 这种方法很简单,结果当然不理想。很可能设计出的对象大而空泛,没有实施上的意义,也可能变成了功能分解的模块化设计,毫无用处,反而有害。关于职责设计,职责究竟是什么,很难说清,但绝对不是按照功能设计。从某种意义上可以说,由概念出发设计对象的方法已被宣布为错误或不当,Robert C. Martin说: I don't know who came up with "Objects should model the real world." but we need to find the guy and trash him soundly.

  10. 关于命令模式 Command(命令) 模式被Robert C. Martin称为最"优雅"的模式,但也有人说该模式不是对象方法,而是结构化方法的残余。我认为,有关该模式的争论深刻地揭示出我们头脑中结构化的毒害到底有多深,我们离真正的对象方法到底有多远。结构化思维的一大特征是隐含的时间上的顺序性,也就是控制流程的迁移,类似于流程图的结构。对象不是的,对象没有先后关系,没有流动性,只有职责的关联,组成网状的结构。在设计对象的时候,考虑的不是控制的转移,而是职责的转移。最典型就是Command模式,其次还有State(状态)模式,在这里时间不具有意义,没有先后,只有职责的本质。理解Command模式、State模式,是打破结构化思维,上升到对象思维的突破口。

  11. 编程的自然过程 从手边收集的较为熟悉的用户描述(或用例)开始,按照测试优先及低耦合的原则,快速展开迭代,并随时重构,每次小的周期都产生一个可运行、可观察、可自动测试的程序。然后备份,开始下一个周期...

  12. 两条至高无上的原则 低耦合与测试优先!这两条原则超越所有方法,是必须遵守与体现的最高原则。

  13. 模型论 对象的概念不如模型的概念,模型是由两个以上的对象组成的超稳定结构(试想一下水分子模型),孤立的对象则是毫无用处的,也无法进行评价。模型无法用结构化的方法设计与实现。模型只有创建与销毁两种与时间有关的概念,除此之外,在模型的生存期,没有时间性,没有顺序性--任何时候的观察与测试,模型都按照其自身逻辑返回同样的结果。模型收到消息并处理之后,模型的内部状态有可能改变,但总是满足其自身内部逻辑的约束(有的说法叫"不变式")。通常,在OO方法的论述中(比如UML),就连调用一个对象的方法这么简单的事也被改称为向对象发送一个消息,这样做是极有道理的,前者是结构化方法的体现,后者则是面向对象方法的体现。模型不是数据结构+算法,模型是对象+消息。模型具有封闭性(是一个自闭包),也就是说,模型为了实现自身的逻辑,无须借助任何外部对象,也无须了解任何外部信息,模型为外部对象提供服务或支持。

  14. 享元(Flyweight)模式的要点是分离对象的内部状态与外部状态,当两个对象的内部状态恒等,或者是根本没有内部状态(即无状态对象)时,可以让它们共享一个实例(只创建一个共享实例)

  15. XOL2的作用: 一、创建并装配对象,使之构成可工作的对象网络或模型;二、在对象行为的插入点执行特殊的上下文操作,实现类似于回调函数或事件句柄的灵活性。(注:XOL2是笔者开发的一种类C++语言)

  16. 策略(Strategy)模式的一个经典描述是:改变对象的内容。当一个对象需要根据客户的请求改变自身的内存结构时,通常只能采用策略模式。

  17. 正是由于很难对界面采用TDD开发,所以应尽可能将代码集中在领域模型,最终的界面仅仅是领域模型的"简单"映像(MVC)

  18. 架构论 有时候,难点在于无法想出合适的对象,使之能够平滑地连入现有的对象网络,完成较为独立的任务,并与其它对象保持相对简单的交互。这种需要极力想出来的新对象往往是提供新服务、新功能的对象,是被动的,而不是一些支撑架构的主控对象--主控对象早就想出来了。由于目的性很强,意图明显,这些新对象的职责是明确的,难就难在要尽可能少的影响原有的设计,要求这些新对象的连接或控制应该是简单的。
    结构化的方法往往倾向于优化底层结构,精简已有代码,使之更加通用,然后就可以在此基础上建筑更复杂的结构--库函数大多是这样做出来的。面向对象的方法正好相反,面向对象的方法是要极力保留最先想出来的设计,这些设计往往简单、直观,意图明显,因此特别强悍,强悍的结构也就适合于架构。从方向上看,结构化的方法总是企图降低原有代码的层次,使之更加底层、通用,面向对象的方法则要提升原有代码的层次,使之更加高层、抽象。
    本质上来说,架构是简单、直观、强悍的,大多数架构都可用一句话进行描述,例如"层模式":将代码分割成几个相互独立的层,层与层之间仅接口可见。
    如果想破坏架构,最常见的做法就是将架构变小,然后使用组合、中介等几种模式在其上组织更大的结构,这样做下去,软件的架构慢慢损毁,最终架构不复存在--软件越来越复杂,越来越不直观,难以理解。
    借用互联网成功的KISS原则:Keep It Simple and Stupid,可以说,架构的成功在于简单并直观

  19. 软件的根本问题是找出简单的模型模拟复杂的现实世界。简化模型的关键是简化限制条件。通过模型与模型的层层虚拟组织,简单的模型可以处理复杂的现实问题。(参见:李国杰《对计算机科学的反思》摘要)

  20. 开发软件的过程完全值得重新学习!在努力发现并学会解决复杂的问题之后,随之而来的难题是:如何发现并解决简单的问题。开发软件的基本理念应该是:简单、完整地模拟一个现实事务。在初步建立软件的前几次迭代过程中,尤其应该尽可能忽略限制条件,在近乎理想的状态下,完整地处理一个事务。这也许是做事的普遍规律:万事开头难,如果你想的过多的话,可能就什么也做不了。一句话: 不求完美,只求完整

  21. TDD的精髓是: 先增加一个失败的测试,然后使之通过。关键在于前者,除非由于缺少某些代码将导致测试失败,否则就拒绝在程序中增加哪怕一行代码。这样做,可以保证所写的代码都是确实有验证的,也就无需人为的加大测试覆盖。
    学会小步前进是不容易的事,而这正是TDD的要点。
    Robert C. Martin
    : 编写单元测试是一种验证行为,更是一种设计行为。同样,它更是一种编写文档的行为。

  22. 太多的技术是无用的技术。搞技术要抱着任它弱水三千,我只取一瓢饮的心态,坚持自主创新精神,开发出既省钱又省力的产品。
    创新就是不迷信任何人、任何技术,直面问题本身,找出最适合自身的解决方案。创新是捷径,既省钱又省力,可以带来巨大的利益。
    主流技术是要学的,但不能追求学全、学满,那样成本太高,得不偿失。要能解决面临的问题,找出自己的道就行
    一种技术所要解决的问题通常是抽象的、全面的,而现实问题却是具体的、有针对性的。成功的技术人员能够审时度势,花最小的时间和代价,以自主创新为主,以参考吸取为辅,既快又省地完成任务。
    听来的,学来的,都不十分可靠,因为没有经过解决问题的实验。

  23. 测试驱动的代码,要加上简短的注释,说明测试的意图,或者解释测试的结果,这样的加注释的代码就是最好的文档,既是设计说明,也是使用说明。



你可能感兴趣的:(设计模式,编程,软件测试,单元测试,领域模型)