阅读《疯狂Java讲义》

从2000年至今,Java语言一直是应用最广的开发语言,并拥有最广泛的开发人群。如今,java已经不再简单地是一门语言,它更像一个完整的体系,一个系统的开发平台。更甚至,它被延伸成一种开源精神。

如何学习java?

程序的作用是:解决问题--如果你的程序不能解决你自己的问题,如何期望你的程序去解决别人的问题呢?那你的程序的价值何在?所以笔者认为:最好的学习方法就是“案例驱动”--知道为什么要用这个知识点,才去学这个知识点,而不是盲目学习!因此本书强调编程实战,强调以项目激发编程兴趣。

java语言具有功能强大和简单易用两个特征。

Sun公司在1995年年初发布了java语言,Sun公司直接把java放到互联网山,免费给大家使用。甚至连源代码也不保密,也放在互联网上向所有人公开。

  • J2ME:主要用于控制移动设备和信息家电等有限存储的设备。
  • J2SE:是整个java技术的核心和基础,它是j2ME和J2EE编程的基础,也是这本书主要介绍的内容。
  • J2EE:java技术中应用最广泛的部分,J2EE提供了企业应用开发相关的完整解决方案。

java的设计宗旨独立于任何平台,自然不会提供太多的Windows特性。但这也正是java语言的优势:跨平台。

事实上,Ruby确实是一种非常简洁的解释性语言,它是一种纯粹的面向对象编程语言,甚至比java更纯粹(在java语言里,还有基本数据类型等不是对象的变量,但在Ruby语言里,一切都是对象)。除此之外,Ruby还提供了许多额外的便捷功能:闭包、迭代和集合等,这些都是为了达到Ruby语言创始人的梦想:让Ruby开发者能享受编程的快乐。

Ruby语言还有一个重要的优点:它也是完全跨平台的,可以在任何操作系统上解释执行。

关于Rails框架和java EE平台,其实是各有优势的:Rails平台的简洁性,易用性会在中小型应用上发挥出更大的吸引力;但java EE平台则提供了更多的选择,适合对技术有精准把握的开发者,用于解决有复杂需求的大型企业级应用。

java语言是一种特殊的高级语言,它既具有解释性语言的特征,也具有编译型语言的特征,因为java程序要经过先编译,后解释两个步骤。

封装,继承和多态。

  • OOA-面向对象分析
  • OOD-面向对象设计
  • OOP-面向对象编程

目前业界统一采用UML(统一建模语言)来描述并记录OOA和OOD的结果。

结构化程序设计简介

结构化程序设计方法主张按功能来分析系统需求,其主要原则可概括为自顶向下,逐步求精,模块化等。结构化程序设计首先采用结构化分析方法对系统进行需求分析,然后使用结构化设计方法对系统进行概要设计,详细设计,最后采用结构化编程方式来实现系统。使用这种SA,SD和SP的方式可以较好地保证软件系统的开发进度和质量。

因为结构化程序设计方法主张按功能把软件系统逐步细分,因此这种方式也被成为面向功能的程序设计方法;结构化程序设计的每个功能都负责对数据进行一次处理,每个功能都接受一些数据,处理完后输出一些数据,这种处理方式也被成为面向数据流的处理方式。

结构化程序设计里最小的程序单元是函数,每个函数都负责完成一个功能,用于接受一些输入数据,函数对这些输入数据进行处理,处理结束后输出一些数据。整个软件系统由一个一个函数组成,从而完成整个软件系统的功能。

结构化设计需要采用自顶而下的设计方式,在设计阶段就需要考虑每个模块应该分解成哪些子模块,每个子模块又分解成哪些更小的模块......以此类推,直至将模块细分成一个一个函数。

每个函数都是具有输入,输出的子系统,函数的输入数据包括函数形参,全局变量和常量等,函数的输出数据包括函数返回值以及传出参数等。结构化程序设计方式的局限性有如下两个:

  • 设计不够直观,与人类习惯思维不一致。采用结构化程序分析,设计时,开发者需要将客观世界模型分解成一个一个功能,每个功能用以完成一定的数据处理。
  • 适应性差,可扩展性不强。由于结构化设计采用自顶而下的设计方式,所以当用户的需求发生改变,或需要修改现有的实现方式时,都需要自顶而下地修改模块结构,这种方式的维护成本相当大。

任何简单或复杂的算法都可以由顺序结构,选择结构和循环结构这三种基本结构组合而成。

java语言是面向对象的,但java的方法里则是一种结构化的程序流。

