徒手撸设计模式-单例模式

概念

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

参考连接: 单例模式 | 菜鸟教程

代码案例

公共类

public final class StFlag {
    public StFlag() {
    }
    /**
     * 饿汉式
     */
    public static final String HUNDER="HUNDER";
    /**
     * 双重检验锁
     */
    public static final String DCL="DCL";
    /**
     * 懒汉式非安全
     */
    public static final String LAZYUNSAFE="LAZYUNSAFE";
    /**
     * 懒汉式安全
     */
    public static final String LAZYSAFE="LAZYSAFE";
    /**
     * 静态内部类
     */
    public static final String STATICINNER="STATICINNER";

}

五种单例模式

DCL

/**
 * double check locking 双重检验锁
 */
@Slf4j
public class SingletonDCL {
    //创建 SingleObject 的一个对象
    private volatile static SingletonDCL instance ;

    //让构造函数为 private,这样该类就不会被实例化
    private SingletonDCL(){}

    //获取唯一可用的对象
    public static SingletonDCL getInstance(){
        if (instance ==null){
            synchronized (SingletonDCL.class){
                if (instance ==null){
                    instance=new SingletonDCL();
                }
            }
        }
        return instance;
    }

    public void showMessage(){
        log.info("DCL say Hello World!=========="+instance.hashCode());
    }
}

饿汉式

/**
 * 饿汉式
 */
@Slf4j
public class SingletonHunger {
    //创建 SingleObject 的一个对象
    private static SingletonHunger instance = new SingletonHunger();

    //让构造函数为 private,这样该类就不会被实例化
    private SingletonHunger(){}

    //获取唯一可用的对象
    public static SingletonHunger getInstance(){
        return instance;
    }

    public void showMessage(){
        log.info("Hunger say Hello World!=========="+instance.hashCode());
    }
}

懒汉安全

/**
 * 懒汉安全
 */
@Slf4j
public class SingletonLazySafe {
    //创建 SingleObject 的一个对象
    private static SingletonLazySafe instance ;

    //让构造函数为 private,这样该类就不会被实例化
    private SingletonLazySafe(){}

    //获取唯一可用的对象
    public static synchronized SingletonLazySafe getInstance(){
        if (instance ==null){
            instance=new SingletonLazySafe();
        }
        return instance;
    }

    public void showMessage(){
        log.info("Lazy Safe say Hello World!=========="+instance.hashCode());
    }
}

懒汉非安全

/**
 * 懒汉非安全
 */
@Slf4j
@Service("lazyUnSafe")
public class SingletonLazyUnSafe {
    //创建 SingleObject 的一个对象
    private static SingletonLazyUnSafe instance ;

    //让构造函数为 private,这样该类就不会被实例化
    private SingletonLazyUnSafe(){}

    //获取唯一可用的对象
    public static SingletonLazyUnSafe getInstance(){
        if (instance ==null){
            instance=new SingletonLazyUnSafe();
        }
        return instance;
    }

    public void showMessage(){
        log.info("Lazy UnSafe say Hello World!=========="+instance.hashCode());
    }
}

静态内部类

/**
 * 静态内部类
 */
@Slf4j
@Service("staticInner")
public class SingletonStaticInner {
    private static class SingletonStaticInnerClass{
        //创建 SingleObject 的一个对象
        private static final SingletonStaticInner instance = new SingletonStaticInner();
    }

    //让构造函数为 private,这样该类就不会被实例化
    private SingletonStaticInner(){}

    //获取唯一可用的对象
    public static SingletonStaticInner getInstance(){
        return SingletonStaticInnerClass.instance;
    }

    public void showMessage(){
        log.info("DCL say Hello World!=========="+SingletonStaticInnerClass.instance.hashCode());
    }
}

测试类

/**
 * 设计模式控制器
 */
