当前位置:文档之家› JAVA编程思想的翻译

JAVA编程思想的翻译

JAVA编程思想第2章一切都是对象尽管以C++为基础,但Java是一种更纯粹的面向对象程序设计语言”。

无论C++还是Java都属于杂合语言。

但在Java中,设计者觉得这种杂合并不象在C++里那么重要。

杂合语言允许采用多种编程风格;之所以说C++是一种杂合语言,是因为它支持与C语言的向后兼容能力。

由于C++是C的一个超集,所以包含的许多特性都是后者不具备的,这些特性使C++在某些地方显得过于复杂。

Java语言首先便假定了我们只希望进行面向对象的程序设计。

也就是说,正式用它设计之前,必须先将自己的思想转入一个面向对象的世界(除非早已习惯了这个世界的思维方式)。

只有做好这个准备工作,与其他OOP语言相比,才能体会到Java的易学易用。

第6章类再生“Java引人注目的一项特性是代码的重复使用或者再生。

但最具革命意义的是,除代码的复制和修改以外,我们还能做多得多的其他事情。

”在象C那样的程序化语言里,代码的重复使用早已可行,但效果不是特别显著。

与Java 的其他地方一样,这个方案解决的也是与类有关的问题。

我们通过创建新类来重复使用代码,但却用不着重新创建,可以直接使用别人已建好并调试好的现成类。

但这样做必须保证不会干扰原有的代码。

在这一章里,我们将介绍两个达到这一目标的方法。

第一个最简单:在新类里简单地创建原有类的对象。

我们把这种方法叫作“合成”,因为新类由现有类的对象合并而成。

我们只是简单地重复利用代码的功能,而不是采用它的形式。

第二种方法则显得稍微有些技巧。

它创建一个新类,将其作为现有类的一个“类型”。

我们可以原样采取现有类的形式,并在其中加入新代码,同时不会对现有的类产生影响。

这种魔术般的行为叫作“继承”(Inheritance),涉及的大多数工作都是由编译器完成的。

对于面向对象的程序设计,“继承”是最重要的基础概念之一。

第14章多线程利用对象,可将一个程序分割成相互独立的区域。

我们通常也需要将一个程序转换成多个独立运行的子任务。

象这样的每个子任务都叫作一个“线程”(Thread)。

编写程序时,可将每个线程都想象成独立运行,而且都有自己的专用CPU。

一些基础机制实际会为我们自动分割CPU的时间。

我们通常不必关心这些细节问题,所以多线程的代码编写是相当简便的。

这时理解一些定义对以后的学习狠有帮助。

“进程”是指一种“自包容”的运行程序,有自己的地址空间。

“多任务”操作系统能同时运行多个进程(程序)——但实际是由于CPU分时机制的作用,使每个进程都能循环获得自己的CPU时间片。

但由于轮换速度非常快,使得所有程序好象是在“同时”运行一样。

“线程”是进程内部单一的一个顺序控制流。

因此,一个进程可能容纳了多个同时执行的线程。

多线程的应用范围很广。

但在一般情况下,程序的一些部分同特定的事件或资源联系在一起,同时又不想为它而暂停程序其他部分的执行。

这样一来,就可考虑创建一个线程,令其与那个事件或资源关联到一起,并让它独立于主程序运行。

一个很好的例子便是“Quit”或“退出”按钮——我们并不希望在程序的每一部分代码中都轮询这个按钮,同时又希望该按钮能及时地作出响应(使程序看起来似乎经常都在轮询它)。

事实上,多线程最主要的一个用途就是构建一个“反应灵敏”的用户界面。

第15章网络编程历史上的网络编程都倾向于困难、复杂,而且极易出错。

程序员必须掌握与网络有关的大量细节,有时甚至要对硬件有深刻的认识。

一般地,我们需要理解连网协议中不同的“层”(Layer)。

而且对于每个连网库,一般都包含了数量众多的函数,分别涉及信息块的连接、打包和拆包;这些块的来回运输;以及握手等等。

这是一项令人痛苦的工作。

但是,连网本身的概念并不是很难。

我们想获得位于其他地方某台机器上的信息,并把它们移到这儿;或者相反。

这与读写文件非常相似,只是文件存在于远程机器上,而且远程机器有权决定如何处理我们请求或者发送的数据。

Java最出色的一个地方就是它的“无痛苦连网”概念。

有关连网的基层细节已被尽可能地提取出去,并隐藏在JVM以及Java的本机安装系统里进行控制。

