设计模式之单件模式

引入

书接上回,我们来聊聊啥是单件模式?
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
顾名思义,这个模式的意图就是只能有一个实例,这种方法可以保证系统不能通过new运算符去创建这个类,可以很好的表示只有一个实例的情况,如冠军、印章等。
需要保证不能同时两个的情况的时候都可以用到这个单例模式

适合用单例模式的场景

在引入那就提到了,当系统需要某个类只能有一个实例的情况就会用到单例模式

单例模式的定义

保证一个类仅有一个实例,并提供一个访问它的全局访问点

单例模式的结构

在这里插入图片描述

没有什么类之间的交互,就是单例模式这个类的写法有点不一样,它将构造函数私有化了,然后提供了一个公有方法去调用它自身。
单件模式的类图是自关联的,这意味着它会在自己的类里面创建一个自己的对象实例,具体的大家看代码

//懒汉模式,new的过程是在调用getMoon的时候完成的
public class Moon {
    //这里定义这个实例
    private static Moon uniqueMoon;
    //实例中有两个属性
    double radius;
    double distanceToEarth;
    //私有化的构造函数
    private Moon(){
        uniqueMoon = this;
        radius = 1738;
        distanceToEarth = 363300;
    }
    //提供给外部程序的调用方法,这里采用synchronized保证线程互斥
    public static synchronized Moon getMoon(){
        if(uniqueMoon == null){
            uniqueMoon = new Moon();
        }
        return uniqueMoon;
    }
    public String show(){
        String s = "月亮的半径是"+ radius + "km,距离地球是"+distanceToEarth+"km";
        return s;
    }
}

小细节

根据应用程序的调用时机不同,单件模式又被分为懒汉模式和饿汉模式,
懒汉模式则是在线程要使用这个实例的时候才创建它
我这里写的就是懒汉模式,通过synchronized保证了线程互斥,但是也可能导致线程的竞争。
优点是不浪费资源

饿汉模式是指在类创建同时就创建一个静态的实例供系统使用;
优点是饿汉式天生就是线程安全的
缺点是闲置的实例造成了资源的浪费
我们将上面的代码的一些细节改一下就是饿汉模式,这里只写区别

//饿汉模式,new的过程是在定义类的时候实现的
public class Moon {
    private static Moon uniqueMoon = new Moon();//在定义这个类的时候直接生成这个实例
    //私有化的构造函数
    private Moon(){}
    public staticMoon getMoon(){
        return uniqueMoon;
    }
}

应用程序调用

这里用Frame简单建立两个画布线程去竞争这个实例,可以看出这个对象只有一个实例,不会因为不同对象的调用而创建过多的实例使得内存飙升,在程序中多次使用同一个对象且作用相同时,单例模式让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象,这节约了资源。

import javax.swing.*;
import java.awt.*;
public class Application {
    public static void main(String[] args) {
        MyFrame f1 = new MyFrame("张三看月亮");
        MyFrame f2 = new MyFrame("李四看月亮");
        f1.setBounds(10,10,360,150);
        f2.setBounds(370,10,360,150);
        f1.validate();
        f2.validate();
    }
}

class MyFrame extends JFrame{
    String str;
    MyFrame(String title){
        setTitle(title);
        Moon moon = Moon.getMoon();
        str = moon.show();
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setVisible(true);
        repaint();
    }
    public void paint(Graphics g){
        super.paint(g);
        g.setFont(new Font("宋体",Font.BOLD,14));
        g.drawString(str,5,100);
    }
}


总结

作为考试单例模式了解到这里就够了,但是这个单例模式在面试中考的很频繁的,其中的细节大家还可以更深层的了解。
这位大佬就讲的很详细我给面试官讲解了单例模式后,他对我竖起了大拇指!

模式不仅仅是模式,它是我们在编码过程中总结出来的结晶,是前人应对复杂多变的软件系统优秀的解决方案,每一种编码方式的不同带出来的结果都不同,仅仅是将构造方法私有化这一个小技巧都可以让我们受益匪浅!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AlbertOS

还会有大爷会打钱?

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值