面型对象程序设计简介

面向对象是一种更优秀的程序设计方法,它的基本思想是使用类,对象,继承,封装,消息等基本概念来进行程序设计。它是从现实世界中客观存在的事物(即对象)出发来构造软件系统,并在系统构造中尽可能运用人类的自然思维方式,强调直接以现实世界中的事物(即对象)为中心来思考问题,认识问题,并根据这些事物的本质特点, 把他们抽象地表示为系统中的类,作为系统的基本构成单元(而不是用一些与现实世界中的事物相关比较远,并且没有对应关系的其他过程来构造系统),这使得系统可以直接映射客观世界,并保持客观世界中事物及其相互关系的本来面貌。

如果采用面向对象方式开发的软件系统,其最小的程序单元是类,这些类可以生成系统中的多个对象,而这些对象则直接映射成客观世界中的各种事物。

从世界观的角度可以认为:面向对象的基本哲学是认为世界是由各种各样具有自己的运动规律和内部状态的对象所组成的;不同对象之间的相互作用和通信构成了完整的现实世界。因此,人们应当按照现实世界这个本来面貌来理解世界,直接通过对象及其相互关系来反映世界。这样建立起来的系统才能符合现实世界的本来面目。

从方法学的角度可认为:面向对象的方法是面向对象的世界观在开发方法中的直接运用。它强调系统的结构应该直接与现实世界的结构相对应,应该围绕现实世界中的对象来构造系统,而不是围绕功能来构造系统。

从程序设计的角度来看,面向对象的程序设计语言必须有描述对象及其相互之间关系的语言成分。这些程序设计语言可以归纳为以下几类:系统中一切皆为对象:对象是属性及其操作的封装体;对象可按其性质分为类,对象称为类的实例;实例关系和继承关系是对象之间的静态关系;消息传递是对象之间动态联系的唯一形式,也是计算的唯一形式:方法是消息的序列。

对于面向对象的眼光来看,开发者从自己的使用角度或认识角度出发来定义类。就是说,我们定义类的目的是希望模拟客观世界的某种事物,并让自己明白,这种事物是用来做什么的,或者这种事物是怎么来的,对于我们有什么意义,这就睡面向对象方式的主要思考方式。因此,面向对象程序设计的主要优点是:让人类习惯的思维方法一致;稳定性哈;可重用性好;易于开发大型软件产品;可维护性好。

面向对象的基本特征

面向对象方法具有三个基本特征:封装,继承和多态,其中,继承是面向对象实现软件复用的重要手段,当子类继承父类后,子类作为一种特殊的父类,将直接获得父类的属性和方法;封装指的是将对象的实现细节隐藏起来,然后通过一些公用方法来暴露该对象的功能;多态指的是子类对象可以直接赋给父类变量,但运行时依然表现出子类的行为特征,这意味着同一个类型的对象在运行时可能表现出不同的行为特征。

除此之外,抽象也是面向对象的重要部分,抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面。抽象并不打算了解全部问题,而只是考虑部分问题。例如我们需要考察Person实体时,我们不可能在程序中将Person的所有细节都定义出来,通常只能定义Person的部分数据,部分行为特征--而这些数据,行为特征是软件系统所关心的部分。


提示:虽然抽象是面向对象的重要部分,但它不是面向对象的特征之一,因为所有编程语言都需要抽象。当开发者进行抽象时应该考虑哪些特征是软件系统所需要的,那么这些特征就应该使用程序记录,并表现出来。因此,需要抽象哪些特征没有必然的规定,而是取决于软件系统的功能需求。


面向对象还支持如下几个功能:

  • 对象是面向对象方法中最基本的概念,它的基本特点有:标识唯一性,分类性,多态性,封装性,模块独立性好。
  • 类是具有共同属性,共同方法的对象的集合。类是对象的抽象;对象则是类的实例。而类是整个软件呢系统最小的程序单元,类的封装性将各种信息细节隐藏起来并通过公用方法来暴露该类对外所提供的功能,从而提高了类的内聚性,降低了对象之间的耦合性。
  • 对象间的这种相互合作需要一个机制协作进行,这样的机制称为“消息”。消息是一个实例与另一个实例之间传递的信息。
  • 在面向对象方法中,类之间共享属性和操作的机制称为继承。已有的类可当做几类来引用,则新类相应的可当做派生类来引用。继承具有传递性。可分为单继承(一个继承只允许有一个直接父类,即类等级为树形结构)与多继承(一个类允许有多个直接父类)。

