目录
1.什么是设计模式
2.什么是单例模式
也就是说在整个软件运行过程中,从开始运行到最后的结束运行的过程中,要保证某一个类,只有一个实例,不可以再有第二个。
那么这样有什么用??
在网站开发等,有一个核心类,它非常耗用资源,但实际上我们只需要一个,那么这时候单例设计模式就很有价值
3.单例模式应用实例[饿汉式]
按照我们传统的写法,我们来写一个GirlFriend类
public class SingleTon01 {
public static void main(String[] args) {
GirlFriend xh = new GirlFriend("小红");
GirlFriend xb = new GirlFriend("小白");
}
}
//有一个类,GirlFriend
//只能有一个女朋友
class GirlFriend{
private String name;
public GirlFriend(String name) {
this.name = name;
}
}
举个例子,这个可以new出两个女朋友出来,那这就不叫单例,那么要如何保证单例呢?
我们可以这样写,首先将构造器私有化,我们会发现现在创建不了对象
但是我们会发现一个问题,我们一个女朋友都没有,这时候我们就要在类的内部创建
这时候这个对象在内部是创建出来了,可是它是私有的,我们在外部用不了,那么为了我们使用,我们就要提供一个公共的静态方法,返回gf对象
public class SingleTon01 {
public static void main(String[] args) {
//通过方法获取对象
GirlFriend instance = GirlFriend.getInstance();
System.out.println(instance);
}
}
//有一个类,GirlFriend
//只能有一个女朋友
class GirlFriend{
private String name;
//为了能够在静态方法中,返回gf对象,需要将其修饰为static
private static GirlFriend gf = new GirlFriend("小红红");
//如何保障我们只能创建一个 GirlFriend
//步骤
//1. 将构造器私有化
//2. 在类的内部直接创建
//3. 提供一个公共的static方法,返回gf对象
private GirlFriend(String name) {
this.name = name;
}
public static GirlFriend getInstance(){
return gf;
}
@Override
public String toString() {
return "GirlFriend{" +
"name='" + name + '\'' +
'}';
}
}
那么有的人会想,我为什么要用static修饰这个getInstance呢?
如果我们不用static修饰这个方法,那么我们去用这个方法的时候又要去new对象,可是构造器已经被我们设置成private了,此时我们是new不了的,这时候直接通过类.方法名就可以直接调用。
此时我们可以尝试一下,再创建一个这个对象
public static void main(String[] args) {
//通过方法获取对象
GirlFriend instance = GirlFriend.getInstance();
System.out.println(instance);
GirlFriend instance2 = GirlFriend.getInstance();
System.out.println(instance);
System.out.println(instance == instance2);
}
由于是静态的,在类加载的时候就已经创建对象了,并且只会有一次,不会再创建新的
那么这为什么叫饿汉式?
在private static GirlFriend gf = new GirlFriend("小红红");中
这一步就已经创建了,也就是说只要类加载了,那么这个对象就已经创建了,即使我们没有去使用这个gf,它也会去创建
这时候我们在这个类里面添加一个静态变量,我们用类.属性名去调用,虽然我们没有调用那个静态方法,但是这个对象还是被创建出来了,也就是说饿汉式造成了创建对象,但是没有使用,这样就造成了资源浪费
public class SingleTon01 {
public static void main(String[] args) {
System.out.println(GirlFriend.age);
}
}
//有一个类,GirlFriend
//只能有一个女朋友
class GirlFriend{
private String name;
public static int age = 18;
//为了能够在静态方法中,返回gf对象,需要将其修饰为static
private static GirlFriend gf = new GirlFriend("小红红");
//如何保障我们只能创建一个 GirlFriend
//步骤
//1. 将构造器私有化
//2. 在类的内部直接创建
//3. 提供一个公共的static方法,返回gf对象
private GirlFriend(String name) {
System.out.println("构造器被调用...");
this.name = name;
}
public static GirlFriend getInstance(){
return gf;
}
@Override
public String toString() {
return "GirlFriend{" +
"name='" + name + '\'' +
'}';
}
}
4.单例模式应用实例[懒汉式]
public class SingleTon02 {
public static void main(String[] args) {
System.out.println(Cat.n1);
Cat instance = Cat.getInstance();
System.out.println(instance);
}
}
//希望在程序运行过程中,只能创建一个Cat对象
//使用单例模式
class Cat{
private String name;
private static Cat cat;
public static int n1 = 999;
//步骤
//1.仍然将构造器私有化
//2.定义一个静态属性
//3.提供一个public的static方法,可以返回一个Cat对象
private Cat(String name) {
System.out.println("构造器调用....");
this.name = name;
}
public static Cat getInstance(){
if (cat == null){ //如果还没创建cat对象
cat = new Cat("小可爱");
}
return cat;
}
@Override
public String toString() {
return "Cat{" +
"name='" + name + '\'' +
'}';
}
}
这时候我们去调用这个Cat类里的n1属性,Cat对象没有随着类加载而创建出来,当我们想去创建这个对象的时候,可以通过getInstance方法来创建对象,并且将创建完的对象返回