加入VIP
  • 专属下载特权
  • 现金文档折扣购买
  • VIP免费专区
  • 千万文档免费下载

上传资料

关闭

关闭

关闭

封号提示

内容

首页 C++ 编程思想

C++ 编程思想.pdf

C++ 编程思想

banrongjun
2011-12-25 0人阅读 举报 0 0 暂无简介

简介:本文档为《C++ 编程思想pdf》,可适用于IT/计算机领域

C编程思想目录第章对象的演化基本概念对象:特性+行为继承:类型关系多态性操作概念:OOP程序像什么为什么C会成功较好的C采用渐进的学习方式运行效率系统更容易表达和理解“库”使你事半功倍错误处理大程序设计方法学介绍复杂性内部原则外部原则对象设计的五个阶段方法承诺什么方法应当提供什么起草:最小的方法前提高概念论述(treatment)结构化开发重写逻辑其他方法Booch责任驱动的设计(RDD)对象建模技术(OMT)为向OOP转变而采取的策略逐步进入OOP管理障碍小结第章数据抽象声明与定义一个袖珍C库放在一起:项目创建工具什么是非正常基本对象什么是对象抽象数据类型对象细节头文件形式嵌套结构小结练习第章隐藏实现设置限制C的存取控制友元嵌套友元它是纯的吗对象布局类用存取控制来修改stash用存取控制来修改stack句柄类(handleclasses)可见的实现部分减少重复编译小结练习第章初始化与清除用构造函数确保初始化用析构函数确保清除清除定义块for循环空间分配含有构造函数和析构函数的stash含有构造函数和析构函数的stack集合初始化缺省构造函数小结练习第章函数重载与缺省参数范围分解用返回值重载安全类型连接重载的例子缺省参数小结练习第章输入输出流介绍为什么要用输入输出流解决输入输出流问题预先了解操作符重载插入符与提取符通常用法面向行的输入文件输入输出流输入输出流缓冲在输入输出流中查找strstreams为用户分配的存储自动存储分配输出流格式化内部格式化数据例子格式化操纵算子建立操纵算子输入输出流实例代码生成一个简单的数据记录小结练习第章常量值替代头文件里的constconst的安全性集合与C语言的区别指针指向const的指针const指针赋值和类型检查函数参数和返回值传递const值返回const值传递和返回地址类类里的const和enum编译期间类里的常量const对象和成员函数只读存储能力可变的(volatile)小结练习第章内联函数预处理器的缺陷内联函数类内部的内联函数存取函数内联函数和编译器局限性赋值顺序在构造函数和析构函数里隐藏行为减少混乱预处理器的特点改进的错误检查小结练习第章命名控制来自C语言中的静态成员函数内部的静态变量控制连接其他的存储类型指定符名字空间产生一个名字空间使用名字空间C中的静态成员定义静态数据成员的存储嵌套类和局部类静态成员函数静态初始化的依赖因素转换连接指定小结练习第章引用和拷贝构造函数C中的指针C中的引用函数中的引用参数传递准则拷贝构造函数传值方式传递和返回拷贝构造函数缺省拷贝构造函数拷贝构造函数方法的选择指向成员的指针附录A常用字符与ASCII代码对照表下载第章对象的演化计算机革命起源于一台机器程序设计语言也源于一台机器。然而计算机并不仅仅是一台机器它是心智放大器和另一种有表述能力的媒体。这一点使它不很像机器而更像我们大脑的一部分更像其他有表述能力的手段例如写作、绘画、雕刻、动画制作或电影制作。面向对象的程序设计是计算机向有表述能力的媒体发展中的一部分。本章将介绍面向对象程序设计(OOP)的基本概念然后讨论OOP开发方法最后介绍使程序员、项目和公司使用面向对象程序设计方法而采用的策略。本章是一些背景材料如果读者急于学习这门语言的具体内容可以跳到第章然后再回过头来学习本章。基本概念C包含了比面向对象程序设计基本概念更多的内容读者应当在学习设计和开发程序之前先理解该语言所包含的基本概念。对象:特性行为第一个面向对象的程序设计语言是年代开发的Simula。其目的是为了解决模拟问题。典型的模拟问题是银行出纳业务包括出纳部门、顾客、业务、货币的单位等大量的“对象”。把那些在程序执行期间除了状态之外其他方面都一样的对象归在一起构成对象的“类”这就是“类”一词的来源。类描述了一组有相同特性(数据元素)和相同行为(函数)的对象。类实际上就是数据类型例如浮点数也有一组特性和行为。区别在于程序员定义类是为了与具体问题相适应而不是被迫使用已存在的数据类型。这些已存在的数据类型的设计动机仅仅是为了描述机器的存储单元。程序员可以通过增添他所需要的新数据类型来扩展这个程序设计语言。该程序设计系统欢迎创建、关注新的类对它们进行与内部类型一样的类型检查。这种方法并不限于去模拟具体问题。尽管不是所有的人都同意但大部分人相信任何程序都模拟所设计系统。OOP技术能很容易地将大量问题归纳成为一个简单的解这一发现产生了大量的OOP语言其中最著名的是SmalltalkC之前最成功的OOP语言。抽象数据类型的创建是面向对象程序设计中的一个基本概念。抽象数据类型几乎能像内部类型一样准确工作。程序员可以创建类型的变量(在面向对象程序设计中称为“对象”或“实例”)并操纵这些变量(称为发送“消息”或“请求”对象根据发来的消息知道需要做什么事情)。继承:类型关系类型不仅仅说明一组对象上的约束还说明与其他类型之间的关系。两个类型可以有共同的特性和行为但是一个类型可能包括比另一个类型更多的特性也可以处理更多的消息这一描述部分引自我对《TheTaoofObjects》(GaryEntsminger著)一书的介绍。(或对消息进行不同的处理)。继承表示了基本类型和派生类型之间的相似性。一个基本类型具有所有由它派生出来的类型所共有的特性和行为。程序员创建一个基本类型以描述系统中一些对象的思想核心。由这个基本类型派生出其他类型表达了认识该核心的不同途径。例如垃圾再生机要对垃圾进行分类。这里基本类型是“垃圾”每件垃圾有重量、价值等等并且可以被破碎、融化或分解。这样可以派生出更特殊的垃圾类型它们可以有另外的特性(瓶子有颜色)或行为(铝可以被压碎钢可以被磁化)。另外有些行为可以不同(纸的价值取决于它的种类和状态)。程序员可以用继承建立类的层次结构在该层次结构中用类型术语来表述他需要解决的问题。第二个例子是经典的形体问题可以用于计算机辅助设计系统或游戏模拟中。这里基本类型是“形体”每个形体有大小、颜色、位置等。每个形体能被绘制、擦除、移动、着色等。由此可以派生出特殊类型的形体:圆、正方形、三角形等它们中的每一个都有另外的特性和行为例如某些形体可以翻转。有些行为可以不同(计算形体的面积)。类型层次结构既体现了形体间的类似又体现了它们之间的区别。用与问题相同的术语描述问题的解是非常有益的这样从问题描述到解的描述之间就不需要很多中间模型(程序语言解决大型问题就需要中间模型)。面向对象之前的语言描述问题的解不可避免地要用计算机术语。使用对象术语类型层次结构是主要模型所以可以从现实世界中的系统描述直接进入代码中的系统描述。实际上使用面向对象设计人们的困难之一是从开始到结束过于简单。一个已经习惯于寻找复杂解的、训练有素的头脑往往会被问题的简单性难住。多态性当处理类型层次结构时程序员常常希望不把对象看作是某一特殊类型的成员而把它看作基本类型成员这样就可以编写不依赖于特殊类型的代码。在形体例子中函数可以对一般形体进行操作而不关心它们是圆、正方形还是三角形。所有的形体都能被绘制、擦除和移动所以这些函数能简单地发送消息给一个形体对象而不考虑这个对象如何处理这个消息。这样新添类型不影响原来的代码这是扩展面向对象程序以处理新情况的最普通的方法。例如可以派生出形体的一个新的子类称为五边形而不必修改那些处理一般形体的函数。通过派生新子类很容易扩展程序这个能力很重要因为它极大地减少了软件维护的花费。(所谓“软件危机”正是由软件的实际花费远远超出人们的想象而产生的。)如果试图把派生类型的对象看作它们的基本类型(圆看作形体自行车看作车辆鸬鹚看作鸟)就有一个问题:如果一个函数告诉一个一般形体去绘制它自己或者告诉一个一般的车辆去行驶或者告诉一只一般的鸟去飞则编译器在编译时就不能确切地知道应当执行哪段代码。同样的问题是消息发送时程序员并不想知道将执行哪段代码。绘图函数能等同地应用于圆、正方形或三角形对象根据它的特殊类型来执行合适的代码。如果增加一个新的子类不用修改函数调用就可以执行不同的代码。编译器不能确切地知道执行哪段代码那么它应该怎么办呢?在面向对象的程序设计中答案是巧妙的。编译器并不做传统意义上的函数调用。由非OOP编译器产生的函数调用会引起与被调用代码的“早捆绑”对于这一术语读者可能还没有听说过因为从来没有想到过它。早捆绑意味着编译器对特定的函数名产生调用而连接器确定调用执行代码的绝对地址。对于OOP在程序运行之前编译器不确定执行代码的地址所以当消息发送给一般对象时需要采用其他的方案。为了解决这一问题面向对象语言采用“晚捆绑”的思想。当给对象发送消息时在程序C编程思想下载运行之前不去确定被调用的代码。编译器保证这个被调用的函数存在并完成参数和返回值的类型检查但是它不知道将执行的准确代码。为了实现晚捆绑编译器在真正调用的地方插入一段特殊的二进制代码。通过使用存放在对象自身中的信息这段代码在运行时计算被调用函数的地址(这一问题将在第章中详细介绍)。这样每个对象就能根据一个指针的内容有不同的行为。当一个对象接收到消息时它根据这个消息判断应当做什么。程序员可以用关键字virtual表明他希望某个函数有晚捆绑的灵活性而并不需要懂得virtual的使用机制。没有它就不能用C做面向对象的程序设计。Virtual函数(虚函数)表示允许在相同家族中的类有不同的行为。这些不同是引起多态行为的原因。操作概念:OOP程序像什么我们已经知道用C语言编写的过程程序就是一些数据定义和函数调用。要理解这种程序的含义程序员必须掌握函数调用和函数实现的本身。这就是过程程序需要中间表示的原因。中间表示容易引起混淆因为中间表示的表述是原始的更偏向于计算机而不偏向于所解决的问题。因为C向C语言增加了许多新概念所以程序员很自然地认为C程序中的main()会比功能相同的C程序更复杂。但令人吃惊的是一个写得很好的C程序一般要比功能相同的C程序更简单和容易理解。程序员只会看到一些描述问题空间对象的定义(而不是计算机的描述)发送给这些对象的消息。这些消息表示了在这个空间的活动。面向对象程序设计的优点之一是通过阅读很容易理解代码。通常面向对象程序需要较少的代码因为问题中的许多部分都可以用已存在的库代码。为什么C会成功C能够如此成功部分原因是它的目标不只是为了将C语言转变成OOP语言(虽然这是最初的目的)而且还为了解决当今程序员特别是那些在C语言中已经大量投资的程序员所面临的许多问题。人们已经对OOP语言有了这样传统的看法:程序员应当抛弃所知道的每件事情并且从一组新概念和新文法重新开始他应当相信最好丢掉所有来自过程语言的老行装。从长远角度看这是对的。但从短期角度看这些行装还是有价值的。最有价值的可能不是那些已存在的代码库(给出合适的工具可以转变它)而是已存在的头脑库。作为一个职业C程序员如果让他丢掉他知道的关于C的每一件事以适应新的语言那么几个月内他将毫无成果直到他的头脑适应了这一新范例为止。如果他能调整已有的C知识并在这个基础上扩展那么他就可以继续保持高效率带着已有的知识进入面向对象程序设计的世界。因为每个人有他自己的程序设计模型所以这个转变是很混乱的。因此C成功的原因是经济上的:转变到OOP需要代价而转变到C所花的代价较小。C的目的是提高效率。效率取决于很多东西而语言是为了尽可能地帮助使用者尽可能不用武断的规则或特殊的性能妨碍使用者。C成功是因为它立足于实际:尽可能地为程序员提供最大便利。较好的C即便程序员在C环境下继续写C代码也能直接得到好处因为C堵塞了C语言中的一第章对象的演化下载些漏洞并提供更好的类型检查和编译时的分析。程序员必须先说明函数使编译器能检查它们的使用情况。预处理器虚拟删除值替换和宏这就减少了查找疵点的困难。C有一个性能称为references(引用)它允许对函数参数和返回值的地址进行更方便的处理。函数重载改进了对名字的处理使程序员能对不同的函数使用相同的名字。另外名字空间也加强了名字的控制。许多性能使C的更安全。采用渐进的学习方式与学习新语言有关的问题是效率的问题。所有公司都不可避免地因软件工程师学习新语言而突然降低了效率。C是对C的扩充而不是新的文法和新的程序设计模型。程序员学习和理解这些性能逐渐应用并继续创建有用的代码。这是C成功的最重要的原因之一。另外已有的C代码在C中仍然是有用的但因为C编译器更严格所以重新编译这些代码时常常会发现隐藏的错误。运行效率有时以程序执行速度换取程序员的效率是值得的。假如一个金融模型仅在短期内有用那么快速创建这个模型比所写程序能更快速执行重要。很多应用程序都要求有一定的运行效率所以C在更高运行效率时总是犯错。C程序员非常重视运行效率这让他们认为这个语言不太庞大也不太慢。产生的代码运行效率不够时程序员可以用C的一些性能做一些调整。C不仅有与C相同的基本控制能力(和C程序中直接写汇编语言的能力)非正式的证据指出面向对象的C程序的速度与用C写的程序速度相差在±之内而且常常更接近。用OOP方法设计的程序可能比C的对应版本更有效。系统更容易表达和理解为适合于某问题而设计的类当然能更好地表达这个问题。这意味着写代码时程序员是在用问题空间的术语描述问题的解(例如“把锁链放在箱子里”)而不是用计算机的术语也就是解空间的术语描述问题的解(例如“设置芯片的一位即合上继电器”)。程序员所涉及的是较高层的概念一行代码能做更多的事情。易于表达所带来的另一个好处是易于维护。据报道在程序的整个生命周期中维护占了花费的很大部分。如果程序容易理解那么它就更容易维护还能减少创建和维护文档的花费。“库”使你事半功倍创建程序的最快方法是使用已经写好的代码:库。C的主要目标是让程序员能更容易地使用库这是通过将库转换为新数据类型(类)来完成的。引入一个库就是向该语言增加一个新类型。编译器负责这个库如何使用保证适当的初始化和清除保证函数被正确地调用因此程序员的精力可以集中在他想要这个库做什么而不是如何做上。因为程序的各部分之间名字是隔离的所以程序员想用多少库就用多少库不会有像C语言那样的名字冲突。•模板的源代码重用一些重要的类型要求修改源代码以便有效地重用。模板可以自动完成对代码的修改因而C编程思想下载是重用库代码特别有用的工具。用模板设计的类型很容易与其他类型一起工作。因为模板对程序员隐藏了这类代码重用的复杂性所以特别好用。错误处理在C语言中错误处理声名狼藉。程序员常常忽视它们对它们束手无策。如果正在建大而复杂的程序没有什么比让错误隐藏在某处且不能指出它来自何处更糟的了。C的异常处理(见第章的内容)保证能检查到错误并进行处理。大程序设计许多传统语言对程序的规模和复杂性有自身的限制。例如BASIC对于某些类型的问题能很快解决但是如果这个程序有几页纸长或者超出该语言的正常解题范围那么它可能永远算不出结果。C语言同样有这样的限制例如当程序超过行时名字冲突就开始成为问题。简言之程序员用光了函数和变量名。另一个特别糟糕的问题是如果C语言中存在一些小漏洞错误藏在大程序中要找出它们是极其困难的。没有清楚的文字告诉程序员什么时候他的语言会失效即便有他也会忽视它们。他不说“我的BASIC程序太大我必须用C重写”而是试图硬塞进另外几行增加额外的性能。所以额外的花费就悄悄增加了。设计C的目的是为了辅助大程序设计也就是说去掉小程序和大程序之间复杂性的分界。当程序员写helloworld类实用程序时他确实不需要用OOP、模板、名字空间和异常处理但当他需要的时候这些性能就有用了。而且编译器在排除错误方面对于小程序和大程序一样有效。方法学介绍所谓方法学是指一组过程和启发式用以减少程序设计问题的复杂性。在OOP中方法学是一个有许多实践的领域。因此在程序员考虑采用某一方法之前了解该方法将要解决的问题是很重要的。对于C有一点是确实的:它本身就是希望减少程序表达的复杂性。从而不必用更复杂方法学。对于用过程语言的简单方法所不能处理的大型问题在C中用一些简单的方法就足够了。认识到“方法学”一词含义太广是很重要的。实际上设计和编写程序时无论做什么都在使用一种方法。只不过因为它是程序员自己的方法而没有意识到。但是它是程序员编程中的一个过程。如果过程是有效的只需要用C做很小的调整。如果程序员对他的效率和调整程序的方法不满意他可以考虑采用一种更正式的方法。复杂性为了分析复杂性先假设:程序设计制定原则来对付复杂性。原则以两种方式出现每种方式都被单独检查。)内部原则体现在程序自身的结构中机灵而有见解的程序员可以通过程序设计语言的表达方式了解这种内部原则。)外部原则体现在程序的源信息中一般被描述为“设计文档”(不要与产品文档混淆)。我认为这两种形式的原则互相不一致:一个是程序的本质是为了让程序能工作而产生第章对象的演化下载的另一个是程序的分析为了将来理解和维护程序而产生的。创建和维护都是程序生命期的基本组成部分。有用的程序设计方法把两者综合为最合适的方式而不偏向任何一方。内部原则程序设计的演化(C只是其中的一步)从程序设计模型强加于内部开始也就是允许程序员为内存位置和机器指令取别名。这是数字机器程序设计的一次飞跃带动了其他方面的发展包括从初级机器中抽象出来向更方便地解决手边问题的模型发展。不是所有这些发展都能流行起源于学术界并延伸进计算机世界的思想常常依赖于所适应的问题。命名子程序的创建和支持子程序库的连接技术在年代向前飞跃发展并且孕育出了两个语言它们在当时产生了巨大冲击这就是为科学工作者使用的FORTRAN(FORmulaTRANslation)和为商业者使用的COBOL(COmmonBusinessOrientedLanguage)。纯计算机科学中很成功的语言是Lisp(ListProcessing)而面向数学的语言应当是APL(AProgrammingLanguage)。这些语言的共同特点是对过程的使用。Lisp和APL的创造专注于语言的高雅语言的“mission语句”嵌入在处理所有任务情况的引擎中。FORTRAN和COBOL的创造是为了解决专门的问题当这些问题变得更复杂有新的问题出现时它们又得到了发展。甚至它们进入衰退期后仍在发展:FORTRAN和COBOL的版本都面向对象进行了扩充(后时髦哲学的基本原则是:任何具有自己独特生活方式的组织其主要目标就是使这种生活方式永存)。命名子程序在程序设计中起了重要作用语言的设计围绕着这一原则特别是Algol和Pascal。同时另外一些语言也出现了它们成功地解决了程序设计的一些子集问题并将它们有序排列。最有趣的两个语言是Prolog和FORTH。前者是围绕着推理机而建立的(在其他语言中常常称作库)。后者是一个可扩充语言允许程序员重新形成这个语言以适应所解决的问题观念上类似于面向对象程序设计。FORTH还可以改变语言因而很难维护并且是内部原则概念最纯正的表达它强调的是问题一时的解而不是对这个解的维护。人们还创造了其他许多语言以解决某一部分的程序设计问题。通常这些语言以特定的目标开始。例如BASIC(BeginnersAllpurposeSymbolicInstructionCode)是在年代设计的目的是使程序设计对初学者更简单。APL的设计是为了数学处理。两种语言都能够解决其他问题而关键在于它们是否是这些问题集合最理想的解。有一句笑话是“带着锤子三年看什么都是钉子”。这反映了根本的经济学真理:如果我们只有BASIC或APL语言特别是当最终期限很短且这个解的生命期有限时它就是我们问题最好的解。然而最终考虑两个因素:复杂性的管理和维护(将在下一部分讨论)。即这种语言首先是为某一领域开发的而程序员又不愿花很长时间来熟悉这门语言其结果只能使程序越来越长使手头的问题屈服于语言。界限是模糊的:谁能说什么时候您的语言会使您失望呢?这不是马上就出现的。问题的解开始变长并且对于程序员更具挑战性。为了知道语言大概的限制你得更聪明这种聪明变成了一种标准也就是“为了使该语言工作而努力”。这似乎是人类的操作方式而不是遇到缺陷就抱怨并且不再称它为缺陷。最终程序设计问题对于求解和维护变得太困难了即求得的解太昂贵了。人们最终明白了程序的复杂性超出了我们能够处理的程度。尽管一大类程序设计要求开发期间去做大部分工作并创建要求最小维护的解(或者简单地丢掉这个解或者用不同的解替换它)但这只是问题的一部分。一般情况是我们把软件看作是为人们提供服务的工具。如果用户的需要变化C编程思想下载了服务就必须随着变化。这样当第一版本开始运行时项目并没有结束。项目是一个不断进化的生命体。程序的更新变成了一般程序设计问题的一个部分。外部原则为了更新和改善程序需要更新思考问题的方法。它不只是“我们如何让程序工作”而是“我们如何让程序工作并且使它容易改变”。这里就有一个新问题:当我们只是试图让程序工作时我们可以假设开发组是稳定的(总之我们可以希望这样)但是如果我们正在考虑程序的整个生命期就必须假设开发组成员会改变。这意味着新组员必须以某种方式学习原程序的要点并与老组员互相通讯(也许通过对话)。这样该程序就需要某种形式的设计文档。因为只想让程序工作文档并不是必需的所以还没有像由程序设计语言强加于程序那样的、强加于创建文档的规则。这样如果要求文档满足特定的需要就必须对文档强加外部原则。文档是否“工作”这很难确定(并且需要在程序一生中验证)因此对外部原则“最好”形式的争论比对“最好”程序设计语言的争论更激烈。决定外部原则时头脑中的重要问题是“我准备解决什么问题”。问题的根本就是上面所说的“我们如何让它工作和使它容易改变”。然而这个问题常常有多种解释:它变成了“我如何才能与FoobleBlah文档规范说明一致以使政府会为此给我拨款”。这样外部原则的目的是为了建立文档而不是为了设计好的、可维护的程序。文档竟然变得比程序本身更重要了。被问到未来一般和特殊的计算的方向时我会从这样的问题开始:哪种解花费较少?假设这个解满足需要价格的不同足以使程序员放弃他当前做事情的习惯方式吗?如果他的方法包括存储在项目分析和设计过程中所创建的每个文档并且包括当项目进化时维护这些文档那么当项目更新时他的系统将花费很大但是它能使新组员容易理解(假设没有那么多的使人害怕阅读的文档)。这样创建和维护方法的花费会和它打算替代方法的花费一样多。外部结构系列的另一个极端是最小化方法。为完成设计而进行足够的分析然后丢掉它们使得程序员不再花时间和钱去维护它为开始编码而做足够的设计然后丢掉这个设计使得程序员不再花时间和钱去维护这些文档然后使得代码是一流的和清晰的代码中只需要最少的注释。为了使新组员快速参与项目代码连同注释就足够了。因为在所有这些乏味的文档上新组员只需花费很少的时间(总之没有人真地理解它们)所以他能较快地参与工作。即便不维护文档丢掉文档也不是最好的办法因为这毕竟是程序员所做的有效工作。某些形式的文档通常是必须的(参看本章后面的描述)。通讯对于较大的项目期望代码像文档一样充分是不合理的尽管我们在实际中常常这样期望。但是代码包含了我们实际上希望外部原则所产生的事物的本质:通讯。我们只是希望能与改进这个程序的新组员通讯就足够了。但是我们还想使花费在外部原则上的钱最少因为最终人们只为这个程序所提供的服务付钱而不是为它后面的设计文档付钱。为了真正有用外部原则应当做比只产生文档更多的事情它应当是项目组成员在创建设计时为了讨论问题而采用的通讯方法。理想的外部原则目标是使关于程序分析和设计的通讯更容易。这对于现在为这个程序而工作的人们和将来为这个程序而工作的人们是有帮助的。中心问题不只是为了能通讯而为了产生好的设计。人们(特别是程序员)被计算机吸引(由于机器为他们做工作)出于经济原因要求开第章对象的演化下载发者为机器做大量工作的外部原则似乎从一开始就注定要失败。成功的方法(也就是人们习惯的方法)有两个重要的特征:)它帮助人们进行分析和设计。这就是用这种方法比用别的方法对分析和设计中的思考和通讯要容易得多。目前的效率和采用这种方法后的效率应当明显不同。否则人们可能还留在原地。还有它的使用必须足够简单不需用手册。当程序员正在解决问题时要考虑简单性而不管他适用于符号还是技术。)没有短期回报就不会加强投资。在通向目标的可见的进展中没有短期回报人们就不会感到采用一种方法能使效率提高就会回避它。不能把这个进展误认为是从一种中间形式到另一种中间形式的变换。程序员可以看到他的类连同类之间互相发送的消息一起出现。为某人创造一种方法就像武断的约束因为它是简单的心理状态:人们希望感到他们正在做创造性的工作如果某种方法妨碍他们而不是帮助他们飞快地接近目标他们将设法绕过这种方法。量级在方法学上反对我的观点之一是:“好了您能够侥幸成功是因为您正在做的小项目很短。”听众对“小”的理解因人而异。虽然这种看法并不全对但它包含一个正确的核心:我们所需要的原则与我们正在努力解决问题的量级有关。小项目完全不需要外部原则这不同于个别程序员正在解的生命期问题的模式。涉及很多人的大项目会使人们之间有一些通讯所以必须使通讯具有形式化方法以使通讯有效和准确。麻烦的是介于它们之间的项目。它们对外部原则的需要程度可能在很大程度上依赖于项目的复杂性和开发者的经验。确实所有中等规模的项目都不需要忠实于成熟的方法即产生许多报告和很多文档。一些项目也许这样做但许多项目可以侥幸成功于“方法学简化”(代码多而文档少)。我们面前的所有方法学的复杂性可以减少到~的(或更少的)规则。我们正在被方法学的细节淹没在所解决的程序设计问题中可能只有不足的问题需要这些方法学。如果我们的设计是充分的并且维护也不可怕那么我们也许不需要方法学或不全部需要它。OOP是结构化的吗现在提出一个更有意义的问题。为了使通讯方便假设方法学是需要的。这种关于程序的元通讯是必须的因为程序设计语言是不充分的它太原始趋向于机器范例对于谈论问题不很有用。例如过程程序设计方法要求用数据和变换数据的函数作为术语谈论程序。因为这不是我们讨论实际问题的方法所以必须在问题描述和解描述之间翻译来翻译去。一旦得到了一个解描述并且实现了它以后无论何时对这个解描述做改变就要对问题描述做改变。这意味着必须从机器模式返回问题空间。为了得到真正可维护的程序并且能够适应问题空间上的改变这种翻译是必须的。投资和组织的需要似乎要求某种外部原则。过程程序的最重要的方法学是结构化技术。现在考虑是否解空间上的语言可以完全脱离机器模式?是否可以强迫解空间使用与问题空间相同的术语?例如在气候控制大楼中的空气调节器就变成了气候调节程序的空气调节器自动调温器变成了自动调温程序等等。(这是按直觉做的与OOP不一致)。突然从问题空间到解空间的翻译变成了次要问题。可以想象在程序分析、设计和实现的每一阶段能使用相同的术语学、相同的描述这样这个问题就变成了“如果文档(程序)能够充分地描述它自身我们仍然需要关于这个文档的文档吗?”如果OOP做它所主张的事情程序设计的形式就变成了这C编程思想下载样:在结构化技术中所遇到的困难在新领域中可能不复存在了。这个论点也为一个思想实验所揭示。假设程序员需要写一些小实用程序例如能在文本文件上完成一个操作的程序(就像在第章的后几页上可找到的那样)它们要程序员花费几分钟最困难的要花费几小时去写。现在假设回到年代这个项目必须用机器语言或汇编语言来写使用最少的库函数它需要许多人几星期或几个月的时间。在年代需要大量的外部原则和管理现在不需要了。显然工具的发展已经极大地增加了我们不用外部原则解决问题的复杂性(同样很显然我们将发现的问题也更加复杂)。这并不是说可以不需要外部原则有用的OOP外部原则解决的问题与有用的过程程序设计外部原则所解决的问题不同特别是OOP方法的目标首先必须是产生好的设计。好设计不仅要促进重用而且它与项目的各级开发者的需要是一致的。这样开发者就会更喜欢采用这样的系统。让我们基于这些观点考虑OOP设计方法中的一些问题。对象设计的五个阶段对象的设计不限于写程序的时期它出现在一系列阶段。有这种观点很有好处因为我们不再期望设计立刻尽善尽美而是认识到对对象做什么和它应当像什么的理解是随着时间的推移而产生的。这个观点也适用于不同类型程序的设计。特殊类型程序的模式是通过一次又一次地求解问题而形成的。同样对象有自己的模式通过理解、使用和重用而形成。下面是描述不是方法。它简直就是对象期望的设计出现时的观察结果。)对象发现这个阶段出现在程序的最初分析期间。可以通过寻找外部因素与界线、系统中的元素副本和最小概念单元而发现对象。如果已经有了一组类库某些对象是很明显的。类之间的共同性(暗示了基类和继承类)可以立刻出现或在设计过程的后期出现。)对象装配我们在建立对象时会发现需要一些新成员这些新成员在对象发现时期未出现过。对象的这种内部需要可能要用新类去支持它。)系统构造对对象的更多要求可能出现在以后阶段。随着不断的学习我们会改进我们的对象。与系统中其它对象通讯和互相连接的需要可能改变已有的类或要求新类。)系统扩充当我们向系统增添新的性能时可能发现我们先前的设计不容易支持系统扩充。这时我们可以重新构造部分系统并很可能要增加新类。)对象重用这是对类的真正的重点测试。如果某些人试图在全新的情况下重用它他们会发现一些缺点。当我们修改一个类以适应更新的程序时类的一般原则将变得更清楚直到我们有了一个真正可重用的对象。对象开发原则在这些阶段中提出考虑开发类时所需要的一些原则:)让特殊问题生成一个类然后在解其他问题时让这个类生长和成熟。)记住发现所需要的类是设计系统的主要内容。如果已经有了那些类这个项目就不困难了。)不要强迫自己在一开始就知道每一件事情应当不断地学习。)开始编程让一部分能够运行这样就可以证明或反驳已生成的设计。不要害怕过程语言风格的细面条式的代码类分割可以控制它们。坏的类不会破坏好的类。)尽量保持简单。具有明显用途的不太清楚的对象比很复杂的接口好。我们总能够从小的第章对象的演化下载参看DesignPatterns:ElementsofReusableObjectOrientedSoftwarebyErichGammaetal,AddisonWesley,。和简单的类开始当我们对它有了较好地理解时再扩展这个类接口但不可能简化已存在的类接口。方法承诺什么由于不同的原因方法承诺的东西往往比它们能够提供的东西多得多。这是不幸的因为当策略和不实际的期望同时出现时程序员会疑神疑鬼。一些方法的坏名声使得程序员丢弃了手上的其他方法忽视了一些有价值的技术。管理者的银子弹最坏的许诺是“这个方法将解决您的所有问题”。这一许诺也很可能用这样的思想表达即一个方法将解决实际上不存在解的问题或者至少在程序的设计领域内没有解的问题:一个贫穷的社团文化疲惫的、互相疏远或敌对的项目组成员不充分的时间和资源或试图解决一个实际上不能解的问题(资源不足)。最好的方法学不管它许诺什么都不解决这些或类似的任何问题。无论OOP还是C都无助于这样的问题。不幸的是在这种情况下管理员是这样的人:对于银子弹的警报他是最易动摇的。提高效率的工具这就是方法应当成为的东西。提高生产效率不仅取决于管理容易和花费不大而且取决于一开始就创建好的设计。由于一些方法学的创造动机是为了改善维护所以它们就片面地强调维护问题而忽视了设计的漂亮和完整。实际上好的设计应当是首要的目标好的OOP设计也应当容易维护但这是它的附加作用。方法应当提供什么不管为特殊方法提出什么要求它都应当提供这一节所列出的基本功能:允许为讨论这个项目将完成什么和如何做而进行通讯的约定支持项目结构化的系统能用某抽象形式描述项目的一组工具(使得程序员能容易地观察和操作项目)。如过去介绍过的一个更微妙的问题是该方法对待最宝贵资源组员积极性的“态度”。通讯约定对于很小的项目组可以用紧密接触的方式自然维持通讯。这是理想的请况。C的最大的好处之一是它可以使项目由很少的项目组成员建立因此明白表示的通讯能使维护变得容易因而通讯费用低项目组能更快地建立。情况并不总是这样理想有可能项目组成员很多项目很复杂这就需要某种形式的通讯原则。方法提供一种在项目组成员之间形成“约定”的办法。可以用两种方式看待这样的约定:)敌对的约定基于参与的当事人之间互有疑问以使得没有人出格且每个人都做应该做的事情。约定清楚地说明如果他们不做这些事会出现坏的结果。这样看待任何约定我们就已经输了因为我们已经认为其他人是不可信赖的了。如果不能信任某人约定并不能确保好的行为。)信息的约定是一种努力使每个人都知道我们已经在哪些方面取得了一致的意见。这是对通讯的辅助使得每个人能看到它并说“是的这是我认为我们将要做的事情”。它是协议作出后对协议的表述只是消除误解。这类约定能最小化并容易读。C编程思想下载AreferencetovampiresmadeinTheMythicalManMonth,byFredBrooks,AddisionWesley,。有用的方法不鼓励敌对的约定而重点是在通讯上。使系统结构化结构化是系统的核心。如果一个方法能做些事情那么它就必须能够告诉程序员:)需要什么类)如何把它们连接在一起形成一个工作系统。一个方法产生这些回答需要一个过程即首先对问题进行分析最终对类、系统和类之间传递的消息进行某种表述。描述工具模型不应当比它描述的系统更复杂。一种好的模型仅提供一种抽象。程序员一定不会使用只对特殊方法有用的描述工具。他能使自己的工具适合自己的各种需要。(例如在本章后面建议一种符号用于商业字处理机。)下面是有用的符号原则:)方法中不含有不需要的东西。记住“七加减二”规则的复杂性。(瞬间人们只能在头脑中存放这么多的条目。)额外的细节就变成了负担必须维护它为它花钱。)通过深入到描述层人们应当能够得到所需要的信息。即我们可以在较高的抽象层上创建一些隐藏的层仅在需要时它们才可见。)符号应当尽可能少。“过多的噱头使得软件变坏”。)系统设计和类设计是互相隔离的问题。类是可重用工具而系统是对特殊问题的解(虽然系统设计也是可重用的)。符号应当首先集中在系统设计方面。)类设计符号是必须的吗?由C语言提供的类表达对大多数情况是足够的。如果符号在描述类方面不能比用OOP语言描述有一个明显的推进那么就不要用它。)符号应当在隐藏对象的内部实现。在设计期间这些内部实现一般不重要。)保持符号简单。我们想用我们的方法做的所有事情基本上就是发现对象及其如何互相连接以形成系统。如果一个方法或符号要求更多的东西则应当问一问该方法花费我们的时间是否合理。不要耗尽最重要的资源我的朋友MichaelWilk来自学术界也许并不具备做评判的资格(从某个人那里听说的新观点)但他观察到项目、开发组或公司拥有的最重要的资源是积极性。不管问题如何困难过去失败多么严重工具多么原始或不成套积极性都能克服这些障碍。不幸的是各种管理技术常常完全不考虑积极性或因为不容易度量它就认为它是“不重要”的因素他们认为如果管理完善项目就能强制完成。这种认识有压制开发组积极性的作用因为他们会感到公司除了利益动机以外就没有感兴趣的东西了。一旦发生这种现象组员就变成了“雇员”看着钟想着感兴趣的、分心的事情。方法和管理技术是建立在动机和积极性的基础上的最宝贵的资源应当是对项目真正感兴趣。至少应当考虑OOP设计方法对开发组士气起的作用。“必”读在选择任何方法之前从并不想出售方法的人那儿得到意见是有帮助的。不真正地理解我们想要一种方法是为了做什么或它能为我们做什么那么采用一种方法很容易。其他人正在用它这似乎是很充足的理由。但是人们有一种奇怪的心理:如果他们相信某件事能解决他们的问题他们就将试用它(这是经验是好的)。但是如果它不能解决他们的问题他们可能加倍地努力并且开始大声宣布他们已经发现了伟大的东西(这是否定是不好的)。这个假设是如果见到同一条船上有其他人就不感到孤单即便这条船哪儿也不去。第章对象的演化下载这并不是说所有的方法学都什么也不做而是用精神方法使程序员武装到牙齿这些方法能使程序员保持实验精神(“它不工作让我们再试其它方法”)和跳出否定方式(“不这根本不是问题每样东西都很好我们不需要改变”)。我认为在选择方法之前读下面的书会为我们提供这些精神武器。《软件的创造力》(SoftwareCreativityRobertGlass编PrenticeHall,)。这是我所看到的讨论整个方法学前景最好的书。它是由Glass已经写过的短文和文章以及收集到的东西组成的(PJPlauger是一个撰稿者)反映出他在该主题上多年的思考和研究。他们愉快地说明什么是必须的并不东拉西扯和扫我们的兴不说空话而且这里有几百篇参考文献。所有的程序员和管理者在陷入方法学泥潭之前应当读这本书。《人件》(PeoplewareTomDemarco和TimothyLister编DorsetHouse,)。虽然他们有软件开发方面的背景而且本书大体上是针对项目和开发组的但是这本书的重点是人和他们的需要方面而不是技术和技术的需要方面。他们谈论创造一个环境在其中人们是幸福和高效率的而不是决定人们应当遵守什么样的规则以使得他们成为机器的合适部件。我认为这本书后面的观点是对程序员在采用XYZ方法然后平静地做他们总是做的事情时微笑和点头的最大贡献。《复杂性》(Complexity,MMitchellWaldrop编SimonSchuster,)。此书集中了SantaFe,NewMexico的一组持不同观点的科学家讨论单个原则不能解决的实际问题(经济学中的股票市场、生物学的生命原始形式、为什么人们做他们在社会中应做的事情等等)。通过物理学、经济学、化学、数学、计算机科学、社会学和其他学科的交叉对这些问题的一种多原则途径正在发展。更重要的是思考这些极其复杂问题的不同方法正在形成。抛开数学的确定性人们想写一个预言所有行为的方程首先观察和寻找一个模式

用户评价(0)

关闭

新课改视野下建构高中语文教学实验成果报告(32KB)

抱歉,积分不足下载失败,请稍后再试!

提示

试读已结束,如需要继续阅读或者下载,敬请购买!

文档小程序码

使用微信“扫一扫”扫码寻找文档

1

打开微信

2

扫描小程序码

3

发布寻找信息

4

等待寻找结果

我知道了
评分:

/49

C++ 编程思想

仅供在线阅读

VIP

在线
客服

免费
邮箱

爱问共享资料服务号

扫描关注领取更多福利