注意:由于多重继承可能引起继承结构的混乱,而且会大大降低程序的可理解性,所以java不再支持多继承。

在编程语言领域,还有一种“基于对象”的概念,这两个概念极易混淆:通常而言,"基于对象"也使用了对象,但是无法利用现有的对象模板产生新的对象类型,继而产生新的对象,也就是说,“基于对象”没有继承的特点。而“多态”表现为父类类型的子类对象实例,没有了继承的概念也就无从谈论“多态”。而面向对象的三大基本特征(封装,继承,多态)缺一不可,例如javaScript语言就是基于对象的,它使用一些封装好的对象,调用对象的方法,设置对象的属性。但是他们无法让开发者派生新对象类型。他们只能使用现有对象的方法和属性。

当你判断一门语言是否是面向对象的时候,通常可以使用后两个特性来加以判断。“面向对象”和“基于对象”都实现了“封装”的概念,但是面向对象实现了“继承和多态”,而“基于对象”没有实现这些。

从事面向对象编程的人按照分工来说,可以分为“类库的创建者”和“类库的使用者”。使用类库的人并不都是具备了面向对象思想的人,通常知道如何继承和派生新对象就可以使用类库了,然而我们的思维并没有真正地转过来,使用类库只是在形式上是面向对象,而实质上只是库函数的一种扩展。

UML(统一建模语言)介绍

面向对象软件开发需要经过OOA(面向对象分析),OOD(面向对象设计)和OOP(面向对象编程)三个阶段,OOA对目标系统进行分析并建立分析模型,并将之文档化,OOD用面向对象的思想将OOA的结果进行细化,得出设计模型。OOA和OOD的分析,设计结果需要统一的符号的描述,交流并记录,UML就是这种用于描述,记录OOA和OOD结果的符号表示法。

面向对象的分析与设计方法在20世纪80年代末至90年代中出现了一个高潮,UML是这个高潮的产物。在此期间出现了三种具有代表性的表示方法。

UML是一种定义良好,易于表达,功能强大且普遍适用的建模语言。它的作用域不限于支持面向对象的分析与设计,还支持从需求分析开始饿软件开发的全过程。

截止1996年10月,UML获得了工业界,科技界和应用界的广泛支持,已有700多个公司表示支持采用UML作为建模语言。1996年底,UML已稳占面向对象技术市场的85%,称为可视化建模语言事实上的工业标准。

很少有一个系统软件系统在分析,设计阶段把每个细节都使用十三种图形来表现。永远记住一点:不用把UML表示法当成一种负担,而应该把它当成一种工具,一种用于描述,记录软件分析设计的工具。最常用的UML图包括:用例图,类图,组件图,部署图,顺序图,通信图,活动图和状态机图等。

用例图

用例图用于描述系统提供的系列功能,而每个用例则代表系统的一个功能模块。用例图的主要目的是帮助开发团队以一种可视化的方式理解系统的需求功能,用例图对系统的实现不作任何说明,仅仅是系统功能的描述。

用例图包括用例(以一个椭圆表示,用例的名称放在椭圆的中心或椭圆下面),“角色”(Actor,也就是与系统交互的其他实体,以一个人形符号表示),角色和用例之间的关系(以简单的线段来表示),以及系统内用例之间的关系。用例图一般表示出用例的组织关系--要么是整个系统的全部用例,要么是完成具体功能的一组用例。

用例图通常用于表达系统或者系统范畴的高级功能。可以很容易看出该系统所提供的功能。这个系统允许注册用户登录,发帖和回复,其中发帖和回复需要依赖于登录;允许管理员删除其他人的帖子,删帖也需要依赖于登录。

用例图主要在需求分析阶段使用,用于与客户交流,保证系统需求的无二性,用实例图表示系统外观,不要指望用例图和系统的各个类之间有任何联系。不要把用例做得过多,过多的用例将导致难以阅读,难以理解;尽可能多地使用文字说明。

类图

类图是最古老,功能最丰富,使用最广泛的UML图形。类图表示系统中应该包含哪些实体,各实体之间如何关联;换句话说,它显示了系统的静态结构,类图可用于表示逻辑类逻辑类通常就是业务人员所谈及的事物种类。

类在类图上使用包含三个部分的矩形来描述,最上面额部分显示类的名称,中间部分包含类的属性,最下面的部分包含类的方法。

类图除了可以表示实体的静态内部结构之外,还可以表示实体之间的相互关系,类之间有三种基本关系:

  • 关联(包括聚合,组合)
  • 泛化(与继承同一个概念)
  • 依赖