@RestController
@RequestMapping("/designPattern")
@Slf4j
public class DesignController {
    @GetMapping("/singleton")
    public ResponseModel singleton(String singletonType) {
        if (StringUtils.isEmpty(singletonType)) {
            return new ResponseModel("请输入正确的单例模式类型", 500, null);
        }
        if (StFlag.DCL.equals(singletonType)) {
            SingletonDCL instance = SingletonDCL.getInstance();
            instance.showMessage();
            return new ResponseModel("双重检验锁单例创建成功", 200, instance.hashCode());
        } else if (StFlag.HUNDER.equals(singletonType)) {
            SingletonHunger instance = SingletonHunger.getInstance();
            instance.showMessage();
            return new ResponseModel("饿汉式单例创建成功", 200, instance.hashCode());

        } else if (StFlag.LAZYSAFE.equals(singletonType)) {
            SingletonLazySafe instance = SingletonLazySafe.getInstance();
            instance.showMessage();
            return new ResponseModel("懒汉式安全单例创建成功", 200, instance.hashCode());

        } else if (StFlag.LAZYUNSAFE.equals(singletonType)) {
            SingletonLazyUnSafe instance = SingletonLazyUnSafe.getInstance();
            instance.showMessage();
            return new ResponseModel("懒汉式非安全单例创建成功", 200, instance.hashCode());

        } else if (StFlag.STATICINNER.equals(singletonType)) {
            SingletonStaticInner instance = SingletonStaticInner.getInstance();
            instance.showMessage();
            return new ResponseModel("内部类单例成功", 200, instance.hashCode());
        }
        return null;
    }
}

测试案例

每个请求发两次比较hash值

饿汉式

双重检验锁

懒汉非安全

懒汉式安全

静态内部类

控制台日志

2022-06-16 02:01:18.638 INFO  Hunger say Hello World!==========593888302 【http-nio-8081-exec-4】【SingletonHunger:21】
2022-06-16 02:01:29.767 INFO  Hunger say Hello World!==========593888302 【http-nio-8081-exec-2】【SingletonHunger:21】
2022-06-16 02:02:13.813 INFO  DCL say Hello World!==========682619383 【http-nio-8081-exec-1】【SingletonDCL:31】
2022-06-16 02:02:15.836 INFO  DCL say Hello World!==========682619383 【http-nio-8081-exec-9】【SingletonDCL:31】
2022-06-16 02:02:47.905 INFO  Lazy UnSafe say Hello World!==========1560853762 【http-nio-8081-exec-10】【SingletonLazyUnSafe:24】
2022-06-16 02:02:50.264 INFO  Lazy UnSafe say Hello World!==========1560853762 【http-nio-8081-exec-8】【SingletonLazyUnSafe:24】
2022-06-16 02:03:11.053 INFO  Lazy Safe say Hello World!==========728785882 【http-nio-8081-exec-7】【SingletonLazySafe:24】
2022-06-16 02:03:15.359 INFO  Lazy Safe say Hello World!==========728785882 【http-nio-8081-exec-6】【SingletonLazySafe:24】
2022-06-16 02:03:37.376 INFO  DCL say Hello World!==========150313621 【http-nio-8081-exec-5】【SingletonStaticInner:26】
2022-06-16 02:03:39.190 INFO  DCL say Hello World!==========150313621 【http-nio-8081-exec-3】【SingletonStaticInner:26】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您的问题是关于如何实现鼠标悬浮导航栏下方出现具体内容的效果,对吗? 这个效果可以通过CSS中的伪类:hover来实现。具体的做法是,在鼠标悬浮到导航栏的某个菜单项上时,通过CSS选择器选中该菜单项下方的具体内容,并设置display属性为block或者其他合适的值,使其显示出来。 以下是一个简单的示例代码: HTML代码: ``` <ul class="nav"> <li><a href="#">菜单1</a> <div class="sub-menu"> <p>菜单1的具体内容</p> </div> </li> <li><a href="#">菜单2</a> <div class="sub-menu"> <p>菜单2的具体内容</p> </div> </li> <li><a href="#">菜单3</a> <div class="sub-menu"> <p>菜单3的具体内容</p> </div> </li> </ul> ``` CSS代码: ``` .nav { list-style: none; padding: 0; margin: 0; } .nav li { display: inline-block; position: relative; } .nav li a { display: block; padding: 10px; text-decoration: none; color: #333; } .sub-menu { display: none; position: absolute; top: 100%; left: 0; background-color: #f5f5f5; border: 1px solid #ddd; padding: 10px; } .nav li:hover .sub-menu { display: block; } ``` 解释一下上面的代码: 1. 首先定义了一个ul列表,每个列表项li对应一个菜单项。 2. 每个菜单项li中包含一个a链接和一个子菜单div,子菜单div中包含了该菜单项对应的具体内容。 3. 子菜单div默认设置为display: none,即不显示。 4. 当鼠标悬浮到某个菜单项li上时,通过:hover伪类选中该菜单项下方的子菜单div,并设置display属性为block,即显示出来。 您可以根据具体的需求,调整CSS样式和HTML结构,实现您想要的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值