• 面向对象编程(高级部分)——单例模式


    目录

    1.什么是设计模式

    2.什么是单例模式

    3.单例模式应用实例[饿汉式]

    4.单例模式应用实例[懒汉式]

    5.饿汉式和懒汉式的区别


    1.什么是设计模式

     

    2.什么是单例模式

    也就是说在整个软件运行过程中,从开始运行到最后的结束运行的过程中,要保证某一个类,只有一个实例,不可以再有第二个。

    那么这样有什么用??

    网站开发等,有一个核心类,它非常耗用资源,但实际上我们只需要一个,那么这时候单例设计模式就很有价值 

    3.单例模式应用实例[饿汉式]

    按照我们传统的写法,我们来写一个GirlFriend类

    1. public class SingleTon01 {
    2. public static void main(String[] args) {
    3. GirlFriend xh = new GirlFriend("小红");
    4. GirlFriend xb = new GirlFriend("小白");
    5. }
    6. }
    7. //有一个类,GirlFriend
    8. //只能有一个女朋友
    9. class GirlFriend{
    10. private String name;
    11. public GirlFriend(String name) {
    12. this.name = name;
    13. }
    14. }

    举个例子,这个可以new出两个女朋友出来,那这就不叫单例,那么要如何保证单例呢?

    我们可以这样写,首先将构造器私有化,我们会发现现在创建不了对象

    但是我们会发现一个问题,我们一个女朋友都没有,这时候我们就要在类的内部创建

    这时候这个对象在内部是创建出来了,可是它是私有的,我们在外部用不了,那么为了我们使用,我们就要提供一个公共的静态方法,返回gf对象

    1. public class SingleTon01 {
    2. public static void main(String[] args) {
    3. //通过方法获取对象
    4. GirlFriend instance = GirlFriend.getInstance();
    5. System.out.println(instance);
    6. }
    7. }
    8. //有一个类,GirlFriend
    9. //只能有一个女朋友
    10. class GirlFriend{
    11. private String name;
    12. //为了能够在静态方法中,返回gf对象,需要将其修饰为static
    13. private static GirlFriend gf = new GirlFriend("小红红");
    14. //如何保障我们只能创建一个 GirlFriend
    15. //步骤
    16. //1. 将构造器私有化
    17. //2. 在类的内部直接创建
    18. //3. 提供一个公共的static方法,返回gf对象
    19. private GirlFriend(String name) {
    20. this.name = name;
    21. }
    22. public static GirlFriend getInstance(){
    23. return gf;
    24. }
    25. @Override
    26. public String toString() {
    27. return "GirlFriend{" +
    28. "name='" + name + '\'' +
    29. '}';
    30. }
    31. }

    那么有的人会想,我为什么要用static修饰这个getInstance呢?  

    如果我们不用static修饰这个方法,那么我们去用这个方法的时候又要去new对象,可是构造器已经被我们设置成private了,此时我们是new不了的,这时候直接通过类.方法名就可以直接调用。


    此时我们可以尝试一下,再创建一个这个对象

    1. public static void main(String[] args) {
    2. //通过方法获取对象
    3. GirlFriend instance = GirlFriend.getInstance();
    4. System.out.println(instance);
    5. GirlFriend instance2 = GirlFriend.getInstance();
    6. System.out.println(instance);
    7. System.out.println(instance == instance2);
    8. }

    由于是静态的,在类加载的时候就已经创建对象了,并且只会有一次,不会再创建新的

    那么这为什么叫饿汉式?

    在private static GirlFriend gf = new GirlFriend("小红红");中

    这一步就已经创建了,也就是说只要类加载了,那么这个对象就已经创建了,即使我们没有去使用这个gf,它也会去创建

    这时候我们在这个类里面添加一个静态变量,我们用类.属性名去调用,虽然我们没有调用那个静态方法,但是这个对象还是被创建出来了,也就是说饿汉式造成了创建对象,但是没有使用,这样就造成了资源浪费

    1. public class SingleTon01 {
    2. public static void main(String[] args) {
    3. System.out.println(GirlFriend.age);
    4. }
    5. }
    6. //有一个类,GirlFriend
    7. //只能有一个女朋友
    8. class GirlFriend{
    9. private String name;
    10. public static int age = 18;
    11. //为了能够在静态方法中,返回gf对象,需要将其修饰为static
    12. private static GirlFriend gf = new GirlFriend("小红红");
    13. //如何保障我们只能创建一个 GirlFriend
    14. //步骤
    15. //1. 将构造器私有化
    16. //2. 在类的内部直接创建
    17. //3. 提供一个公共的static方法,返回gf对象
    18. private GirlFriend(String name) {
    19. System.out.println("构造器被调用...");
    20. this.name = name;
    21. }
    22. public static GirlFriend getInstance(){
    23. return gf;
    24. }
    25. @Override
    26. public String toString() {
    27. return "GirlFriend{" +
    28. "name='" + name + '\'' +
    29. '}';
    30. }
    31. }

     

    4.单例模式应用实例[懒汉式]

    1. public class SingleTon02 {
    2. public static void main(String[] args) {
    3. System.out.println(Cat.n1);
    4. Cat instance = Cat.getInstance();
    5. System.out.println(instance);
    6. }
    7. }
    8. //希望在程序运行过程中,只能创建一个Cat对象
    9. //使用单例模式
    10. class Cat{
    11. private String name;
    12. private static Cat cat;
    13. public static int n1 = 999;
    14. //步骤
    15. //1.仍然将构造器私有化
    16. //2.定义一个静态属性
    17. //3.提供一个public的static方法,可以返回一个Cat对象
    18. private Cat(String name) {
    19. System.out.println("构造器调用....");
    20. this.name = name;
    21. }
    22. public static Cat getInstance(){
    23. if (cat == null){ //如果还没创建cat对象
    24. cat = new Cat("小可爱");
    25. }
    26. return cat;
    27. }
    28. @Override
    29. public String toString() {
    30. return "Cat{" +
    31. "name='" + name + '\'' +
    32. '}';
    33. }
    34. }

    这时候我们去调用这个Cat类里的n1属性,Cat对象没有随着类加载而创建出来,当我们想去创建这个对象的时候,可以通过getInstance方法来创建对象,并且将创建完的对象返回


    5.饿汉式和懒汉式的区别

  • 相关阅读:
    代理IP与Socks5代理在网络安全与数据隐私中的关键作用
    优秀的ui设计作品(合集)
    MYSQL DQL in 到底会不会走索引&in 范围查询引发的思考。
    Pop3和SMTP协议有什么关系或者区别吗?
    可视化全链路日志追踪
    React + Node.js『markdown 笔记本 』项目
    IDEA创建第一个spring项目
    SQL Server事务隔离级别
    宠物寄养小程序实战教程(上篇)
    MyBatis配置日志和使用注解
  • 原文地址:https://blog.csdn.net/qq_44706176/article/details/126455617