我们使用的编程模型是一个文件的模型;事实上,网络连接(一个“套接字”)已被封装到系统对象里,所以可象对其他数据流那样采用同样的方法调用。

除此以外,在我们处理另一个连网问题——同时控制多个网络连接——的时候,Java内建的多线程机制也是十分方便的。

第16章设计范式在向面向对象程序设计的演化过程中,或许最重要的一步就是“设计范式”(Design Pattern)的问世。

它在由Gamma,Helm和Johnson编著的《Design Patterns》一书中被定义成一个“里程碑”(该书由Addison-Wesley于1995年出版,注释①)。

那本书列出了解决这个问题的23种不同的方法。

在最开始,可将范式想象成一种特别聪明、能够自我适应的手法,它可以解决特定类型的问题。

也就是说,它类似一些需要全面认识某个问题的人。

在了解了问题的方方面面以后,最后提出一套最通用、最灵活的解决方案。

具体问题或许是以前见到并解决过的。

然而,从前的方案也许并不是最完善的,大家会看到它如何在一个范式里具体表达出来。

尽管我们称之为“设计范式”,但它们实际上并不局限于设计领域。

思考“范式”时,应脱离传统意义上分析、设计以及实施的思考方式。

相反,“范式”是在一个程序里具体表达一套完整的思想,所以它有时可能出现在分析阶段或者高级设计阶段。

这一点是非常有趣的,因为范式具有以代码形式直接实现的形式,所以可能不希望它在低级设计或者具体实施以前显露出来(而且事实上,除非真正进入那些阶段,否则一般意识不到自己需要一个范式来解决问题)。

范式的基本概念亦可看成是程序设计的基本概念:添加一层新的抽象!只要我们抽象了某些东西,就相当于隔离了特定的细节。

而且这后面最引人注目的动机就是“将保持不变的东西身上发生的变化孤立出来”。

这样做的另一个原因是一旦发现程序的某部分由于这样或那样的原因可能发生变化,我们一般都想防止那些改变在代码内部繁衍出其他变化。

这样做不仅可以降低代码的维护代价,也更便于我们理解(结果同样是降低开销)。

为设计出功能强大且易于维护的应用项目,通常最困难的部分就是找出我称之为“领头变化”的东西。

这意味着需要找出造成系统改变的最重要的东西,或者换一个角度,找出付出代价最高、开销最大的那一部分。

一旦发现了“领头变化”,就可以为自己定下一个焦点,围绕它展开自己的设计。

所以设计范式的最终目标就是将代码中变化的内容隔离开。

如果从这个角度观察,就会发现本书实际已采用了一些设计范式。

举个例子来说,继承可以想象成一种设计范式(类似一个由编译器实现的)。

在都拥有同样接口(即保持不变的东西)的对象内部,它允许我们表达行为上的差异(即发生变化的东西)。

合成亦可想象成一种范式,因为它允许我们修改——动态或静态——用于实现类的对象,所以也能修改类的运作方式。

