设计模式之创建型模式

创建型模式

简约的理解创建型模式就是和创建对象相关的设计模式,它主要包含了6种设计模式:
1) 单例模式
2) 建造者模式
3) 原型模式
4) 简单工厂模式
5) 工厂方法模式
6) 抽象工厂模式

1、单例模式(Singleton)

定义:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例.
UML类图:
Singleton模式
其中Client——高层客户端;Singleton——单例类
实现单例模式的几个关键点:
1) 构造函数不对外开放,一般为private
2) 通过一个静态方法或者枚举返回单例类对象
3) 确保单例类对象只有一个
4) 确保单例类对象在反序列化时不会重新构建对象.

单例模式实现方法

实现单例模式有饿汉单例模式、懒汉单例模式、DCL实现单例、静态内部类单例模式、枚举单例、容器实现单例模式.
饿汉单例模式:在类中声明一个静态对象并初始化,对外开放一个静态方法用于返回该静态对象,以此实现单例模式.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 饿汉单例模式
*/
public class Singleton {
//创建静态对象并初始化
private static final Singleton singleton = new Singleton();
private Singleton(){
}
//对外开发的方法,并返回静态对象
public static Singleton getInstance(){
return singleton;
}
}

懒汉单例模式:在类中声明一个静态对象,并且在用户第一次调用getInstance()方法时才对其进行初始化.这里和饿汉单例模式的区别就在于单例对象创建的时间不同.其优点在于只有在使用时才会被实例化;其缺点就是第一次加载时需要及时实例化,反应稍慢,最大的问题就是每次调用getInstance方式都需要进行同步.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 懒汉单例模式
*/
public class Singleton {
private static Singleton singleton;
private Singleton(){
}
/**
* 若单例类对象为空,即第一次调用getInstance方法,则先创建再返回;若单例对象已经创建过了,那么直接返回
* @return
*/
public static synchronized Singleton getInstance(){
if(singleton==null){
singleton = new Singleton();
}
return singleton;
}
}

Double Check Lock(DCL)实现单例: DCL方式实现单例模式的优点就是即能够在需要时才初始化单例,又能够保证线程安全,且单例对象初始化都调用getInstance不进行同步锁.
具体为在getInstance方法中采用两层判断:第一层判断是为了避免不必要的同步;第二层的判断则是为了在null的情况下创建实例.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 单例模式
*/
public class Singleton {
//(1)
//private static Singleton singleton = null;
//(2)在多线程环境下,(1)的语句就会出现问题,所以在JDK1.5之后,可以为变量加上一个关键字“volatile”来保证每次读取变量的值时,读取到的数据都是最新的.
private volatile static Singleton singleton = null;
private Singleton(){
}
public static Singleton getInstance(){
if(singleton==null){
synchronized (Singleton.class) {
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}

静态内部类单例模式:这种方式不仅保证线程安全,也能够保证单例对象的唯一性,同时也延迟了单例的实例化.

1
2
3
4
5
6
7
8
9
10
private Singleton(){
}
public static Singleton getInstace(){
return SingletonHolder.sInstance;
}
//静态内部类
private static class SingletonHolder{
private static final Singleton sInstance = new Singleton();
}

2、建造者模式(Builder)

定义:将一个复杂对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示.
使用场景:
1) 相同的方法不同的执行顺序,产生不同的事件结果;
2) 多个部件或者零件,都可以装配到一个对象中,但是产生的运行结果又不相同时;
3) 当初始化一个对象特别复杂,如参数多,且很多参数都具有默认值时.
UML类图:
1) Product产品类——产品的抽象类;
2) Builder——抽象Builder类,规范产品的组建,一般由子类实现具体的组建过程;
3) ConcreteBuilder——具体的Builder类,实现产品每个组件的建造过程.
4) Director——统一组装过程(在平时使用时,通常不要这个类)
Builder模式
优点:良好的封装性,使用建造者模式可以使客户端不必知道产品内部组成的细节.易扩展

建造者模式实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/**
* 抽象Builder类,定义产品的组建步骤(如需要哪些组件)
*/
public abstract class Builder {
public abstract void buildeWheel(String wheel);
public abstract void buildeEngine(String engine);
public abstract void buildeExterior(String exterior);
public abstract void buildBrand();
public abstract Car create();
}
/**
* 抽象产品类
*/
public abstract class Car {
protected String mWheel;
protected String mEngine;
protected String mExterior;
protected String mBrand;
protected Car(){
}
public abstract void setmBrand();
//省略setter和getter
@Override
public String toString() {
// TODO Auto-generated method stub
return "Car [mWheel=" + mWheel +", mEngine="+mEngine + ", mExterior=" + mExterior+ ", mBrand="+ mBrand +"]";
}
}
/**
* 具体产品类
*/
public class BMWCar extends Car{
@Override
public void setmBrand() {
// TODO Auto-generated method stub
mBrand = "BMW x1";
}
}
/**
* 具体Builder类
*/
public class BMWCarBuilder extends Builder{
private Car car = new BMWCar();
@Override
public void buildeWheel(String wheel) {
// TODO Auto-generated method stub
car.setmWheel(wheel);
}
@Override
public void buildeEngine(String engine) {
// TODO Auto-generated method stub
car.setmEngine(engine);
}
@Override
public void buildeExterior(String exterior) {
// TODO Auto-generated method stub
car.setmExterior(exterior);
}
@Override
public void buildBrand() {
// TODO Auto-generated method stub
car.setmBrand();
}
@Override
public Car create() {
// TODO Auto-generated method stub
return car;
}
}
/**
* 指导者类
*/
public class Director {
Builder mBuilder = null;
public Director(Builder builder){
mBuilder = builder;
}
//构建对象
public void construct(String wheel,String engine,String extrior){
mBuilder.buildeWheel(wheel);
mBuilder.buildeEngine(engine);
mBuilder.buildeExterior(extrior);
}
}
//使用
public class Main {
public static void main(String[] args) {
Builder builder = new BMWCarBuilder();
//builder.create().setmWheel("日产");
Director d = new Director(builder);
d.construct("", "", "");//传入参数
}
}

原型模式(Prototype)

定义:用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象.
使用场景:(1)类初始化需要消化非常多的资源,这个资源包含数据、硬件资源等,通过原型拷贝避免这些浪费;
(2)通过new产生一个对象需要非常繁琐的数据准备或者访问权限;