目录
第一章 设计模式概述
1,什么是模式?
模式是在特定环境下,人们解决某类重复出现问题的一套成功或有效的解决方案。
特定环境,重复出现,成功有效的解决方案。
在发现模式的过程中,需要遵循大三律, 即只有经过3 个以上不同类型的系统的校验,一个解决方案才能升级为模式。
所以模式一套解决方案, 根据它的特点 ,可以看出它是可以在特定环境下,解决某一重复出现的问题一套成功有效的解决方案。
2,什么叫设计模式?
设计模式是一套被反复使用的,多数人知晓的,经过分类编目的,代码,设计经验的总结。
它也是在特定环境下,为解决某一通用软件设计问题提供的一套定制的解决方案,该方案描述了对象与类之间的相互作用。
总共有23种设计模式。(不包括简单工厂模式)
有两种分类,
一是根据目的分类,有 创建型模式(5),结构性模式(7),行为型模式(11)
二是根据范围分类,有 对象模式 和 类模式
根据这个学期我们所学的,我们所学的10种设计模式。
创建型有 4种, 分别为 简单工厂模式,工厂方法模式,抽象工厂模式,单例模式,
其中属于类模式的 只有 工厂方法模式,其他 3 个是 对象模式。
结构型 有5种,分别为 适配器模式,桥接模式,组合模式,外观模式,代理模式。
其中属于 类模式的 只有 适配器模式中的类适配器模式,其他属于对象模式。
行为型模式只有 1个,即 策略模式。
附录A UML类图
1,什么是UML?
它是一个通用的可视化建模语言,不同于编程语言,它通过一些标准的图形符号和文字对系统进行建模,
用于对软件进行描述,可视化处理,构造和建立软件系统制品的文档。
它提供13种图,有类图,用例图,对象图,包图,组合结构图,状态图,活动图,顺序图,通信图,定时图,交互概览图,组件图,部署图。
2,如何用UML表示类之间的关系?
总共有 4种 关系,分别为 关联关系,继承关系,依赖关系,实现关系。
一,关联关系。(一般用 实现加箭头表示)
有 单向关联,双向关联,子关联,多重性关联
还有两种比较特殊的,
聚合关系(用空心菱形 加 实线 加 箭头 表示)
两个类,一般在本类中,先定义另一个类的成员对象,再在本类中的构造方法,Setter方法,或业务方法中的参数注入。
如:
public class Car{
public Engine engine;
public Car(Engine engine)
{
this.engine=engine;
}
public void setEngine(Engine engine)
{
this.engine=engine;
}
}
public class Engine{
}
组合关系 (一般用 实心菱形 加 实线 加 箭头 表示 )
两个类,一般在本类中,先定义另一个类的成员对象,再在本类的构造方法中直接 实例化成员类。
如:
public class Head{
public Mouth mouth;
public Head(){
mouth=new Mouth();
}
}
public class Mouth{
}
二,依赖关系(一般用 虚线 加 箭头)
它是一种使用关系,它的特点就是,没有定义成员变量,都是在成员方法中使用另一个类的方法(可以通过参数注入,调用静态方法,也可以用作为局部变量)。
三,泛化关系(继承关系,一般用 实线 加 空心三角形 表示)
四,实现关系(一般用 虚线 加 空心三角形状 表示 )
实现接口。
第二章 面向对象设计原则
1,有哪些原则,它们的职能分别又是什么?
本书总共讲了,7个常用的面向对象设计原则。
分别是,
单一职责原则:控制 类的粒度大小,最好一个类 一个职能。
开闭原则:对扩展开放,对修改关闭。
里氏代换原则:用基类类型 对对象进行定义。用子类对象替换父类对象。
依赖倒转原则:针对接口,抽象类编程,即用接口,抽象类来进行 各种声明。
接口隔离原则:把一个大的接口 分为 几个小的接口(合适就好)
合成复用原则:又称为 组合/聚合复用原则,尽量不用继承。
迪米特法则:引入中间类。
第三章 简单工厂模式
1,什么叫简单工厂模式?
它是属于对象创建型模式,它的主要目的是把 对象的创建和使用分离。需要一个对象时,直接去工厂调用即可。
它包含:工厂类,具体产品类,抽象产品类 三种角色
2,XML格式的配置文件怎么写?
<?xml version="1.0"?>
<config>
<chartType>****</chartType>
</config>
public class XMLtil{
public static String getChartType(){
try{
DocumentBuilderFactory df=DocumentBuilderFactory.newInstance();
DocumentBuilder db= df.newDocumentBuilder();
Document doc=db.parse(new File("/**/**/**/config.xml"));
NodeList nl=doc.getElementsByTagName("chartType");
Node node=nl.item(0).getFirstChild();
String chartType=node.getNodeValue().trim();
return chartType;
}catch(Exception e){
e.printStackTrace();
return null;
}
}
}
<chartType> 可以自定义
3,创建对象有几种方式?
有四种,
new,反射机制,克隆,工厂
4,简单工厂的优缺点有哪些?
优点:实现对象的创建与使用分离。通过xml配置文件,可以不修改源代码。
缺点:工厂类职责过重,增加了类的个数,一旦添加新产品,就需要修改工厂类的代码。
第四章 工厂方法模式
1,它的特点是什么?
工厂方法模式是创建型模式中唯一一个类模式。
它包含:抽象工厂,具体工厂,抽象产品,具体产品 4种角色。
它为每一个具体产品,都提供一个专门的具体工厂生产。
2,反射机制与配置文件?
<?xml version="1.0" encoding="UTF-8" ?>
<config>
<className>cn.wyb.NostalgicFilter</className>
</config>
package cn.wyb;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
public class XMLtil {
public static Object getBean(){
try{
DocumentBuilderFactory documentBuilderFactory=DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder=documentBuilderFactory.newDocumentBuilder();
Document document=documentBuilder.parse(new File("module15/src/main/resources/config.xml"));
NodeList nl=document.getElementsByTagName("className");
Node node=nl.item(0).getFirstChild();
String cName=node.getNodeValue();
Class c=Class.forName(cName);
Object obj=c.newInstance();
return obj;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
3,如何添加一个新的产品类?
先继承一下抽象产品类,再建一个该产品的工厂类,继承一下抽象工厂类,然后改一下配置文件即可。
4,工厂方法模式优缺点?
优点:无需修改任何源代码,添加产品简单,扩展性良好。
缺点:增加了类的个数
第五章 抽象工厂模式
1,什么是产品族和产品等级结构?
产品等级结构就是 一个个 产品继承结构。比如:海尔电视机,海信电视机,都是电视机。
产品族就是 从各个产品等级结构 选取 品牌一样的产品。比如:海尔空调,海尔洗衣机,都是海尔。
2,什么是抽象产品模式?
它结合了简单工厂和工厂方法模式的优缺点。
每一个工厂既不生产全部产品,也不生产一个产品,它生产属于它的品牌的产品即 从各个继承结构中 选一个。
它包含:抽象工厂,具体工厂,抽象产品,具体产品 四种角色。
3,开闭原则的倾斜性是什么?
-增加产品族,即增加一个工厂,不需做任何源代码的修改。
-增加新的产品等级结构,要修改工厂代码,违背开闭原则。
4,抽象工厂的优缺点?
优点:算是简单工厂和工厂方法中的中间者。
缺点:增加新的产品等级结构麻烦。
第八章 单例模式
1,什么叫单例模式?
我们的任务管理器是很明显的单例模式。它只有一个。
单例模式:确保一个类只能有一个实例。
它有三个要点:一是某个类只能有一个实例,二是它必须自行创建这个实例,三是它必须自行向整个系统提供这个实例。
它有且只有一个角色,就是单例角色。
它有个特点,就是无论是变量还是方法都必须是静态的。
2,如何简单的实现它?
public class Singleton{
private static Singleton instance=null;//静态私有成员变量。
private Singleton(){
}
public static Singleton getInstance(){
if(instance==null)
{
instance=new Singleton();
}
return instance;
}
}
这个属于 懒汉式单例模式。它有个弊端就是 要考虑 多线程 以及 性能问题。
于是在它的基础上,我们又发展了双重检查锁定。
3,什么叫做双重检查锁定?
我们在锁定 new 对象的同时,在下面继续再判断instance是否为空。
实现代码
public class LazySingleton{
private volatile static LazySingleton instance=null;//静态私有成员变量。
private LazySingleton(){
}
public static LazySingleton getInstance(){
if(instance==null)
{
synchronized(LazySingleton.class){
if(instance==null)
instance=new LazySingleton();
}
}
return instance;
}
}
这个方法并不是很好,因为volatile关键字会屏蔽java虚拟机所做的一些代码优化。导致系统性能降低。
4,饿汉式以及静态内部类?
直接在成员变量进行实例化instance对象。并且只需加一个final关键字。
public class EagerSingleton{
private static final EagerSingleton instance=new EagerSingleton();
private EagerSingleton(){
}
public static EagerSingleton getInstance(){
return instance;
}
}
那么它也有问题,就是一直会占用资源。
怎么办,改进一下,用内部类去实现new。
public class EagerSingleton{
private EagerSingleton(){
}
private static class HolderClass{
private static final EagerSingleton instance=new EagerSingleton();
}
public static EagerSingleton getInstance(){
return HolderClass.instance;
}
}
5,单例模式的优缺点?
优点:节约系统资源,允许可变数目的实例。
缺点:单例类的职责过重,扩展困难。
第九章 适配器模式
1,用一句话说一下适配器?
适配器模式它包含:适配者类,适配器类,目标抽象类三个角色。
简单的说,就是用适配器类去 继承目标抽象类,关联适配者类,这是 对象适配器。
而类适配器就是 用 适配器类去 实现 目标抽象类接口,然后继承 适配者类。
2,如何实现呢?
类适配器:Adapter(适配器类) Adaptee(适配者类,有specificRequest()方法) Target(目标抽象接口类, 有request()抽象方法)。
public class Adapter extends Adaptee implement Target{
public void request(){
super.specificRequest();
}
}
对象适配器:Adapter(适配器类) Adaptee(适配者类,有specificRequest()方法) Target(目标抽象类, 有request()抽象方法)。
public class Adapter extends Target{
private Adaptee adp;
public Adapter (Adaptee adp){
this.adp=adp;
}
public void request(){
adp.specificRequest();
}
}
对象适配器可以同时适配多个适配者。
3,缺省适配器模式什么鬼?
就是多了一层抽象层继承结构,它里面都是些空方法。为了不实现接口那么多的方法。
4,双向适配器?
就是两边的接口既可以是抽象目标类,也可以是适配者类。
5,适配器模式优缺点?
优点:解耦,增加了类的复用性,灵活性和扩展性好。
缺点:主要是java,c#自身语言的局限性,实现过程比较复杂。
第十章 桥接模式
1,桥接模式解决的主要问题是什么?
桥接模式将两个独立变化的维度分离出来,用抽象关联来取代传统的多层继承,将类之间的静态继承关系转换为动态的对象组合关系。
比如:用 毛笔与颜料来解决 蜡笔。
2,什么是桥接模式?
它就是将抽象部分与它的实现部分 解耦,使得两者 都能独立变化,而不是继承。
它包含:抽象类,扩充抽象类,实现类接口,具体实现类 四个角色。
主要就是 有 两个 抽象类 ,然后 分别都有自己的继承结构,然后我们在一方的抽象层 里去聚合一下另一个抽象层基类。
再在这一方的子类方法中,我们去实现另一个类的方法。
3,这里我们如何实现XML配置文件与反射机制?
<?xml version="1.0" encoding="UTF-8" ?>
<config>
<className>cn.wyb.WindowsImp</className>
<className>cn.wyb.JPGImg</className>
</config>
package cn.wyb;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
public class XMLtil {
public static Object getBean(String args){
try{
DocumentBuilderFactory documentBuilderFactory=DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder=documentBuilderFactory.newDocumentBuilder();
Document document=documentBuilder.parse(new File("module16/src/main/resources/config.xml"));
NodeList nl=null;
Node node=null;
String cName=null;
nl=document.getElementsByTagName("className");
if(args.equals("image")){
node=nl.item(1).getFirstChild();
}
else if(args.equals("os")){
node=nl.item(0).getFirstChild();
}
cName=node.getNodeValue();
Class c=Class.forName(cName);
Object obj=c.newInstance();
return obj;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
4,桥接模式优缺点?
优点:分离抽象与实现部分,解耦,提高了系统的可扩展性,减少了类的数目。
缺点:增加了系统的理解难度。
第十一章 组合模式
1,什么叫组合模式?
它是对象结构型模式。组合多个对象形成树形结构以表示具有部分-整体关系的层次结构。
它也叫 部分-整体 模式。
它包含:抽象构件,叶子构件,容器构件三种角色。
根据我的理解,就是容器构建多了个 集合。然后来个for循环搞个递归,当然了,核心还在客户端如何构建一棵树。
2,透明组合模式和安全组合模式?
透明组合模式就是我们刚刚说的。
安全组合模式就是抽象构件没有管理访问方法,只有业务方法。
3,组合模式优缺点?
优点:符合开闭原则,方便对整个层次结构进行控制。
缺点:对增加的构件很难进行限制。
第十三章 外观模式
1,什么叫外观模式?
简单地讲,就是我们通过一个中间类就可以 对所有系统进行访问。很明显的迪米特法则。
它包含:外观,子系统两种角色。
实现起来也很简单,用我的话概述就是,在所有的子系统类中,我们不作任何行动。
我们只需创建一个外观类,在它的成员变量中定义所有子系统类的成员对象,然后在它的构造方法中对子系统类实例化,
再在成员方法中,使用所有子系统类的方法。
我们也来分析下外观类与子系统类之间的类关系。
首先是成员对象,我们考虑关联,然后,在构造方法中有实例化,则我们判断它们之间的关系是组合关系。
2,抽象外观类?
如果我们要添加,删除,更换一个子系统类,我们必须修改外观类。
所以我们增加一个抽象外观类,这样我们也可以直接增加一个外观类,用来接收新的子系统。
3,外观模式的优缺点?
优点:松耦合。
缺点:不能很好地限制客户端直接使用子系统类。可能会违背开闭原则。
第十五章 代理模式
1,什么是代理模式?
它包含:抽象主题角色,代理主题角色,真实主题角色三种
其中 代理主题类和真实主题类都继承 抽象主题类。
然后,代理类还会在成员变量中,直接实例化真实主题对象。
再在成员方法中调用真实主题类的方法。
它们之间的关系应该是关联关系。
2,它具体有哪些代理呢?
有,
远程代理:提供一个本地的代理对象去连接远程业务对象。
虚拟代理:先创建一个较小的对象来表示,加速了系统的启动时间,同时也缩短了用户的等待时间,
对于占用大量系统资源的对象,我们一般要等到它要被创建时,才创建,在之前我们都是用简单的代理对象来代表
真实对象,同时为了节省内存,创建之后,我们也可以多次重用。
保护代理:为不同的用户提供不同的权限。
缓冲代理:提供一个临时空间,以便更多的客户端可以共享这些结果。
智能引用代理: 提供额外的一些操作,比如计数
3,什么是动态代理?
动态代理可以让系统在运行时根据实际需要来动态创建代理类,让同一个代理类能够代理多个不同的真实主题类而且可以代理不同的方法。
通过使用动态代理可以实现对多个真实主题类的统一代理和集中控制。
4,代理模式的优缺点?
优点:降低了系统的耦合度,符合开闭原则。
缺点:请求的处理速度会变慢,例如保护代理。远程代理很难。
第二十四章 策略模式
1,什么是策略模式?
它定义了一系列算法,将每一个算法封装起来,并让它们可以相互替换。
它包含:环境类,抽象策略类,具体策略类三种角色
环境类会在成员变量中,定义一个抽象策略类,然后在setter方法中注入具体策略类,然后再成员方法中实现算法。
环境类与抽象策略类属于很明显的聚合关系。
2,策略模式的优缺点?
优点:可以很灵活的增加新的算法,符合开闭原则,避免重复代码和多重条件。
缺点:客户必须知道所有算法的用法,而且无法同时使用多个算法。