化简:
- 第一步:先看系统还剩下多少资源没分配,再看有哪些进程是不阻塞(“不阻塞”即:系统有足够的空闲资源分配给它)的
- 第二步:把不阻塞的进程的所有边都去掉,形成一个孤立的点,再把系统分配给这个进程的资源回收回来
- 第三步:看剩下的进程有哪些是不阻塞的,然后又把它们逐个变成孤立的点。
- 第四步:最后,所有的资源和进程都变成孤立的点。这样的图就叫做“可完全简化”。
如果一个图可完全简化,则不会产生死锁;如果一个图不可完全简化(即:图中还有“边”存在),则会产生死锁。这就是“死锁定理”。
扩展:死锁
1.图形工具
(1)程序流程图(FC)
优点:容易掌握,历史悠久,使用广泛
缺点:
本质上不具备逐步求精的特点,对于提高大型系统的可理解性,作用甚微;
不易表示数据结构;
可以随心所欲地画控制流程,容易造成非结构化的程序结构
趋势:停止使用
(2)盒图(NS)
优点:
功能域(一个特定控制结构的作用域)明确,可以从盒图上一眼就看出来
没有箭头不允许随意转移控制,不可能任意转移控制
很容易确定局部、全程数据的作用域
很容易表示嵌套关系,也可以表示模块的层次结构
缺点:随着程序内嵌套的层数增多时,内层方框越来越小,会增加画图的难度,影响清晰度
(3)问题分析图(PAD)
优点:
程序结构清晰,结构化程度高
支持自顶向下,逐步求精的设计方法
既可以表示程序逻辑,也可以描绘数据结构
表现程序逻辑,易读易写,使用方便
容易转换成高级语言源程序,也可用软件工具实现自动转换
2.表格工具
(1)判定表
优点:包含多重嵌套的条件选择时,程序流程图、N-S图、PAD都不易清楚地描述。但判定表可以清晰地表达复杂的条件组合与应做动作之间的对应关系
缺点:
缺乏通用性,没法和PAD图那样良好的转换成代码
数据元素的值多于两个时不易表示
无法清晰表示顺序、重复等处理
(2)判定树
优点:
表示复杂的条件组合与应做的动作之间的对应关系
形式简单,长期以来一直受到重视
缺点:
简洁性不如判定表:同一值重复写多遍;页端重复次数急剧增加
分支次序对于最终画出的判定树的简捷程度有较大影响
3.语言工具
(1)过程设计语言(PDL),即伪码
优点:
可以作为注释直接插在源程序中间
可以使用普通的正文编辑程序、文字处理系统,很方便地完成PDL的书写和编辑工作,书写方便
已经有自动处理PDL的程序存在,而且可以自动由PDL生成程序代码
缺点:不如图形工具形象直观,描述复杂的条件组合与动作间的对应关系时,不如判定表清晰简单
逆向工程:即求反工程,reverse enginneering
通过反汇编、反编译和动态跟踪等方法,分析出其动画效果的实现过程,这种行为就是逆向工程;不仅仅是反编译,而且还要推倒出设计,并且文档化,逆向软件工程的目的是使软件得以维护。
软件维护:辅助软件维护过程中的活动的软件称为“软件维护工具”,它辅助维护人员对软件代码及其文档进行各种维护活动。
(2)流图G的环形复杂度V(G)=E-N+2,其中,E是流图中边的条数,N是结点数。
(3)流图G的环形复杂度V(G)=P+1,其中,P是流图中判定结点的数目。
4.关联:两个类、或者类与接口之间语义级别的一种强依赖关系。比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,而且双方的关系一般是平等的、关联可以是单向、双向的。代码中以属性形式出现。
5.聚合:关联关系的一种特例,他体现的是整体与部分、拥有的关系,即has-a的关系,此时整体与部分之间是可分离的,他们可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享。现在代码层面,和关联关系是一致的,只能从语义级别来区分;
6.组合:是关联关系的一种特例,他体现的是一种contains-a的关系,这种关系比聚合更强,也称为强聚合;他同样体现整体与部分间的关系,但此时整体与部分是不可分的,整体的生命周期结束也就意味着部分的生命周期结束;表现在代码层面,和关联关系是一致的,只能从语义级别来区分;
总结:强弱程度依次为:组合>聚合>关联>依赖
1.用例图:其他实体与系统的关系、系统内用例之间的关系。通常用于表达系统或者系统范畴的高级功能
2.类图:不同的实体(人、事物和数据)如何彼此相关。示了系统的静态结构,用于表示逻辑类
3.序列图:示具体用例(或者是用例的一部分)的详细流程。显示了流程中中不同对象之间的调用关系,同时还可以很详细地显示对不同对象 的不同调用。有两个维度:垂直维度以发生的时间顺序显示消息/调用的序列;水平维度显示消息被发送到的对象实例。
4.状态图:某个类所处的不同状态和该类的状态转换信息。
5.活动图:处理某个活动时,两个或者更多类对象之间的过程控制流。
6.组件图:系统的物理视图。显示系统中的软件对其他软件组件(例如,库函数)的依赖关系。
7.部署图:软件系统如何部署到硬件环境中。用于显示硬件与软件之间架构,是具体的系统实施环境部署。部署图中的符号包括组件图中所使用的符号元素,另外还增加了几个符号,包括节点的概念。
创建型
1. Factory Method(工厂方法):定义一个用于创建对象的接口,让子类决定实例化哪一个类。
2. Abstract Factory(抽象工厂):创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
3. Builder(建造者):将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
4. Prototype(原型):用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
5. Singleton(单例):保证一个类仅有一个实例,并提供一个访问它的全局访问点。
结构型
6. Adapter Class/Object(适配器):将一个类的接口转换成客户希望的另外一个接口。Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
7. Bridge(桥接):将抽象部分与它的实现部分分离,使它们都可以独立地变化。
8. Composite(组合):将对象组合成树形结构以表示“部分-整体”的层次结构。C o m p o s i t e 使得用户对单个对象和组合对象的使用具有一致性。
9. Decorator(装饰):动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator 模式相比生成子类更为灵活。
10. Facade(外观):为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
11. Flyweight(享元):运用共享技术有效地支持大量细粒度的对象。
12. Proxy(代理):为其他对象提供一种代理以控制对这个对象的访问。
行为型
13. Interpreter(解释器):给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子.
14. Template Method(模板方法):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TemplateMethod 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
15. Chain of Responsibility(责任链):使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
16. Command(命令):将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。
17. Iterator(迭代器):提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。
18. Mediator(中介者):用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
19. Memento(备忘录):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。
20. Observer(观察者):定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
21. State(状态):允许一个对象在其内部状态改变时改变它的行为。
22. Strategy(策略):定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
23. Visitor(访问者):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TemplateMethod 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
对象间关系:
2,静态只能覆盖静态,或被静态覆盖。
3.重载时如果子父类中函数名称相同,仅仅是返回值则不同绝不允许重载(编译报错,调用的不确定性)。因为重载是基于函数参数区别;
4.覆盖时函数的声明必须完全相同,包括返回值也必须一致。
①如果子父类函数名称相同而参数列表不同,则该方法就成了子类特有方法,不存在覆盖
②如果子父类函数名称和参数列表都相同而返回值不同,编译不通过