当前位置:文档之家› 设计模式知识点整理

设计模式知识点整理

设计模式综述:
什么是设计模式?
Christopher Alexander说:“每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的解决方案的核心,这样,你就能一次又一次地使用该方案而不必做重复劳动”。

设计模式就是对被用来在特定场景下解决一般设计问题的类和相互通信的对象的描述。

设计模式的基本要素?
一般而言,一个模式有四个基本要素:
模式名称——一个助记名,它用一两个词来描述模式的问题、解决方案和效果。

问题——描述了应该在何时使用模式。

解决方案——描述了设计的组成部分。

效果——描述了模式应用的效果及使用模式应权衡的问题。

设计模式的分类?
我们根据两条准则对模式进行分类:
第一是目的准则,即模式是用来完成什么工作的:
模式依据其目的可分为创建型(Creational)、结构型(Structural)或行为型(Behavioral)三种,创建型模式与对象的创建有关,结构型模式处理类或对象的组合,行为型模式对类或对象怎样交互和怎样分配职责进行描述。

第二是范围准则,即指定模式主要是用于类还是用于对象:
创建型类模式:将对象的部分创建工作延迟到子类
创建型对象模式:将对象的部分创建工作延迟到另一个对象中
结构型类模式:使用继承机制来组合类
结构型对象模式:描述了对象的组装方式
行为型类模式:使用继承描述算法和控制流
行为型对象模式:描述一组对象怎样写作完成单个对象所无法完成的任务
第一个设计模式——单例模式(创建型模式)
先来看看下面这幅图片:
这是windows任务管理器,当我们打开一个任务管理器窗口后,如果试图再打开一个任务管理器窗口,会发现打不开,显示的还是原来的那个窗口,也就是说,任务管理器窗口只能打开一个,不可能打开多个,这就用到了单例模式。

那么,什么是单例模式呢?
单例模式(Singleton Pattern):单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。

知道了单例模式的定义后,我们如果想自己创建一个单例模式,该怎么做呢?
先看下面的java代码:
//Singleton.java
public class Singleton{
//定义该类的一个实例,类型为静态私有的
private static Singleton singleton;
//定义一个字符串成员变量,用于对单例模式做测试
public String name;
//将构造方法设为私有的
private Singleton(){}
//给该类添加一个公有静态的方法,名为getInstance,用于返回该类的一个实例
//在该类的内部,判断该类的实例是否为null
public static Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
public static void main(String[] args){
//测试单例类
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
="hello";
System.out.println();//打印s1中的name值
="HELLO";
System.out.println();//打印s1中的name值
}
}
运行上面的代码,结果如下图所示:
下面我们分析上面的代码:
在Singleton.java文件中,我们在main方法中使用Singleton类的静态方法getInstance()返回了两个对象s1,s2,假设这两个对象不是同一个对象,则用为s1的成员变量name赋值后name为“hello”,第一条打印语句也打印出了“hello”,但是,后面我们用为s2的成员变量name赋值为“HELLO”,然后,再次打印了s1的成员变量name(注意:前后两次都是打印s1的name值),从命令行中我们看到,s1的成员变量name值发生了变化,也就是说,通过s2,我们改变了s1的name值,这充分说明,s1和s2其实是同一个对象。

更简单的判断s1和s2是不是同一个对象的方法是,直接使用s1==s2判断,我们在上面的main方法中末尾加上一句代码:System.out.println(s1==s2);
最后运行结果如下所示:
可以看到,打印的结果为true,足以说明s1和s2是同一个对象。

上面的代码即为单例模式的框架。

模式名称:单例模式(Singleton)
模式动机:对于系统中的某些类来说,有且只能有一个实例。

例如:一个系统只能有一个窗口管理器。

系统中可以有许多打印机,但是只能有一个打印机正在工作。

问题:我们怎样保证一个类只有一个实例并且这个实例易于被访问呢?
解决办法:让类自身负责保存它的唯一实例。

这个类可以保证没有其它实例被创建,并且它可以提供一个访问该实例的方法。

这就是单例模式——Singleton Pattern。

单例模式的要点有三个:
一是某个类只能有一个实例;
二是它必须自行创建这个实例;
三是它必须自行向整个系统提供这个实例。

单例模式是一种对象创建型模式。

使用单例模式,需要以下几个步骤:
①将单例模式类的构造方法设为私有的,不允许从外部直接调用构造方法创建该类的对象
②将要创建的实例封装在单例类的成员变量中,并设置为静态私有的
③在该类中给外部提供一个getInstance()方法,用于得到一个单例类的实例,且只产生一个实例,该方法要用静态公有修饰,是因为外部不可能调用该类的构造方法,故只有用static 修饰,让外部通过类名调用getInstance()方法,这也是为什么第二步要将成员变量设置为静态的(类的静态成员函数只能访问该类的静态成员变量)。

上面说了这么多,那么,该在什么时候使用单例模式呢?
在以下情况下可以使用单例模式:
系统只需要一个实例对象。

例如,系统要求提供一个唯一的系列号生成器或资源管理器,或
资源消耗太大而只允许创建一个对象。

客户调用类的单个实例只允许使用一个公共访问点。

模式的主要优点:
提供了对唯一实例的受控访问。

由于系统中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象,单例模式无疑可以提高系统的性能。

允许可变数目的实例。

可以对单例模式进行扩展,设计指定个数的实例对象,即节省系统资源,又解决了由于单例对象共享过多有损性能的问题。

模式的主要缺点:
由于单例模式中没有抽象层,因此单例类的扩展有很大困难。

单例类的职责过重,在一定程度上违背了单一指责原则。

因为单例模式即提供业务方法,又提供了创建对象的方法,将对象功能和创建耦合在一起。

很多面向对象语言的GC垃圾回收技术,实例化的对象长期不使用,系统会认为是垃圾,自动销毁并回收资源,这将导致共享的单例对象状态的丢失。

相关主题