好,大家好,我们开始 本周的学习。
本周呢是向大家介绍状态图部分, 这个也是,状态图本身也是描述
行为的一种模型,但是它这个描述行为呢和我们上周讲的这个
交互图描述行为的这个方式是不同的,或者说它们针对不同的 行为,更适合于不同的行为。
因为上周我们那个 交互图呢主要还是一种按部就班的,一种这个
过程,描述一种比较这个固定的过程, 或者说我们称之为数据流,或者说是也叫
这个驱动的这么一种 行为,比较适合用
这个状态,比较适合用这个交互图或者顺序图来描述。
其中呢这个 ,这行为呢它分为若干个
动作,动作呢实际上是一步一步的,不管是传递消息
还是自己做一个动作,这些呢都是 按部就班的,有简单的一些分支或者循环,但是呢
总体来说呢,它的这个行为呢是比较固定的,我们称之为静态 行为。
本周呢我们将介绍这个动态行为,所谓动态行为呢就是说 我们无法非常精确的,或者大概
知道它在哪个时间点上的具体的一个行为,而是呢 它这个对象和动作呢全部是依赖于一些事件的,
不仅依赖于当前的事件,而且依赖于这个 事件的序列。
所以在这种情况下呢,我们无法感知 或者无法准确的预言这个一个对象的这个行为
在任何时间点上具体在哪个位置,而是呢必须得是
有一个一系列的这个事件序列,然后呢可以知道它现在
所处的一个,做什么动作,处在一个状态, 描述这种行为呢,我们称之为事件驱动的行为。
也就是事件驱动的行为呢这个,用那个
顺序图或交互图呢,不是说不可以,但实际上呢这个会带来很大的复杂性,
而用这个状态图来描述呢就反而显得非常简单。
因此呢这个有必要呢我们学习一下 状态图,对于一些事件驱动的行为,
这个来描述这个比较适合。
首先呢我们看一下 这个一个简单的介绍,也就是说这个实际上我们这个面向对象
这个对象呢,可以分为若干状态。
然后一个对象从它这个产生到最终的消亡,可以分为
它的生命周期中可以分为若干阶段,每一个阶段呢, 可以分为大大小小的一些状态,
所以状态基本上就是一个对象生命周期中的某一个阶段,可以简单的这么理解,
这个,这个呢我们这个称之为状态。
而它在不同的这个阶段下呢,它 做的一些事情是不同的,然后呢它响应外部的一些事件也是不同的。
它这个响应一些事件,然后呢这个 把它转化为一些动作也是不同的,因此呢
所谓状态图呢就是要描述一个对象在生命周期的整个过程或某些
这个阶段,然后它的一个状态的一个变化的一个过程,并随之而来呢描述这个
随着状态的变化而带来的一些动作,或者说一些动作序列,这是就是
这才是真正描述它的行为。
所以 这是这个对象状态大概的一个,对象的状态图大概描述的一个什么样的一种
一种情况,或者说是一种对象。
所以这个事物的一般的这个生命形式,这个
可能呢是有一些周期性的,也就是说这个对象呢,在描述状态的时候呢它没有一个
产生和消亡的一个过程,它就是始终在那产生着,然后呢来了不同的这个消息,
来了不同的事件它会做不同的动作,它周而复始的始终在内存中或者
在现实世界中,这种这个对象的生命形式称之为这个周期性的生命周期。
这个而还有一种呢就是 描述这个对象,我们实际上是描述它从生到死的这个
整个周期,因此呢它有必要描述它开始是个什么,
在这个对象产生,产生的时候它是一个什么状态,然后到最后 到这个消亡的时候它是个什么状态。
在从生到死整个阶段 它历经了哪些阶段,在这个阶段中它有哪些事件激发了它们
它这个从一个状态转换为另外一个状态,然后在每个状态下它这个动作的
变化情况,这个因此呢一般来说呢状态图分为这两种模式。
前面呢我们说的是这个,这个 模式,也就是说可以有不同,两种模式来描述。
另外呢就是对象的不同呢也会导致它的这个状态图有不同的这种情况,
这个因为我们前面也提到了被动对象和主动对象,
被动对象和主动对象呢,在前边这个
顺序图中,实际上是代表两个不同的这个
模式的一种顺序图,在我们状态图中呢它也是代表两个不同模式的这个状态图。
所以被动对象呢,也就是说它内部不封装线程,然后它这个
本身呢,必须得有其他对象 发送消息才能唤醒它,然后给它分配了一定的 CPU 资源
之后,然后它才能完成一个什么事情,它完成完这个事情之后呢,接着进入这个休眠状态, 这是我们前面提到的被动对象。
而主动对象呢,自身封装了一个线程,就是说它在 这个整个线程全部,在它从生到死整个
生命周期中啊全部有,封装了一个线程,因此这时候呢 它可以,它的生命线呢实际上是
一直处在激活状态,这是这个主动对象和被动对象两个区别。
如果 主动对象和被动对象画状态图的话,实际上呢是它是用不同模式的状态图。
也就是说被动对象只支持状态图的很少一部分特征,而主动对象呢支持 这个我们这个
UML 这个状态图的全部的一些 特征。
那么这个对象的和这个状态图
到底有什么区别?就是说它或者说这个对象 生命周期和状态图是如何联系起来。
我们可以看这张图,也就是说这个对象初始化, 如果说是被动对象的话,初始化呢实际上是,它初始化有专门的一个线程来帮它完成,
这个线程调用它的初始化的一个方法之后,然后呢这个对象就从内存中 产生了。
产生完之后呢它一直,如果不分配,如果不请求它的一些消息,
不通过消息发送的方式请求一些操作的话呢,它一直处在一个 一个休眠的状态,这个
一旦发送了一个,一旦收到了一个请求,这时候呢它就处在激活状态,
它就会这个处理这个请求,处理完请求之后呢,这个线程呢又从它这呢
分配出去了,它又再次进入休眠状态,进入了等待请求的这个阶段。
最后一直到什么呢?不需要这个对象之后就从内存中析构掉了, 整个就是这个被动对象的这个生命周期。
这个因此呢这个被动对象的这个状态图呢,
它就是描述的就是它从产生到消亡的
这一个时间段中,然后它接受哪些对象,哪些
这个来自于外部的哪些消息,然后在这个消息的激发下它这个状态的变迁,主要是这个被动对- 象是描述这样的 存在情况。
这个而主动对象呢,我们说它的内部呢 封装了一个线程或进程,这个在对象初始化的时候这个线程
就已经给它分配给这个对象了,并且伴随这个对象 终身使用。
因此呢它始终,不管是它在 处在这个等待请求还是它在处理请求,
这两个阶段呢,实际上线程一直是在它这边,也就是说它一直封装着线程,
因此呢,这是这个主动对象和被动对象的区别。
这个下面呢这个实际上呢,
我们可以看出,这个我们随着后面的展开我们可以看出呢这个,二者的这个
区别是,有很大的区别,就是这个 被动,我们前面也提到,这个被动对象呢,
它这个接收的消息全部都是 同步消息,而主动对象呢也可以接收
这个,这个一些这个同步的消息,也可以 接收异步的消息,而它接收异步消息的时候呢是
这个,不管是它接收这个同步消息还是异步消息, 对于我们画状态图的时候都把它抽象为一个事件。
这个因此呢在我们这个状态图里面
同步消息和异步消息是不做区分的,但是呢实际上我们可以看到
这个后面随着这个我们深入地讲解这个状态图呢 由于它支持的这个行为不同,这个就是说这个
主动对象和被动对象支持的行为不同,导致的它这个状态图啊 有些时候情况下呢,它支持不同的,我们可以完全看
根据这个状态图的不同,来判定它到底是主动对象还是
被动对象,就是因为它这,这里边这个有一些这个进程和线程的一个
机制,这个我们可以这个之后呢再给大家
借助于一些例子,来深入地讲解这个问题 这个发送消息呢,就说这个在
在这个主动对象和被动对象里边呢这个消息传递,实际上是
不区分的,全部都是,不管你是同步消息和异步消息我们全部都是这个 抽象为我们的一些事件。
下面呢我们就 先给大家简单的介绍基本的状态图,也就是最简单的状态图 所谓基本的状态图呢就是没有嵌套层次的状态图
它不涉及到一些比较复杂的大状态里边套小状态的 一种情况,这时候呢状态图变得非常简单
一般的这个简单状态图,一般有四个概念就可以组成一个简单状态图 就是状态、
事件、 动作和转换,只要有着四个,然后就形成一个很小的状态图 就可以描述事件驱动的一些行为。
下面呢我们看一下 这个事件,既然是这个事件驱动,我们这描述事件驱动的这个行为状态图是
那么什么是事件呢?所谓一个事件呢,在 UML 它也是从这个 和类呀,
use case ,actor,它们是一个层次上的,它们全部都是一种类型 所谓事件是可观察的发生事情的类型
而这些类型呢,可以包括 大概是三个方面
就是我们可以至少可以从三个方面呢在画状态图的时候 来获取这个事件,或者候选的一些事件。
第一个就是交互事件 就是说这个对象和对象之间发送的这个消息,如果画对象状态图的时候,是以对象为单位的
这个基本上呢这个在类图中圈定一个对象 现在要对某一个对象的一个状态图,把这个对象圈定起来
对象周围,这个对象发生联系的所有对象都可以是外部,它们向它发送的各种消息呢,都可- 以称之为
事件,而这个事件呢,在这个我们的状态图里边呢,概括为这个交互
事件,而交互事件呢就分为,我们前面讲到的,就是分为这个同步消息和异步消息
这个也就是说,这个同步消息一般来说就是一些这个消
一些这个操作调用事件,这个即在被动对象和主动对象里边都会常见
还有一种异步消息,异步消息呢大概来说这个
从抽象的角度来看,是认为是信号,但是在具体的软件的这个实现上有很多种
不同的分类,是吧,这个根据它的实现机制不同 像一个这个
TCP/IP 这个协议包,这个就是一个事件,是吧,然后那个
两个线程之间传递一个 局部变量,这个也可以认为是个事件,等等,这些都可以认为是事件
这是第一种,第一种这个,我们如果说识别
事件的话,第一步要从这个交互上,当前选定的这个对象与其他对象之间的交互上 来进行反映。
第二个就是时间事件,就是时间事件也分两种,第一种叫时间间隔事件
也就是说过了一天,过了一个小时,过了一秒钟,这个有一个间隔之后,这个称之为
时间间隔事件,另外就是一些准点,这个即时性的这个时刻事件 每到
12 点钟,每到整点,进行报时,这个就是这个
分为两种,一种是这个间隔时间段,一种是这个时刻,这都称之为这个时间事件
还有一种呢就是对象自身的一些,不一定是对象,这个当前对象,也可能是其它对象的
一些这个数值上的变化,某些属性的变化,这个呢也称之为 这个事件,我们称之为变化事件,比如说这个对象呢
它的某一个属性值发生变化,这个呢也可以被抽象为一个事件
所以事件呢大概,要识别事件呢,大概就可以这三个方面来进行这个识别
就是说尽管呢这个事件这个 来自于不同的一些这个,就是说不同类型的事件
这个,实现这个,实现方式是完全不同的,在软件世界中
在这个自然,在现实世界中呢,这个不同的事件也是完全的不同的,非常异构
但是呢在我们的状态图中却有相同的表示 这就体现我们状态图的非常强的一方面的一种抽象能力
正是因为这种非常强大的抽象能力,使得它可以帮助我们把一些复杂的问题变得非常简单
这个,这个我们后面可以通过一些后面的例子呢,来这个 体会,体会到这个方面。
再就是 同样,在 UML 中呢,既然有事件,事件是一种类型,那么
事件的实例,事件实例化之后呢就成为了事件实例,那么事件实例呢就是
这个事件类型的一个实例,这个并且呢在这个事件的
过程中呢,我们通过一种抽象,就是发生这个事件,事件的发生是没有时间
这个间隔的,体现一个瞬时性,它没有时间延迟,这个并且呢在这个 UML2
中呢,我们这个讲 这个事件的这个实例呢称之为触发,这个,这是呢这个
一些这个说法上的,但实际上都是指的相同的意思
接下来我们这个,所谓状态图呢 第一个最重要的概念就是事件驱动,你要明白什么是事件
第二个就是什么是状态,这个状态的概念,到底什么是一个对象的一个状态 这个呢有不同的专家呢有不同的这个看法
我们可以看这个在《对象技术词典》,1995 年出版的这个版本中 什么是对象呢?它认为呢,本质上来说
这个所谓对象的这个状态是什么呢?就是它的这个属性值
这个的一种变化,称之为这个
状态,而一个对象属性值发生了一个变化,那就说明它从一种状态
跳变为另外一种状态,比如说我们人,从这个从生到死,整个过程
他这个年龄每年都在增长,增长
一岁,他的状态呢,我们可以认为他变化一下 这个呢实际上就是说从本质上来说呢,这个对象
的状态呢可以从这个属性值的变化上 来进行描述。
但是呢 它这个如果用这种方式来这个
帮助我们识别状态的话呢,应该说是 指导意义呢不是特别大,为什么呢?就是因为这个对象可能
有这个几个属性或者说几十个属性
如果说按照这个定义的话,那么它属性值的变化都可以称之为状态,然后它又有很多属性值 假如说它有这个
10 个属性值,每个属性值这个有 10 个 可变的这么一种取值范围的话,那就有
10 的 10 次方个状态 你这个状态太庞大了,如果我们用这种方式来识别属性的话,这个
来识别状态的话,这个状态呈爆炸性增大
因此呢,尽管从这个道理上来说,从定义上来说,可以把这个状态定义为这个
对象属性的变化,啊情况,但是实际上呢在真正实践中呢,我们不能够按照这种方式来识别我们
这状态,所以呢,这个,这个 是一种这个,只能作为一个定义。
另外一种方式呢就是 在这个给定时间、 方法、
行为的情况下,某个人或某个事 相关的一组环境变量和属性集,也就说这个
这个定义呢应该说比前一个 定义呢,这个更加这个受限,或者说是更加
可控,就是它这个尽 通过这个定义我们可以读解一下,就是它这个尽管呢这个
这个对象的状态呢可能表现为属性值的变化,但 不是对象的每一个属性都决定这个对象的
这个都是决定这个对象状态的一个属性 也就是说这个时候呢它是,这个与这个当前的这个对象
的一组相关的一种环境变量的属性值,使得我们在真正
识别状态的时候呢,不应该是按照每一个对象,啊,这个 对象里边所有的属性来考查,而可能就是考查它的一两个属性
的变化,来决定它的这个属性值,所以 这个,这个定义呢,
尽管也是用属性来定义,属性的取值范围来定义这个对象的状态。
但是呢,它给它加了一些约束条件,这个认定不是所有的属性
都对这个状态,对象的状态发生决定性作用,而是其中的一些
非常相关的一组,这个属性的子集,它们可能会对属性 这个状态识别呢,起到一定的作用。
所以这个好一些。
另外呢, 这个在《 UML 参考手册》中给出这么一个定义,所谓状态呢,是对象生命
周期的一个阶段,在这个阶段中啊,这个对象
满足一些特点的条件,从事特定的活动或者说呢 在等待某一个事件。
这个应该说 就是一种比较实用的一个定义了。
它不仅定义了什么是状态,而且 定义了你如何发现状态的时候,你从哪个角度来考虑,也就是说这个
状态呢,是对象生命周期一个阶段,这个阶段中 如果我们要划分这个对象有哪几个状态的时候,那就看这个
这个是不是对象在某一个生命周期的某一个阶段它正在
满足某一些条件,或者说从事特定的活动,或者说什么也不干,但是呢,却是在等待某一个事- 件的发生。
这样的话呢可以,这个给出我们这个一种这个
比较这个指导性的一种,指导我们识别状态的这么一种定义。
并且呢,这个概念已经完全抛弃了这个 就是说这个不是按照,机械的按照这个属性和属性值的方式,
而是这个,从这个我们实际的需求,从如何
尽可能的描述清楚这个行为这个角度来出发,来这个 定义状态。
因此呢,这个状态从属性的概念上来看, 一个对象可以从不同的角度来看,它有不同的状态。
但实际上呢,如果描述一个特定的行为的时候,
这时候我们只能,这个针对这个特定行为呢,给它进行一个抽象,然后给它划分成
为了把这个行为描述清楚,给它划分成刚刚 够用的这个状态集合就可以了。
并且这个 要做到这个,描述这个行为,非常精确的描述这个行为,但是呢,状态越少越好。
所以,这是一个比较好的一个定义。
另外呢,就在这个还是对象这个技术词典中给出了另外一个定义,也就是说,对象
或者说是类的一个整体行为的,某些规则所能适应的 这个状况、
情况、 条件、 形式或生命周期的阶段。
也就是说,这个定义 这个认为什么是状态呢?状态就是一个规则,
在某种状态下执行某些事情,
一个对象在某些状态下能够执行一些动作, 特定的动作。
在另外一个状态下就不能支持另外的动作。
就是说人这个 在清醒状态,要可以执行一些这个学习工作, 这个一些动作。
但是他这个当他休息睡眠的时候呢,他就不能执行这些动作。
这实际上呢,所谓状态的定义从另外一个角度来看,就是 一种规则。
也就是说在某些状态下能够执行这个 某些行为,在另外一个状态下不执行这个行为。
实际上它描述的就是一种规则。
在这个规则呢,实际上就是在当前状态下,
来了一个什么样的一个事件?我把这个事件给它映射成一个什么样的集合?
什么样的行为?什么样的动作?也就是说它这个 是通过这种方式来描述这个规则的。
这个 这个定义呢,应该说就是从另外一个角度,从规则这个角度来定义这个对象的这个
行为,认为这个所谓的这个状态无非就是一些对应性行为规则。
另外,应该来说也是有一定的实践一些指导意义。
也就是说这个,并且呢只有这个对象的这个行为规则不同的时候,才能定义为不同状态,
认为这个行为规则是确定这个对象状态 唯一的一个因素,而不是这个属性。
这应该说是对我们识别状态 iii 非常有帮助的概念。