主要关注点:怎样创建对象?
主要特点:将对象的创建与使用分离。
好处:降低系统的耦合度,使用者不需关注对象的创建细节,对象的创建由相关的工厂来完成。
就像我们买东西,不需要知道商品是怎么生产的,因为它们有专门的厂商生产。
分类:1.单例模式 2.工厂方法模式 3.抽象工厂模式 4.原型模式 5.建造者模式
定义: 指一个类只有一个实例(对象),且该类能自行创建这个实例(对象的创建在此类中就完成了,而且创建的是自己的对象)的一种模式 。
单例模式提供了一种创建对象的最佳方式,单例模式可以理解为单个对象的设计模式。
特点:
①单例类只有一个实例对象。(自己的对象)
②该单例对象必须由单例类自行创建。(对象的创建在类内部就已完成)
③单例类对外提供一个访问该单例的全局访问点。(在单例类中,提供了一种访问其唯一对象的方法,外界不可以实例化该对象,仅能通过此方法(全局访问点)获取到该类的对象)
结构:
①单例类:只能创建一个实例(对象)的类。
②访问类:其实就是测试类,使用单例类的。
实现方式:
单例设计模式分为两类:
①饿汉式:类加载就会导致该单实例对象被创建。
②懒汉式:类加载的时候该类的对象并不会被创建,而是在首次使用该对象的时候(外界调用获取该单实例对象的getInstance()方法时)被创建。
区分懒汉式和饿汉式的方法:看对象是否是在类加载的时候被创建的。如果是,就是饿汉式;如果不是,就是懒汉式。
下面来介绍饿汉式的三种实现方式(静态成员变量方式、静态代码块方式、枚举方式)
1.饿汉式-方式1(静态成员变量方式)
1.单例类(Singleton)
public class Singleton {
//1,私有构造方法(让外界访问不到)
private Singleton(){}
//2,在本类中创建本类对象(方法返回值类型是静态的,静态的不能访问非静态的,所以这个对象也用static修饰)
private static Singleton instance = new Singleton();
//3,对象虽然创建了但是用private修饰,所以需要提供一个公共的访问方式,让外界获取该对象
//用static修饰方法是因为外界不能创建此类对象,不能创建就不能访问非静态的方法,所以定义的是静态的方法
public static Singleton getInstance(){
return instance;
}
}
2.测试类(Client)
public class Client {
public static void main(String[] args) {
//创建singleton对象,通过类名获取
Singleton instance = Singleton.getInstance();
//判断获取到的两个对象是否是同一个对象(在内存中是否是同一个地址)
Singleton instance1 = Singleton.getInstance();
System.out.println(instance == instance1);//true
}
}
3.运行结果(运行结果是true,说明两次创建的是同一个对象,实现了单例)
2.饿汉式-方式2(静态代码块方式)
1.单例类(Singleton)
public class Singleton {
//私有构造方法
private Singleton(){};
//声明Singleton类型的变量(只是声明,没有进行赋值,不是创建!)
private static Singleton instance;//null
//在静态代码块中进行赋值
static {
instance = new Singleton();
}
//对外提供获取该类对象的方法
public static Singleton getInstance(){
return instance;
}
}
2.测试类(Client)
public class Client {
public static void main(String[] args) {
Singleton instance = Singleton.getInstance();
Singleton instance1 = Singleton.getInstance();
//判断是否为同一对象
System.out.println(instance == instance1);
}
}
3.运行结果(结果为true,说明实现了单例)
方式1和方式2唯一的区别是:方式1是在声明该类的成员变量的同时进行赋值;方式2是先声明了该类的成员变量,然后在代码块里面进行赋值。
3.饿汉式-方式3(枚举方式)
1.单例类(Singleton,枚举类型)
public enum Singleton {
INSTANCE;
}
2.测试类(Client)
public class Client {
public static void main(String[] args) {
Singleton instance = Singleton.INSTANCE;
Singleton instance1 = Singleton.INSTANCE;
//判断获取的对象是否是同一个
System.out.println(instance == instance1);//true
}
}
3.运行结果(运行结果为true,说明实现了单例)
枚举方式的优点:线程安全,只会加载一次,是所有单例实现中唯一一种不会被破坏的单例实现模式。
枚举方式的缺点:会造成内存空间的浪费。
单例模式-饿汉式的缺点:(会造成内存空间的浪费)
饿汉式缺点解释:饿汉式都是在类加载时创建了对象,但如果只是进行了类加载,并没有获取该类的对象,此时对象也已经存在了内存中。如果该对象足够大的话,一直没有使用就会造成内存的浪费。
不考虑内存空间浪费的话,首选枚举方式。
{{ cmt.username }}
{{ cmt.content }}
{{ cmt.commentDate | formatDate('YYYY.MM.DD hh:mm') }}