云南大学软件学院设计模式期末复习.docx
- 文档编号:24039809
- 上传时间:2023-05-23
- 格式:DOCX
- 页数:16
- 大小:404.72KB
云南大学软件学院设计模式期末复习.docx
《云南大学软件学院设计模式期末复习.docx》由会员分享,可在线阅读,更多相关《云南大学软件学院设计模式期末复习.docx(16页珍藏版)》请在冰豆网上搜索。
云南大学软件学院设计模式期末复习
第一章
1.什么是模式?
模式是在物体或事件上,产生的一种规律变化与自我重复的样式与过程。
在模式之中,某些固定的元素不断以可预测的方式周期性重现。
2.什么是设计模式?
广义讲,软件设计模式是可解决一类软件问题并能重复使用的软件设计方案;
狭义讲,设计模式是对被用来在特定场景下解决一般设计问题的类和相互通信的对象的描述。
是在类和对象的层次描述的可重复使用的软件设计问题的解决方案;
设计模式是在一个上下文中,对一个问题的解决方案,及其能够达到的效果。
3.设计模式四要素
名称、上下文与问题、解决方案、效果
●模式名称(PatternName)
●问题(Problem):
描述应该在何时使用模式。
解释了设计问题和问题存在的前因后果,可能还描述模式必须满足的先决条件;
●解决方案(Solution):
描述了设计的组成成分、相互关系及各自的职责和协作方式。
模式就像一个模板,可应用于多种场合,所以解决方案并不描述一个具体的设计或实现,而是提供设计问题的抽象描述和解决问题所采用的元素组合(类和对象);
●效果(consequences):
描述模式的应用效果及使用模式应权衡的问题
4.设计模式分类
23种设计模式:
创建型:
5种;结构型:
7种;行为型:
11种
5.面向对象的四个基本方法:
●抽象(Abstraction)
●封装(Encapsulation)
●多态(Polymorphism)
●继承(Inheritance)
6.面向对象的设计原则
开闭原则(OCP):
对于扩展是开放的(Openforextension)。
这意味着模块的行为是可以扩展的。
当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。
也就是说,我们可以改变模块的功能。
对于修改是关闭的(Closedformodification)。
对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。
模块的二进制可执行版本,无论是可链接的库、DLL或者.EXE文件,都无需改动。
单一职责原则(SRP):
定义:
就一个类而言,应该仅有一个引起它变化的原因;
每一个引起类变化的原因就是一个职责,当类具有多职责时,应把多余职责分离出去,分别创建一些类来完成每一个职责;
每一个职责都是一个变化的轴线,当需求变化时会反映为类的职责的变化;
里氏替换原则(LSP):
定义:
所有引用基类的地方必须能透明地使用其子类的对象
里氏替换原则是继承复用的基石,只有当派生类可以替换掉其基类,而软件功能不受影响时,基类才能真正被复用,派生类也才能够在基类的基础上增加新的行为
LSP本质:
在同一个继承体系中的对象应该有共同的行为特征
依赖倒置原则(DIP):
定义:
高层模块不应依赖低层模块,二者都应该依赖于抽象
高层模块只应该包含重要的业务模型和策略选择,低层模块则是不同业务和策略的实现;
高层抽象不依赖高层和低层模块的具体实现,最多只依赖于低层的抽象;
低层抽象和实现也只依赖于高层抽象;
接口隔离原则(ISP):
定义:
类间的依赖关系应该建立在最小的接口上。
多个和客户相关的接口要好于一个通用接口;
如果一个类有几个使用者,与其让这个类载入所有使用者需要使用的所有方法,还不如为每个使用者创建一个特定接口,并让该类分别实现这些接口;
接口隔离原则包含了四层重要含义:
接口尽量要小;
接口要高内聚;
定制服务;
接口设计是有限度的
迪米特原则(LoD):
定义:
一个软件实体应当尽可能少的与其他实体发生相互作用。
每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。
迪米特法则也叫做做最少知识原则(LeastKnowledgePrinciple,简称LKP)
迪米特法则的初衷在于降低类之间的耦合。
第二章
(请重点复习本章)
1.策略模式
策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
2.标准类图
3.设计原则
●“开-闭”原则(OCP)
●单一职责原则(SRP)
●里氏替换原则(LSP)
●接口隔离原则(ISP)
4.设计实例及代码参考书22页
效果分析
优点:
算法和使用算法的对象相互分离,客户程序可以在运行时动态选择算法,代码复用性好,便于修改和维护;
用组合替代继承,效果更好。
若从Context直接生成子类,也可以实现对象的多种算法,但继承使子类和父类紧密耦合,使Context类难以理解、难以维护和难以扩展。
策略模式采用组合方式,使Context和Strategy之间的依赖很小,更利于代码复用;
消除了冗长的条件语句序列,将不同的算法硬编码进一个类中,选择不同的算法必然要使用冗长的条件语句序列,采用策略模式将算法封装在一个个独立的Strategy类中消除了这些条件语句;算法的动态选择,Strategy模式可以提供相同行为的不同实现,客户可以根据不同的上下文从不同的策略中选择算法;
缺点:
客户必须了解不同的Strategy,一个客户要选择一个合适的Strategy就必须知道这些Strategy到底有什么不同;
Strategy和Context之间的通信开销加大,根据算法的需要,Context必须向每个不同的具体Strategy类实例传递不同的参数,因此Strategy接口就要传递所有这些不同参数的集合,导致Context会创建和传递一些永远用不到的参数;
增加了类和对象数目,因为各种算法被抽取出来单独成类,导致了对象数目增加,这种情况在算法较多时更加严重;
5.要点
良好的OO设计必须具备可复用、可扩充、可维护三个特性
我们常把系统中会变化的部分抽象出来封装
第三章
1.观察者模式
观察者模式定义了对象之间一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会接到通知并自动更新。
2.标准类图
3.设计原则
为了交互对象之间的松耦合设计而努力。
4.效果分析
优点:
Subject和Observer之间是松偶合的,可以各自独立改变;
Subject在发送广播通知时,无须指定具体的Observer,Observer可以自己决定是否要订阅Subject的通知;
高内聚、低偶合;
缺陷:
松偶合导致代码关系不明显,有时可能难以理解;
如果一个Subject被大量Observer订阅的话,在广播通知的时候可能会有效率问题;
6.要点
观察者模式定义了对象之间一对多的关系
主题用一个共同的接口来更新观察者
观察者和可观察者之间用松耦合方式结合,可观察者不知道观察者的细节,只知道观察者实现了观察者的接口
使用此模式时,可以从观察者处推或拉数据(推的方式被认为更正确)
有多个观察者时,不可以依赖特定的通知次序。
第四章
(请重点复习本章)
1.装饰者模式
第五章
(请重点复习本章)
1.工厂模式
2.抽象工厂模式
第六章
1.单件模式
单件模式确保一个类只有一个实例,并提供一个全局访问点。
2.标准类图
3.单件模式处理多线程的方法
a)同步-staticsynchronized
这是保证可行的最直接方法。
不考虑性能
b)急切实例化
一定需要一个实例的时候可以采用该种方法
c)双重检查加锁
publicstaticSingletongetInstance(){
if(uniqueInstance==null){
synchronized(Singleton.class){
if(uniquelnstance==null){
uniquelnstance=newSingleton();
}
}
}
}
考虑性能的时候并且采用Java5以上的版本时使用该方法。
4.效果分析
优点
对唯一实例的受控访问:
因为Singleton类封装唯一实例,所以它可以严格的控制客户怎样以及何时访问它;
缩小名空间:
Singleton模式是对全局变量的一种改进。
它避免了那些存储唯一实例的全局变量污染命名空间;
允许对操作和表示的精化:
Singleton类可以有子类,而且用这个扩展类的实例来配置一个应用是很容易的。
可以用所需要的类的实例在运行时刻配置应用;
缺陷
不是所有的类实例化都需要实现单例;
不便使用继承;
5.要点
单件模式确保程序中的一个类最多只有一个实例。
单件模式提供访问这个实例的全局点。
在Java中实现单件模式需要私有的构造器、一个静态方法和一个静态变量。
如果使用多个类加载器,可能导致单件失效而产生多个实例。
如果采用Java2第5版以下的版本,双重检查加锁实现会失效。
JVM1.2及以下版本必须建立单件注册表,否则会失效。
7.DumpQuestion
1)难道不能创建一个类,把所有的方法和变量都定义为静态,把类直接当做一个单件?
如果类是自己自足的,而且不依赖于复杂的初始化,那么可以这样做。
但是静态初始化的控制权在Java手上,这么做有可能导致混乱,特别是当有许多类牵涉其中的时候。
这样做常常会造成一些微妙的、不容易发现的和初始化的次序有关的Bug。
除非你有绝对的必要使用类的单件,否则还是建议使用对象的单件,比较保险。
2)把单件类当做超类,设计出子类,究竟可不可以继承单件类?
继承单件会遇到一个问题,就是构造器是私有的。
不能使用私有构造器来扩展类。
因此,必须把单件的构造器改成公开的或受保护的。
但是这样一来就不算是真正的单件了,因为别的类也可以实例化它。
如果这的把构造器的权限改变了,想要让子类能够顺利工作,基类必须实现注册表功能。
3)在那些方面全局变量比单件模式差?
a)全局变量需要急切实例化,这个对象有可能非常消耗资源,而程序在一次执行中有可能没有用到它,这就造成了资源浪费。
b)全局变量可以提供全局访问。
但是不能保证只有一个实例。
c)全局变量会变相鼓励开发人员,用许多全局变量指向许多小对象来造成命名空间的污染。
第七章
(请重点复习本章)
1.命令模式
第八章
1.适配器模式
适配器模式将一个类的接口转换成客户期望的另一个接口。
适配器让原本不兼容的类可以合作无间。
2.标准类图
3.类适配器
4.对象适配器
5.设计原则:
最少知识原则。
6.要点
当需要使用一个现有的类而其接口并不符合你的需要时,就使用适配器。
当需要简化并统一一个很大的接口或者一群复杂的接口时,使用外观。
适配器改变接口以符合客户的期望。
外观将客户从一个复杂的子系统中解耦。
适配器模式有两种形式:
对象适配器和类适配器,类适配器在使用过程中需要用到多重继承
可以为一个子系统实现一个以上的外观。
适配器将一个对象封装起来以改变其接口;装饰者将一个对象包装起来以增加新的行为和责任;而外观将一群对象“包装起来”以简化其接口。
8.适配器模式效果分析
优点:
方便设计者自由定义接口,不用担心匹配问题;
缺点:
属于静态结构,由于只能单继承,所以不适用于多种不同的源适配到同一个目标;
9.DumbQuestion
a)如果外观封装了子系统的类,那么需要低层功能的客户如何接触这些类?
外观没有封装子系统的类,外观只是提供简化的接口。
所以用户觉得没有必要,可以直接使用子系统的类。
外观模式一个很好的特征:
提供简化接口的同时,依然将系统完整的功能暴露出来,以供需要的人使用。
b)外观会新增功能吗,或者它只是将每一个请求转由子系统执行?
外观可以增加新的功能,以便使用子系统更加方便。
c)每一个系统只能有一个外观吗?
不,可以为一个子系统创建多个外观。
d)除了能够提供一个比较简单的接口之外,外观模式还有其他优点吗?
外观模式允许将客户实现从任何子系统中解耦。
e)我可不可以这样说,适配器模式和外观模式之间的差异在于:
适配器包装一个类,而外观可以代表许多类?
外观和适配器均可以包装许多类,外观的意图是简化接口,而适配器的意图是将接口转化成不同的接口。
10.外观模式
提供了一个统一的接口,用来访问子系统中的一群接口。
外观定义了一个高层接口,让子系统更容易使用。
10.外观模式的效果
优点
对客户端屏蔽子系统组件,减少客户端使用对象数目;
实现了子系统与客户之间松耦合的关系,使得子系统组件的变化不会影响到客户;
不限制客户应用子系统类;
第九章
1.模板方法模式
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。
模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
2.设计原则
好莱坞原则
3.标准类图
4.要点
模板方法定义了算法的步骤,把这些步骤的实现延迟到了子类。
模板方法的抽象类可以定义具体的方法、抽象方法和钩子。
抽象方法由子类实现
钩子是一种方法,他在抽象类中不做事,或者只做默认的事情,子类可以选择要不要去覆盖它
为了防止子类改变模板方法中的算法,可以将模板方法声明为final
策略模式和模板方法模式都封装算法,一个用组合(策略模式),一个用继承(模板方法模式)。
工厂方法是模板模式的一个特殊版本
模板方法子类决定如何实现算法中的某个步骤
策略封装可互换的行为,然后使用委托来决定要采用哪一种行为
工厂方法有子类决定实例化哪个具体的类
5.效果分析
优点:
模板方法是一种代码复用技术,模板提取了”子类”的公共行为;
模板方法导致一种反向的控制结构:
“你别来找我,让我去找你”,即:
一个父类调用子类的操作,而不是相反;
可通过在抽象模板定义模板方法给出成熟算法步骤,同时又不限制步骤细节,具体模板实现算法细节不会改变整个算法骨架;
在抽象模板模式中,可以通过钩子方法对某些步骤进行挂钩,具体模板通过钩子可以选择算法骨架中的某些步骤;
6.DumpQuestion
a)当我创建一个模板方法时,怎么才能知道什么时候该使用抽象方法,什么时候使用钩子呢?
当你的子类必须提供算法中的某个方法或步骤实现时,就使用抽象方法。
如果算法的这个部分是可选的,就用钩子。
如果是钩子的话,子类可以选择实现这个钩子,但并不强制这么做。
b)使用钩子真正的目的是什么?
钩子可以让子类实现算法中可选的部分,或者在钩子对子类的实现并不重要的时候,子类可以对此钩子置之不理。
钩子的另一个用法是让子类能够有机会对模板方法中某些即将发生的步骤做出反应。
钩子也可以让子类又能力为其抽象类做一些决定。
c)子类必须实现抽象类中的所有方法吗?
是的,每一个具体的子类都必须定义所有的抽象方法,并为模板方法中未定义步骤提供完整的实现。
d)似乎我应该保持抽象方法的数目越少越好,否则,在子类中实现这些方法将会很麻烦?
可以让算法中的步骤不要切割得太细,但是如果步骤太少的话,会比较没有弹性,所以要看情况折中,另外要注意的是,某些步骤是可选的,所以可以将这些步骤实现成钩子,而不是实现成抽象方法,这样就可以让抽象类的子类的负荷减轻。
第十章
1.迭代器模式
迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。
2.设计原则:
单一责任,一个类应该只有一个引起变化的原因。
3.标准类图
4.要点
迭代器允许访问聚合的元素,而不需要暴露它的内部结构。
迭代器将遍历的聚合的工作封装进一个对象中。
当使用迭代器的时候,我们依赖聚合提供遍历。
迭代器提供了一个通用的接口,让我们遍历聚合的项,当我们编码使用聚合的项时,就可以使用多态机制。
我们应该努力让一个类值分配一个责任。
组合模式提供一个结构,可同时包容个别对象和组合对象。
组合模式允许客户对个别对象以及组合对象一视同仁。
组合结构内的任意对象称为组件,组件可以是组合也可以是叶节点。
在实现组合模式时,有许多设计上的折中。
你要根据需要平衡透明性和安全性。
5.迭代器模式效果分析
优点:
简化了聚集的行为,迭代子具备遍历接口,聚集不必具备遍历接口;
每一个聚集对象都可以有一个或者更多的迭代子对象,每一个迭代子的迭代状态可以彼此独立;
遍历算法被封装到迭代子对象中,迭代算法可以独立于聚集对象变化。
客户端不必知道聚集对象的类型,通过迭代子就可以读取和遍历聚集对象。
聚集内部数据发生变化不影响客户端程序;
6.组合模式
组合模式允许你将对象组合成树形结构来表现“整体/部分”层次结构。
组合能让客户以一致的方式处理个别对象以及对象组合。
7.组合模式标准类图
8.组合模式效果分析
优点
定义了包含基本对象和组合对象的类层次结构;
简化客户代码,一致使用组合对象和单个对象;
容易增加新类型的组件;
用户使用Component类接口与组合结构中的对象进行交互。
如果接收者是叶节点,直接处理请求;如果接收者是Composite,将请求发送给它的子部件,在转发请求之前和/或之后可能执行一些辅助操作;
9.Dumpquestion
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 云南大学 软件 学院 设计 模式 期末 复习