关联

客观世界之间的两个实体之间总是存在千丝万缕的关系,当我们把这两个实体抽象到软件系统中时,两个类之间必然存在关联关系。关联具有一定的方向性:如果仅能从一个;类单方向地访问另一个类,则被称为单向关联;如果两个类可以互相访问对象,则被称为双向关联。一个对象能访问关联对象的数目被称为多重性,例如建立学生和老师之间的单向关联,则可以从学生访问老师,但从老师不能访问学生,关联使用一条实线来表示,带箭头的视线表示单向关联。

在很多时候,关联和属性很像,关联和属性的关键区别在于:类里的某个属性引用到另外一个实体时,则变成了关联。

关联关系包括两种特例:聚合和组合,他们都有部分和整体的关系,但通常认为组合比聚合更加严格。当某个实体聚合成另一个实体时,该实体还可以同时是另一个实体的部分,例如学生可以既是篮球俱乐部的成员,也可以是书法俱乐部的成员;当某个实体组成另一个实体时,该实体则不能同时是一个实体的部分。聚合使用带空心菱形框的实线表示,组合则使用带实心菱形框的实线表示。

泛化

泛化与继承是同一个概念,都是指的子类是一种特殊的父类,类与类之间的继承关系是非常普遍的,继承关系使用带空心箭头的实线表示。

依赖

如果一个类的改动会导致另一个类的改动,则称为两个类之间存在依赖。依赖关系使用带箭头的虚线表示,其中箭头指向被依赖的实体。依赖的常见可能原因:

  • 改动的类将消息发给另一个类。
  • 改动的类以另一个类作为数据部分。
  • 改动的类以另一个类作为操作参数。

通常而言,依赖是单向的,尤其是当数据表现和数据模型分开设计时,则数据表现依赖于数据模型。

组件图

对于现代的大型应用程序而言,通常不只是单独一个雷或单独一组类所能完成的,通常会由一个或多个可部署的组件组成。对java程序而言,可复用的组件通常打包成一个JAR,WAR等文件;对C/C++应用而言,可复用的组件通常是一个函数库,或者是一个DLL(动态链接库)文件。

组件图提供系统的物理视图。它的用途是显示系统中的软件对其他软件组件(例如,库函数)的依赖关系。组件图可以在一个非常高的层次上显示,从而仅显示粗粒度的组件,也可以在组件包层次上显示。UML使用一个特殊符号来表示组件。

部署图

现代的软件工程早已超出早期的单击程序,整个软件系统可能是跨国家、跨地区的分布式软件。软件的不同部分可能需要部署在不同地方、不同平台之上。部署图用于描述软件系统如何部署到硬件环境中。它的用途是显示软件系统不同的组件将在何处物理地运行,以及他们将如何彼此通信。

因为部署图是对物理运行情况进行建模,所以系统的生产人员就可以很好地利用这种图来安装,部署软件系统。

部署图中的符号包括组件图中所使用的符号元素,另外还增加了几个符号,主要是增加了节点的概念:节点是各种计算资源的通用名称,主要包括处理器和设备两种类型,两者的区别是处理器能够执行程序的硬件构件(如计算机主机),而设备是一种不具备计算能力的硬件构件(如打印机),UML中使用三维立方体表示节点,节点的名称位于立方体的顶部。

顺序图

顺序图显示具体用例(或者是用例的一部分)的详细流程,并且显示了流程中不同对象之间的调用关系,同时还可以很详细地显示对不同对象的不同调用。顺序图描述了对象之间的交互(顺序图和通信图都被称为交互图),重点在于描述消息及其时间顺序。

顺序图有两个维度:垂直维度以发生的时间顺序显示消息/调用的序列;水平维度显示消息被发送到的对象实例。顺序图的关键在于对象之间的消息,对象之间的信息传递就是所谓的消息发送,消息通常表现为对象调用另一个对象的方法或方法的返回值,发送者和接受者之间的箭头表示消息。

顺序图的绘制非常简单。顺序图的顶部每个框表示每个类的实例(对象),在框中,类实例名称和类名称之间用冒号或空格来分隔,例如,myReportGenerator:ReportGenerator。如果某个类实例向另一个类实例发送一条消息,则绘制一条具有指向接收类实例的带箭头的连线,并把消息/方法的名称放在连线上面。

对于某些特别重要的消息,我们还可以绘制一条带箭头的,指向发起类实例的虚线,将返回值标注在虚线上,绘制带返回值的信息可以使得序列图更易于阅读。