Thinking in JavaBruce EckelPresident,MindView Inc.2:Everything is an objectAlthough it is based on C++,Java is more of a“pure”object-oriented language.Both C++and Java are hybrid languages,but in Java the designers felt that the hybridization was not as important as it was in C++.A hybrid language allows multiple programming styles;the reason C++is hybrid is to support backward compatibility with the C language.Because C++is a superset of the C language,it includes many of that language’s undesirable features which can make some aspects of C++overly complicated.The Java language assumes that you want to do only object-oriented programming.This means that before you can begin you must shift your mindset into an object-oriented world (unless it’s already there).The benefit of this initial effort is the ability to program in a language that is simpler to learn and to use than many other OOP languages.6:Reusing classesOne of the most compelling features about Java is code reuse.But to be revolutionary,you’ve got to be able to do a lot more than copy code and change it.That’s the approach used in procedural languages like C,and it hasn’t worked very well. Like everything in Java,the solution revolves around the class.You reuse code by creating new classes,but instead of creating them from scratch,you use existing classes that someone has already built and debugged.The trick is to use the classes without soiling the existing code.In this chapter you’ll see two ways to accomplish this.The first is quite straightforward:You simply create objects of your existing class inside the new class.This is called composition because the new class is composed of objects of existing classes.You’re simply reusing the functionality of the code,not its form.The second approach is more subtle.It creates a new class as a type of an existing class.You literally take the form of the existing class and add code to it without modifying the existing class. This magical act is called inheritance,and the compiler does most of the work.Inheritance is one of the cornerstones of object-oriented programming.14:Multiple threadsObjects provide a way to divide a program up into independent sections.Often,you also need to turn a program into separate,independently-running subtasks.Each of these independent subtasks is called a thread,and you program as if each thread runs by itself and has the CPU to itself.Some underlying mechanism is actually dividing up the CPU time for you,but in general,you don’t have to think about it,which makes programming with multiple threads a much easier task.Some definitions are useful at this point.A process is a self-contained running program with its own address space.A multitasking operating system is capable of running more than one process(program)at a time,while making it look like each one is chugging along by periodically providing CPU cycles to each process.A thread is a single sequential flow of control within a process.A single process can thus have multiple concurrently executing threads.There are many possible uses for multithreading,but in general,you’ll have some part of your program tied to a particular event or resource,and you don’t want to hang up the rest of your program because of that.So you create a thread associated with that event or resource and let it run independently of the main program.A good example is a“quit”button–you don’t want to be forced to poll the quit button in every piece of code you write in your program and yet you want the quit button to be responsive,as if you were checking it regularly.In fact,one of the most immediately compelling reasons for multithreading is to produce a responsive userinterface.15:Network programmingHistorically,network programming has been error-prone,difficult,and complex.The programmer had to know many details about the network and sometimes even the hardware.You usually needed to understand the various“layers”of the networking protocol, and there were a lot of different functions in each different networking library concerned with connecting,packing,and unpacking blocks of information;shipping those blocks back and forth; and handshaking.It was a daunting task.However,the concept of networking is not so difficult.You want to get some information from that machine over there and move it to this machine here,or vice versa.It’s quite similar to reading and writing files,except that the file exists on a remote machine and the remote machine can decide exactly what it wants to do about the information you’re requesting or sending.One of Java’s great strengths is painless networking.As much as possible,the underlying details of networking have been abstracted away and taken care of within the JVM and local machine installation of Java.The programming model you use is that of a file;in fact,you actually wrap the network connection(a“socket”)with stream objects,so you end up using the same method calls as you do with all other streams.In addition,Java’s built-in multithreading is exceptionally handy when dealing with another networking issue:handling multiple connections at once.16:Design patternsProbably the most important step forward in object-oriented design is the“design patterns”movement,chronicled in Design Patterns,by Gamma,Helm,Johnson&Vlissides (Addison-Wesley1995).1That book shows23different solutions to particular classes of problems.Initially,you can think of a pattern as an especially clever and insightful way of solving a particular class of problems.That is,it looks like a lot of people have worked out all the angles of a problem and have come up with the most general,flexible solution for it.The problem could be one you have seen and solved before,but your solution probably didn’t have the kind of completeness you’ll see embodied in a pattern.Although they’re called“design patterns,”they really aren’t tied to the realm of design.A pattern seems to stand apart from the traditional way of thinking about analysis,design,and implementation.Instead,a pattern embodies a complete idea within a program,and thus it can sometimes appear at the analysis phase or high-level design phase.This is interesting because a pattern has a direct implementation in code and so you might not expect it to show up before low-level design or implementation(and in fact you might not realize that you need a particular pattern until you get to those phases).The basic concept of a pattern can also be seen as the basic concept of program design: adding a layer of abstraction.Whenever you abstract something you’re isolating particular details,and one of the most compelling motivations behind this is to separate things that change from things that stay the same.Another way to put this is that once you find some part of your program that’s likely to change for one reason or another,you’ll want to keep those changes from propagating other changes throughout your code.Not only does this make the code much cheaper to maintain,but it also turns out that it is usually simpler to understand(which results in lowered costs).Often,the most difficult part of developing an elegant and cheap-to-maintain design is in discovering what I call“the vector of change.”(Here,“vector”refers to the maximum gradient and not a collection class.)This means finding the most important thing that changes in your system,or put another way,discovering where your greatest cost is.Once you discover the vector of change,you have the focal point around which to structure your design.So the goal of design patterns is to isolate changes in your code.If you look at it this way, you’ve been seeing some design patterns already in this book.For example,inheritance can be thought of as a design pattern(albeit one implemented by the compiler).It allows you to express differences in behavior(that’s the thing that changes)in objects that all have the same interface (that’s what stays the same).Composition can also be considered a pattern,since it allows you to change–dynamically or statically–the objects that implement your class,and thus the way that class works.。

相关主题