单例设计模式
- [1. 什么是设计模式?](#1. 什么是设计模式?)
- [2. 什么是单例设计模式?](#2. 什么是单例设计模式?)
- [3. 怎么实现单例模式?](#3. 怎么实现单例模式?)
-
- [3.1 饿汉式](#3.1 饿汉式)
- [3.2 懒汉式](#3.2 懒汉式)
- [4.饿汉式 VS 懒汉式](#4.饿汉式 VS 懒汉式)
1. 什么是设计模式?
设计模式是静态方法和属性的经典使用
设计模式就是在平时写代码的过程中总结出来的代码结构,需要的时候可以免去思考直接使用这种结构,提高编程效率
除了单例设计模式还有很多其他的设计模式
2. 什么是单例设计模式?
- 单例模式:顾名思义就是单个的实例,要采用某种方法保证在一个软件系统中对一个类只有一个对象实例,要想获取实例只提供一个获取其对象实例的方法。
- 单例模式有两种方法:1.饿汉式 2.懒汉式
3. 怎么实现单例模式?
步骤:
- 将构造器私有化
- 在类的内部创建对象
- 向外暴露一个静态的公共方法(得以获取实例)
- 调用公共方法实现代码
3.1 饿汉式
饿汉式如何保证我们只能创建一个对象实例?
1. 将构造器私有化
2. 在类的内部直接创建对象,并实例化
3. 提供一个public的静static方法,返回对象
代码示例:
java
public class SingleTon01 {
public static void main(String[] args) {
// GirlFriend xh = new GirlFriend("小红");
// GirlFriend xb = new GirlFriend("小白");
//以上创建了两个对象实例,这样就不叫单例模式
//饿汉式:可能会有创造了对象实例,但是没有使用,可能造成数据的浪费
//通过调用静态方法获取gf对象
GirlFriend instance = GirlFriend.getInstance();
System.out.println(instance);
GirlFriend instance2 = GirlFriend.getInstance();
System.out.println(instance2);
System.out.println(instance == instance2);
}
}
class GirlFriend{
private String name;
//为了能够在静态方法中,返回 gf 对象,我们加入 static,如果不用static,就不能在静态方法中返回gf对象
private static GirlFriend gf = new GirlFriend("小红红");//这是私有的,在外面的类用不了,会调用构造器
private GirlFriend(String name) {
System.out.println("构造器被调用...");
this.name = name;
}
//在加载类的时候会执行static相关代码
//为的就是在 不在外部创建对象的情况下就调用这个方法
public static GirlFriend getInstance(){
return gf;
}
@Override
public String toString() {
return "GirlFriend{" +
"name='" + name + '\'' +
'}';
}
}
代码解释:
如上代码,将构造器私有化就限制了不能再new一个对象,然后我们在类中就创建了私有静态的对象实例,为的就是在其他类中用不了,这两步就保证了这个类只能有一个对象实例,接下来再写一个静态公共的方法(getInstance),这个方法返回类型为这个类,返回的是对象名,这样就可以在主方法中调用这个静态公共的方法,就可以使用这个对象实例了
3.2 懒汉式
饿汉式如何保证我们只能创建一个对象实例?
1. 构造器私有化
2. 定义一个static静态属性对象,不new(不实例化)
3. 提供一个public的static方法,返回对象
代码示例:
java
public class SingleTon02 {
public static void main(String[] args) {
Cat instance = Cat.getInstance();
System.out.println(instance);
//再次调用
Cat instance2 = Cat.getInstance();
System.out.println(instance2);
System.out.println(instance == instance2);
}
}
//希望在程序运行过程中只能创建一个Cat对象
class Cat{
private String name;
private static Cat cat;//这里没有new,所以构造器不会被调用
private Cat(String name) {
System.out.println("构造器被调用");
this.name = name;
}
//懒汉式:只有用户调用getInstance方法时,才会创建cat对象,再次调用时,会返回上次创建的cat对象,从而保证了单例模式
public static Cat getInstance(){
if(cat == null){
cat = new Cat("小白");
}
return cat;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
'}';
}
}
代码解释:
如上代码,和饿汉式一样的就是都私有化了构造器和在类中创建了私有静态的对象,但是在懒汉式中这个静态对象并没有实例化,而是在公共静态的方法中通过判断这个对象有没有实例化再做处理,在这个公共静态方法中,如果该对象没有实例化(cat == null),就实例化之后返回对象,如果该对象实例化了,就会返回上次实例化过的对象,这样保证了单例模式,因为只有调用这个方法的时候才会实例化,所以懒汉式还不会导致实例化资源的浪费
4.饿汉式 VS 懒汉式
- 创建对象实例的时机不同:饿汉式是在类加载(创建私有静态对象)的时候就创建了对象实例,而懒汉式是在使用时才创建
- 因为创建对象实例时机不同,所以饿汉式可能会存在资源浪费的可能(程序员没有使用对象实例,那么创建的对象实例就浪费了),而懒汉式是在使用时才创建,就没有这个问题