OOC:内容
来自 ChinaUnix Wiki
Preface
No programming technique solves all problems.
No programming language produces only correct results.
No programmer should start each project from scratch.
没有能解决一切问题的编程技术
没有只产生正确结果的编程语言
没有每个项目都从头写的程序员
Object-oriented programming is the current cure-all — although it has beenaround for much more then ten years. At the core, there is little more to it then finally applying the good programming principles which we have been taught for more then twenty years. C++ (Eiffel, Oberon-2, Smalltalk ... take your pick) is the New Language because it is object-oriented — although you need not use it thatway if you do not want to (or know how to), and it turns out that you can do just as well with plain ANSI-C. Only object-orientation permits code reuse between projects — although the idea of subroutines is as old as computers and good programmers always carried their toolkits and libraries with them.
This book is not going to praise object-oriented programming or condemn the Old Way. We are simply going to use ANSI-C to discover how object-oriented programming is done, what its techniques are, why they help us solve bigger problems, and how we harness generality and program to catch mistakes earlier. Along the way we encounter all the jargon — classes, inheritance, instances, linkage,methods, objects, polymorphisms, and more — but we take it out of the realm of magic and see how it translates into the things we have known and done all along.
I had fun discovering that ANSI-C is a full-scale object-oriented language. To share this fun you need to be reasonably fluent in ANSI-C to begin with — feeling comfortable with structures, pointers, prototypes, and function pointers is a must. Working through the book you will encounter all the new speak — according to Orwell and Webster a language ‘‘designed to diminish the range of thought’’ — and I will try to demonstrate how it merely combines all the good programming principles that you always wanted to employ into a coherent approach. As a result, you may well become a more proficient ANSI-C programmer.
The first six chapters develop the foundations of object-oriented programming with ANSI-C. We start with a careful information hiding technique for abstract data types, add generic functions based on dynamic linkage and inherit code by judicious lengthening of structures. Finally, we put it all together in a class hierarchy that makes code much easier to maintain.
Programming takes discipline. Good programming takes a lot of discipline, a large number of principles, and standard, defensive ways of doing things right. Programmers use tools. Good programmers make tools to dispose of routine tasks once and for all. Object-oriented programming with ANSI-C requires a fair amount of immutable code — names may change but not the structures. Therefore, in chapter seven we build a small preprocessor to create the boilerplate required. It looks like yet another new object-oriented dialect language (yanoodl perhaps?) but it should not be viewed as such — it gets the dull parts out of the way and lets us concentrate on the creative aspects of problem solving with better techniques. ooc(sorry) is pliable: we have made it, we understand it and can change it, and it writes the ANSI-C code just like we would.
The following chapters refine our technology. In chapter eight we add dynamic type checking to catch our mistakes earlier on. In chapter nine we arrange for automatic initialization to prevent another class of bugs. Chapter ten introduces delegates and shows how classes and callback functions cooperate to simplify, for example, the constant chore of producing standard main programs. More chapters are concerned with plugging memory leaks by using class methods, storing and loading structured data with a coherent strategy, and disciplined error recovery through a system of nested exception handlers.
Finally, in the last chapter we leave the confines of ANSI-C and implement the obligatory mouse-operated calculator, first for curses and then for the X Window System. This example neatly demonstrates how elegantly we can design and implement using objects and classes, even if we have to cope with the idiosyncrasies of foreign libraries and class hierarchies.
Each chapter has a summary where I try to give the more cursory reader a run-down on the happenings in the chapter and their importance for future work. Most chapters suggest some exercises; however, they are not spelled out formally, because I firmly believe that one should experiment on one’s own. Because we are building the techniques from scratch, I have refrained from making and using a massive class library, even though some examples could have benefited from it. If you want to understand object-oriented programming, it is more important to first master the techniques and consider your options in code design; dependence on somebody else’s library for your developments should come a bit later.
An important part of this book is the enclosed source floppy — it has a DOS filesystem containing a single shell script to create all the sources arranged by chapter.
There is a ReadMe file — consult it before you say make. It is also quite instructive to use a program like diff and trace the evolution of the root classes and ooc reports through the later chapters.
The techniques described here grew out of my disenchantment with C++ when I needed object-oriented techniques to implement an interactive programming language and realized that I could not forge a portable implementation in C++. I turned to what I knew, ANSI-C, and I was perfectly able to do what I had to. I have shown this to a number of people in courses and workshops and others have used the methods to get their jobs done. It would have stopped there as my footnote to a fad, if Brian Kernighan and my publishers, Hans-Joachim Niclas and John Wait, had not encouraged me to publish the notes (and in due course to reinvent it all once more). My thanks go to them and to all those who helped with and suffered through the evolution of this book. Last not least I thank my family — and no,object-orientation will not replace sliced bread.
Hollage, October 1993
Axel-Tobias Schreiner
前言
没有万能的编程技术
没有只产生正确结果的程序语言
不是每个项目的编程都要从零开始
面世十多年后,面向对象编程现在是灵丹妙药,无所不用。本质上,除了应用20多年来一贯推行的良好编程原则之外,面向对象编程并没有更多新东西。C++(Eiffel、Oberon-2、SmallTalk……随便你举哪个来说)之所以是“新编程语言”是因为它是面向对象的。当然,如果你不想或不知道怎么做,你不必非得用它去面向对象不可。即使要面向对象,普通ANSI-C做得一样好。虽然子程序的概念与计算机一样久远,优秀的程序员也总是随身带着他们的工具和程序库,真正使得代码可以在其它项目里可再用的是面向对象的思想。
本书既不推崇面向对象的编程也不谴责传统方式的编程。我们将仅仅发掘如何用ANSI-C实现面向对象的编程,要用到哪些技术,为什么这些技术帮助我们解决更大的问题,以及如何制约过度的一般性并及早捕获出错。本书中,你会接触到所有这些行话术语——类、继承、实例、连接、方法、对象、多态以及更多其它——不过我们剥去其神奇外衣,看看它们如何还原为我们一直熟悉的东西及做过的事情。
发现ANSI-C是一门完全面向对象的语言于我是很有乐趣的事情。要分享我这份乐趣,你起码得对ANSI-C足够熟练——至少对结构、指针、原型、函数指针不陌生。随着本书的进展,你将遇到一个“新语言”——按照“新语言”(newspeak)原作Orwell和韦氏词典的解释,“新语言”设计目的就是缩减思维的广度——而我会尽力证明,它仅仅汇合了所有的你总想一致运用的良好编程原则。结果,你可以成为一个更专业的ANSI-C程序员。
前六章建立用ANSI-C做面向对象编程的基础。我们从抽象数据类型的一个谨慎的信息隐蔽技术开始,然后加入基于动态连接的一般抽象函数,再通过明智而谨慎地扩充结构来继承代码。最后,我们将所有上述发展放进一个类树中,使代码的维护容易得多。
编程需要规范。良好的编程需要实行严格的规范、遵守众多原则标准以及确保正确无误的防范措施。程序员使用工具,而优秀的程序员制作工具来一劳永逸地处理那些重复的日常事务。用ANSI-C的面向对象的编程需要相当大量的有“免疫”功能的编码——名称可能变化但结构不变。因此,在第7章里我们搭建一个小小的预处理器,用来创建所需要的模板。这模板很像是另一个方言式面向对象的语言(也许就叫yanhoodl?)。不过它不是,它剔除“方言”中枯燥无味的东西,让我们专注于用更好的技术解决问题的创新。OOC(请原谅这个命名——译注:OOC在英文中又有缺现钱的意,故作者有此调侃)是坚韧的:我们创造了它,了解它,能够改变它,而且它也如我们所愿使用ANSI-C。
余下章节继续深入讨论我们的技术。第8章加入动态类型检测来实现错误的早期捕获。第9章讲自动初始化防止另一类软件缺陷。第10章引入委托代理,说明类和回调函数如何协作,共同完成(比如)简化标准主程序的生成这样的常规任务。其他章节专注于用类方法堵塞内存泄漏,用一致的策略存储和加载结构数据,用嵌套的异常处理系统实行规范的纠错。
在最后一章,我们搁置ANSI-C,做了一个期望已久的鼠标操作的计算器——先是针对curses然后是针对X Window。这个例子清晰地表明:即使被迫适应外部库和类树的混杂,有了对象和类,我们可以多么精致地设计和实现一个应用。
每一章都有章结。我试图在章结中给随意浏览的读者一个本章的梗概以及它对此后章节的重要性。各章多数都备有习题,不过不必当成正式作业来完成,因为我坚定的相信读者应当自己探索。由于我们是从从无到有建立新的技术——尽管有些个例应该能够从中获益——我一直避免制作和使用庞大的类库。如果你真要理解面向对象的编程,更重要的是先掌握面向对象的技术并且在代码设计范围内运用这些技术;至于开发中依赖使用他人的库,应当稍后再说。
本书的一个重要部分是所附源码软盘,其上有一个DOS文件系统,包括一个SHELL脚本来生成所有按章排序的源码。还有一个ReadMe文件——在你执行make命令前要先看看这个文件。使用diff类的工具追踪根类和ooc报告在后续章节的演化也是非常有帮助的。
这里呈上的技术起源于我对C++的失望。当时我需要面向对象技术实现一个交互式编程语言,但我失望地意识到没法用C++“敲打”出一个可移植的东西来。我转向我所了解的,ANSI-C,然后我完全能够做我本来要做的事情。我将这个经历告诉课程上的几个人,然后他们用同样的方法完成了他们的工作。如果不是布赖恩·克尼翰(Brian Kernighan)以及我的出版商翰斯·尼科拉斯(Hans-Joachim Niclas)和约翰·维特(John Wait)他们鼓励我出版,这个故事可能就止于是我对一个流行时尚的脚注(当然在以后上课要用时再从头来过一遍)。我感谢他们和所有帮助本书的进展并且与此同甘共苦的人。最后也是最重要的,感谢我的家庭——面向对象绝不会代替餐桌上的面包。 阿塞尔-托彼亚斯·斯莱内尔(Axel-Tobias Schreiner)1993年10月于Hollage
第一章:Abstract Data Types -- Information Hiding
第二章:Dynamic Linkage -- Generic Functions
第三章: Programming Savvy --Arithmetic Expressions
第四章: InheritanceCode Reuse and Refinement
第六章: Class Hierarchy Maintainability