当绘制顺序图时,消息可以向两个方法扩展,消息穿梭在顺序图中,通常应该把消息发送者与接受者相邻摆放,尽量避免消息跨越多个对象。对象的激活器不是其存在的时间,而是它占据cpu的执行时期,绘制顺序图时,激活期要精确。

阅读顺序图也非常简单,通常我们从最上面的消息开始(也就是时间上最先开始的消息),然后沿消息方向依次阅读。

大多数情况,交互图中的参与者是对象,多以也可以直接在方框中放置对象名。

绘制顺序图主要帮助开发者对某个用例的内部执行清晰化,当需要考察某个用例内部若干对象行为时,应使用顺序图,顺序图擅长表现对象之间的协作顺序,不擅长表现行为的精确定义。

活动图

活动图和转态机图都被称为演化图,其区别和联系如下:

  • 活动图:用于描述用例内部的活动或方法的流程,如果除去活动图中的并行活动描述以后,它就变成流程图。
  • 状态机图:描述某一对象生命周期中需要关注的不同状态,并将详细描述刺激对象状态改变的事件,以及对象状态改变时所采取的动作。

演化图的五要素如下:

  • 状态:状态是对象响应事件前后的不同面貌,状态是某个时间段对象所保持的稳定态,目前的软件计算都是基于稳定态的,对象的稳定态是对象的固有特征,一个对象的状态一般是有限的。有限状态的对象是容易计算的,对象的状态越多,对象的状态迁移越复杂,对象状态可以想象成对象演化过程中的快照。
  • 事件:来自对象外界的刺激,通常的形式是消息的传递,只是相对对象而言发生了事件。事件是对象状态发生改变的原动力。
  • 动作:动作是对象针对所发生事件所做的处理,实际上通常表现为某个方法被执行。
  • 活动:活动是动作激发的后续系统行为。
  • 条件:条件指事件发生所需要具备的条件。

对于激发对象状态改变的事件,通常有两种类型:

  • 内部事件:从系统内部激发的事件,一个对象的方法(动作)调用,(通过事件激活)另一个对象方法(动作)。
  • 外部事件:从系统边界外激发的事件,例如用户的鼠标,键盘动作。

活动图主要用于描述过程原理,业务逻辑以及工作流的技术,很多情况下,活动图与传统的流程图非常相似,区别是活动图支持并发。活动图非常类似于传统的流程图,它也使用圆角矩形表示活动,使用带箭头的实线表示事件。

从图中可以看出如果将这个活动图的两支分开,每支就是一个传统的流程图,每个活动依次向下,遇到条件分支使用菱形框来表示条件。与传统的流程图不同的是,互动图可以使用并行分支分出多条并行活动。

绘制活动图时以活动为中心,整个活动图只有一个开始活动,可以有多个结束活动,活动图需要将并行活动和串行活动分离遇到分支和循环时最好像传统流程图将分支,循环条件明确表示。活动图最大优点在于支持并行行为,并行对于工作流建模和过程建模非常重要。因为有了并行,因此需要进行同步,同步通过汇合来指明。

状态机图

状态机图表示某个类所处的不同状态和该类的状态转换信息。实际上我们很少绘制状态机图,我们只对“感兴趣的”类绘制状态机图。也就是说,在系统活动期间具有三个或更多潜在状态的类才需要考虑使用状态机图进行描述。

状态机图的符号集包括5个基本元素:

  • 初始状态,它使用实心圆来绘制;
  • 状态之间的转换,它使用具有带箭头的线段来绘制;
  • 状态,它使用圆角矩形来绘制;
  • 判断点,它使用空心圆来绘制;
  • 一个或者多个终止点,它们使用内部包含实心圆的圆来绘制。

要绘制状态机图,首先绘制起点和一条指向该类的初始状态的转换线段。状态本身可以在图上的任意位置绘制,然后只需使用状态转换线条将他们连接起来。

绘制状态机图时应该保证对象只有一个初始状态,可以有多个终结状态。状态要表示对象的关键快照,有重要的实际意义,无关紧要的状态则无须考虑,绘制状态机图时事件和方法要明确。

状态机图擅长表现单个对象的跨用例行为,对于多个对象的交互行为应该考虑采用顺序图,不要对系统的每个对象都画状态机图,只对真正需要关心各个状态的对象才画状态机图。

猜你喜欢

转载自blog.csdn.net/qq_21874145/article/details/80448211